LISP: L2 ARP handling
[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 = uword_to_pointer (mp->reply_in_shmem, u8 *);
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 = uword_to_pointer (mp->reply_in_shmem, u8 *);
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: pid %d address %U new mac %U sw_if_index %d\n",
1259           mp->mac_ip ? "mac/ip binding" : "address resolution",
1260           ntohl (mp->pid), 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: pid %d address %U new mac %U sw_if_index %d\n",
1275           mp->mac_ip ? "mac/ip binding" : "address resolution",
1276           ntohl (mp->pid), 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 #define vl_api_bridge_domain_details_t_endian vl_noop_handler
1287 #define vl_api_bridge_domain_details_t_print vl_noop_handler
1288
1289 /*
1290  * Special-case: build the bridge domain table, maintain
1291  * the next bd id vbl.
1292  */
1293 static void vl_api_bridge_domain_details_t_handler
1294   (vl_api_bridge_domain_details_t * mp)
1295 {
1296   vat_main_t *vam = &vat_main;
1297   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1298   int i;
1299
1300   print (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-3s",
1301          " ID", "LRN", "FWD", "FLD", "BVI", "#IF");
1302
1303   print (vam->ofp, "%3d %3d %3d %3d %3d %3d",
1304          ntohl (mp->bd_id), mp->learn, mp->forward,
1305          mp->flood, ntohl (mp->bvi_sw_if_index), n_sw_ifs);
1306
1307   if (n_sw_ifs)
1308     {
1309       vl_api_bridge_domain_sw_if_t *sw_ifs;
1310       print (vam->ofp, "\n\n%s %s  %s", "sw_if_index", "SHG",
1311              "Interface Name");
1312
1313       sw_ifs = mp->sw_if_details;
1314       for (i = 0; i < n_sw_ifs; i++)
1315         {
1316           u8 *sw_if_name = 0;
1317           u32 sw_if_index;
1318           hash_pair_t *p;
1319
1320           sw_if_index = ntohl (sw_ifs->sw_if_index);
1321
1322           /* *INDENT-OFF* */
1323           hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1324                              ({
1325                                if ((u32) p->value[0] == sw_if_index)
1326                                  {
1327                                    sw_if_name = (u8 *)(p->key);
1328                                    break;
1329                                  }
1330                              }));
1331           /* *INDENT-ON* */
1332           print (vam->ofp, "%7d     %3d  %s", sw_if_index,
1333                  sw_ifs->shg, sw_if_name ? (char *) sw_if_name :
1334                  "sw_if_index not found!");
1335
1336           sw_ifs++;
1337         }
1338     }
1339 }
1340
1341 static void vl_api_bridge_domain_details_t_handler_json
1342   (vl_api_bridge_domain_details_t * mp)
1343 {
1344   vat_main_t *vam = &vat_main;
1345   vat_json_node_t *node, *array = NULL;
1346   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1347
1348   if (VAT_JSON_ARRAY != vam->json_tree.type)
1349     {
1350       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1351       vat_json_init_array (&vam->json_tree);
1352     }
1353   node = vat_json_array_add (&vam->json_tree);
1354
1355   vat_json_init_object (node);
1356   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1357   vat_json_object_add_uint (node, "flood", mp->flood);
1358   vat_json_object_add_uint (node, "forward", mp->forward);
1359   vat_json_object_add_uint (node, "learn", mp->learn);
1360   vat_json_object_add_uint (node, "bvi_sw_if_index",
1361                             ntohl (mp->bvi_sw_if_index));
1362   vat_json_object_add_uint (node, "n_sw_ifs", n_sw_ifs);
1363   array = vat_json_object_add (node, "sw_if");
1364   vat_json_init_array (array);
1365
1366
1367
1368   if (n_sw_ifs)
1369     {
1370       vl_api_bridge_domain_sw_if_t *sw_ifs;
1371       int i;
1372
1373       sw_ifs = mp->sw_if_details;
1374       for (i = 0; i < n_sw_ifs; i++)
1375         {
1376           node = vat_json_array_add (array);
1377           vat_json_init_object (node);
1378           vat_json_object_add_uint (node, "sw_if_index",
1379                                     ntohl (sw_ifs->sw_if_index));
1380           vat_json_object_add_uint (node, "shg", sw_ifs->shg);
1381           sw_ifs++;
1382         }
1383     }
1384 }
1385
1386 static void vl_api_control_ping_reply_t_handler
1387   (vl_api_control_ping_reply_t * mp)
1388 {
1389   vat_main_t *vam = &vat_main;
1390   i32 retval = ntohl (mp->retval);
1391   if (vam->async_mode)
1392     {
1393       vam->async_errors += (retval < 0);
1394     }
1395   else
1396     {
1397       vam->retval = retval;
1398       vam->result_ready = 1;
1399     }
1400 }
1401
1402 static void vl_api_control_ping_reply_t_handler_json
1403   (vl_api_control_ping_reply_t * mp)
1404 {
1405   vat_main_t *vam = &vat_main;
1406   i32 retval = ntohl (mp->retval);
1407
1408   if (VAT_JSON_NONE != vam->json_tree.type)
1409     {
1410       vat_json_print (vam->ofp, &vam->json_tree);
1411       vat_json_free (&vam->json_tree);
1412       vam->json_tree.type = VAT_JSON_NONE;
1413     }
1414   else
1415     {
1416       /* just print [] */
1417       vat_json_init_array (&vam->json_tree);
1418       vat_json_print (vam->ofp, &vam->json_tree);
1419       vam->json_tree.type = VAT_JSON_NONE;
1420     }
1421
1422   vam->retval = retval;
1423   vam->result_ready = 1;
1424 }
1425
1426 static void
1427   vl_api_bridge_domain_set_mac_age_reply_t_handler
1428   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1429 {
1430   vat_main_t *vam = &vat_main;
1431   i32 retval = ntohl (mp->retval);
1432   if (vam->async_mode)
1433     {
1434       vam->async_errors += (retval < 0);
1435     }
1436   else
1437     {
1438       vam->retval = retval;
1439       vam->result_ready = 1;
1440     }
1441 }
1442
1443 static void vl_api_bridge_domain_set_mac_age_reply_t_handler_json
1444   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1445 {
1446   vat_main_t *vam = &vat_main;
1447   vat_json_node_t node;
1448
1449   vat_json_init_object (&node);
1450   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1451
1452   vat_json_print (vam->ofp, &node);
1453   vat_json_free (&node);
1454
1455   vam->retval = ntohl (mp->retval);
1456   vam->result_ready = 1;
1457 }
1458
1459 static void
1460 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1461 {
1462   vat_main_t *vam = &vat_main;
1463   i32 retval = ntohl (mp->retval);
1464   if (vam->async_mode)
1465     {
1466       vam->async_errors += (retval < 0);
1467     }
1468   else
1469     {
1470       vam->retval = retval;
1471       vam->result_ready = 1;
1472     }
1473 }
1474
1475 static void vl_api_l2_flags_reply_t_handler_json
1476   (vl_api_l2_flags_reply_t * mp)
1477 {
1478   vat_main_t *vam = &vat_main;
1479   vat_json_node_t node;
1480
1481   vat_json_init_object (&node);
1482   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1483   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1484                             ntohl (mp->resulting_feature_bitmap));
1485
1486   vat_json_print (vam->ofp, &node);
1487   vat_json_free (&node);
1488
1489   vam->retval = ntohl (mp->retval);
1490   vam->result_ready = 1;
1491 }
1492
1493 static void vl_api_bridge_flags_reply_t_handler
1494   (vl_api_bridge_flags_reply_t * mp)
1495 {
1496   vat_main_t *vam = &vat_main;
1497   i32 retval = ntohl (mp->retval);
1498   if (vam->async_mode)
1499     {
1500       vam->async_errors += (retval < 0);
1501     }
1502   else
1503     {
1504       vam->retval = retval;
1505       vam->result_ready = 1;
1506     }
1507 }
1508
1509 static void vl_api_bridge_flags_reply_t_handler_json
1510   (vl_api_bridge_flags_reply_t * mp)
1511 {
1512   vat_main_t *vam = &vat_main;
1513   vat_json_node_t node;
1514
1515   vat_json_init_object (&node);
1516   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1517   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1518                             ntohl (mp->resulting_feature_bitmap));
1519
1520   vat_json_print (vam->ofp, &node);
1521   vat_json_free (&node);
1522
1523   vam->retval = ntohl (mp->retval);
1524   vam->result_ready = 1;
1525 }
1526
1527 static void vl_api_tap_connect_reply_t_handler
1528   (vl_api_tap_connect_reply_t * mp)
1529 {
1530   vat_main_t *vam = &vat_main;
1531   i32 retval = ntohl (mp->retval);
1532   if (vam->async_mode)
1533     {
1534       vam->async_errors += (retval < 0);
1535     }
1536   else
1537     {
1538       vam->retval = retval;
1539       vam->sw_if_index = ntohl (mp->sw_if_index);
1540       vam->result_ready = 1;
1541     }
1542
1543 }
1544
1545 static void vl_api_tap_connect_reply_t_handler_json
1546   (vl_api_tap_connect_reply_t * mp)
1547 {
1548   vat_main_t *vam = &vat_main;
1549   vat_json_node_t node;
1550
1551   vat_json_init_object (&node);
1552   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1553   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1554
1555   vat_json_print (vam->ofp, &node);
1556   vat_json_free (&node);
1557
1558   vam->retval = ntohl (mp->retval);
1559   vam->result_ready = 1;
1560
1561 }
1562
1563 static void
1564 vl_api_tap_modify_reply_t_handler (vl_api_tap_modify_reply_t * mp)
1565 {
1566   vat_main_t *vam = &vat_main;
1567   i32 retval = ntohl (mp->retval);
1568   if (vam->async_mode)
1569     {
1570       vam->async_errors += (retval < 0);
1571     }
1572   else
1573     {
1574       vam->retval = retval;
1575       vam->sw_if_index = ntohl (mp->sw_if_index);
1576       vam->result_ready = 1;
1577     }
1578 }
1579
1580 static void vl_api_tap_modify_reply_t_handler_json
1581   (vl_api_tap_modify_reply_t * mp)
1582 {
1583   vat_main_t *vam = &vat_main;
1584   vat_json_node_t node;
1585
1586   vat_json_init_object (&node);
1587   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1588   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1589
1590   vat_json_print (vam->ofp, &node);
1591   vat_json_free (&node);
1592
1593   vam->retval = ntohl (mp->retval);
1594   vam->result_ready = 1;
1595 }
1596
1597 static void
1598 vl_api_tap_delete_reply_t_handler (vl_api_tap_delete_reply_t * mp)
1599 {
1600   vat_main_t *vam = &vat_main;
1601   i32 retval = ntohl (mp->retval);
1602   if (vam->async_mode)
1603     {
1604       vam->async_errors += (retval < 0);
1605     }
1606   else
1607     {
1608       vam->retval = retval;
1609       vam->result_ready = 1;
1610     }
1611 }
1612
1613 static void vl_api_tap_delete_reply_t_handler_json
1614   (vl_api_tap_delete_reply_t * mp)
1615 {
1616   vat_main_t *vam = &vat_main;
1617   vat_json_node_t node;
1618
1619   vat_json_init_object (&node);
1620   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1621
1622   vat_json_print (vam->ofp, &node);
1623   vat_json_free (&node);
1624
1625   vam->retval = ntohl (mp->retval);
1626   vam->result_ready = 1;
1627 }
1628
1629 static void vl_api_mpls_tunnel_add_del_reply_t_handler
1630   (vl_api_mpls_tunnel_add_del_reply_t * mp)
1631 {
1632   vat_main_t *vam = &vat_main;
1633   i32 retval = ntohl (mp->retval);
1634   if (vam->async_mode)
1635     {
1636       vam->async_errors += (retval < 0);
1637     }
1638   else
1639     {
1640       vam->retval = retval;
1641       vam->result_ready = 1;
1642     }
1643 }
1644
1645 static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
1646   (vl_api_mpls_tunnel_add_del_reply_t * mp)
1647 {
1648   vat_main_t *vam = &vat_main;
1649   vat_json_node_t node;
1650
1651   vat_json_init_object (&node);
1652   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1653   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
1654                             ntohl (mp->sw_if_index));
1655
1656   vat_json_print (vam->ofp, &node);
1657   vat_json_free (&node);
1658
1659   vam->retval = ntohl (mp->retval);
1660   vam->result_ready = 1;
1661 }
1662
1663 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
1664   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1665 {
1666   vat_main_t *vam = &vat_main;
1667   i32 retval = ntohl (mp->retval);
1668   if (vam->async_mode)
1669     {
1670       vam->async_errors += (retval < 0);
1671     }
1672   else
1673     {
1674       vam->retval = retval;
1675       vam->sw_if_index = ntohl (mp->sw_if_index);
1676       vam->result_ready = 1;
1677     }
1678 }
1679
1680 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
1681   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1682 {
1683   vat_main_t *vam = &vat_main;
1684   vat_json_node_t node;
1685
1686   vat_json_init_object (&node);
1687   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1688   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1689
1690   vat_json_print (vam->ofp, &node);
1691   vat_json_free (&node);
1692
1693   vam->retval = ntohl (mp->retval);
1694   vam->result_ready = 1;
1695 }
1696
1697
1698 static void vl_api_one_add_del_locator_set_reply_t_handler
1699   (vl_api_one_add_del_locator_set_reply_t * mp)
1700 {
1701   vat_main_t *vam = &vat_main;
1702   i32 retval = ntohl (mp->retval);
1703   if (vam->async_mode)
1704     {
1705       vam->async_errors += (retval < 0);
1706     }
1707   else
1708     {
1709       vam->retval = retval;
1710       vam->result_ready = 1;
1711     }
1712 }
1713
1714 static void vl_api_one_add_del_locator_set_reply_t_handler_json
1715   (vl_api_one_add_del_locator_set_reply_t * mp)
1716 {
1717   vat_main_t *vam = &vat_main;
1718   vat_json_node_t node;
1719
1720   vat_json_init_object (&node);
1721   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1722   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
1723
1724   vat_json_print (vam->ofp, &node);
1725   vat_json_free (&node);
1726
1727   vam->retval = ntohl (mp->retval);
1728   vam->result_ready = 1;
1729 }
1730
1731 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
1732   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1733 {
1734   vat_main_t *vam = &vat_main;
1735   i32 retval = ntohl (mp->retval);
1736   if (vam->async_mode)
1737     {
1738       vam->async_errors += (retval < 0);
1739     }
1740   else
1741     {
1742       vam->retval = retval;
1743       vam->sw_if_index = ntohl (mp->sw_if_index);
1744       vam->result_ready = 1;
1745     }
1746 }
1747
1748 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
1749   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1750 {
1751   vat_main_t *vam = &vat_main;
1752   vat_json_node_t node;
1753
1754   vat_json_init_object (&node);
1755   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1756   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1757
1758   vat_json_print (vam->ofp, &node);
1759   vat_json_free (&node);
1760
1761   vam->retval = ntohl (mp->retval);
1762   vam->result_ready = 1;
1763 }
1764
1765 static void vl_api_gre_add_del_tunnel_reply_t_handler
1766   (vl_api_gre_add_del_tunnel_reply_t * mp)
1767 {
1768   vat_main_t *vam = &vat_main;
1769   i32 retval = ntohl (mp->retval);
1770   if (vam->async_mode)
1771     {
1772       vam->async_errors += (retval < 0);
1773     }
1774   else
1775     {
1776       vam->retval = retval;
1777       vam->sw_if_index = ntohl (mp->sw_if_index);
1778       vam->result_ready = 1;
1779     }
1780 }
1781
1782 static void vl_api_gre_add_del_tunnel_reply_t_handler_json
1783   (vl_api_gre_add_del_tunnel_reply_t * mp)
1784 {
1785   vat_main_t *vam = &vat_main;
1786   vat_json_node_t node;
1787
1788   vat_json_init_object (&node);
1789   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1790   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1791
1792   vat_json_print (vam->ofp, &node);
1793   vat_json_free (&node);
1794
1795   vam->retval = ntohl (mp->retval);
1796   vam->result_ready = 1;
1797 }
1798
1799 static void vl_api_create_vhost_user_if_reply_t_handler
1800   (vl_api_create_vhost_user_if_reply_t * mp)
1801 {
1802   vat_main_t *vam = &vat_main;
1803   i32 retval = ntohl (mp->retval);
1804   if (vam->async_mode)
1805     {
1806       vam->async_errors += (retval < 0);
1807     }
1808   else
1809     {
1810       vam->retval = retval;
1811       vam->sw_if_index = ntohl (mp->sw_if_index);
1812       vam->result_ready = 1;
1813     }
1814 }
1815
1816 static void vl_api_create_vhost_user_if_reply_t_handler_json
1817   (vl_api_create_vhost_user_if_reply_t * mp)
1818 {
1819   vat_main_t *vam = &vat_main;
1820   vat_json_node_t node;
1821
1822   vat_json_init_object (&node);
1823   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1824   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1825
1826   vat_json_print (vam->ofp, &node);
1827   vat_json_free (&node);
1828
1829   vam->retval = ntohl (mp->retval);
1830   vam->result_ready = 1;
1831 }
1832
1833 static void vl_api_ip_address_details_t_handler
1834   (vl_api_ip_address_details_t * mp)
1835 {
1836   vat_main_t *vam = &vat_main;
1837   static ip_address_details_t empty_ip_address_details = { {0} };
1838   ip_address_details_t *address = NULL;
1839   ip_details_t *current_ip_details = NULL;
1840   ip_details_t *details = NULL;
1841
1842   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
1843
1844   if (!details || vam->current_sw_if_index >= vec_len (details)
1845       || !details[vam->current_sw_if_index].present)
1846     {
1847       errmsg ("ip address details arrived but not stored");
1848       errmsg ("ip_dump should be called first");
1849       return;
1850     }
1851
1852   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
1853
1854 #define addresses (current_ip_details->addr)
1855
1856   vec_validate_init_empty (addresses, vec_len (addresses),
1857                            empty_ip_address_details);
1858
1859   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
1860
1861   clib_memcpy (&address->ip, &mp->ip, sizeof (address->ip));
1862   address->prefix_length = mp->prefix_length;
1863 #undef addresses
1864 }
1865
1866 static void vl_api_ip_address_details_t_handler_json
1867   (vl_api_ip_address_details_t * mp)
1868 {
1869   vat_main_t *vam = &vat_main;
1870   vat_json_node_t *node = NULL;
1871   struct in6_addr ip6;
1872   struct in_addr ip4;
1873
1874   if (VAT_JSON_ARRAY != vam->json_tree.type)
1875     {
1876       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1877       vat_json_init_array (&vam->json_tree);
1878     }
1879   node = vat_json_array_add (&vam->json_tree);
1880
1881   vat_json_init_object (node);
1882   if (vam->is_ipv6)
1883     {
1884       clib_memcpy (&ip6, mp->ip, sizeof (ip6));
1885       vat_json_object_add_ip6 (node, "ip", ip6);
1886     }
1887   else
1888     {
1889       clib_memcpy (&ip4, mp->ip, sizeof (ip4));
1890       vat_json_object_add_ip4 (node, "ip", ip4);
1891     }
1892   vat_json_object_add_uint (node, "prefix_length", mp->prefix_length);
1893 }
1894
1895 static void
1896 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
1897 {
1898   vat_main_t *vam = &vat_main;
1899   static ip_details_t empty_ip_details = { 0 };
1900   ip_details_t *ip = NULL;
1901   u32 sw_if_index = ~0;
1902
1903   sw_if_index = ntohl (mp->sw_if_index);
1904
1905   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1906                            sw_if_index, empty_ip_details);
1907
1908   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1909                          sw_if_index);
1910
1911   ip->present = 1;
1912 }
1913
1914 static void
1915 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
1916 {
1917   vat_main_t *vam = &vat_main;
1918
1919   if (VAT_JSON_ARRAY != vam->json_tree.type)
1920     {
1921       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1922       vat_json_init_array (&vam->json_tree);
1923     }
1924   vat_json_array_add_uint (&vam->json_tree,
1925                            clib_net_to_host_u32 (mp->sw_if_index));
1926 }
1927
1928 static void vl_api_map_domain_details_t_handler_json
1929   (vl_api_map_domain_details_t * mp)
1930 {
1931   vat_json_node_t *node = NULL;
1932   vat_main_t *vam = &vat_main;
1933   struct in6_addr ip6;
1934   struct in_addr ip4;
1935
1936   if (VAT_JSON_ARRAY != vam->json_tree.type)
1937     {
1938       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1939       vat_json_init_array (&vam->json_tree);
1940     }
1941
1942   node = vat_json_array_add (&vam->json_tree);
1943   vat_json_init_object (node);
1944
1945   vat_json_object_add_uint (node, "domain_index",
1946                             clib_net_to_host_u32 (mp->domain_index));
1947   clib_memcpy (&ip6, mp->ip6_prefix, sizeof (ip6));
1948   vat_json_object_add_ip6 (node, "ip6_prefix", ip6);
1949   clib_memcpy (&ip4, mp->ip4_prefix, sizeof (ip4));
1950   vat_json_object_add_ip4 (node, "ip4_prefix", ip4);
1951   clib_memcpy (&ip6, mp->ip6_src, sizeof (ip6));
1952   vat_json_object_add_ip6 (node, "ip6_src", ip6);
1953   vat_json_object_add_int (node, "ip6_prefix_len", mp->ip6_prefix_len);
1954   vat_json_object_add_int (node, "ip4_prefix_len", mp->ip4_prefix_len);
1955   vat_json_object_add_int (node, "ip6_src_len", mp->ip6_src_len);
1956   vat_json_object_add_int (node, "ea_bits_len", mp->ea_bits_len);
1957   vat_json_object_add_int (node, "psid_offset", mp->psid_offset);
1958   vat_json_object_add_int (node, "psid_length", mp->psid_length);
1959   vat_json_object_add_uint (node, "flags", mp->flags);
1960   vat_json_object_add_uint (node, "mtu", clib_net_to_host_u16 (mp->mtu));
1961   vat_json_object_add_int (node, "is_translation", mp->is_translation);
1962 }
1963
1964 static void vl_api_map_domain_details_t_handler
1965   (vl_api_map_domain_details_t * mp)
1966 {
1967   vat_main_t *vam = &vat_main;
1968
1969   if (mp->is_translation)
1970     {
1971       print (vam->ofp,
1972              "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U/%d (ip6-src) index: %u",
1973              format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1974              format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1975              format_ip6_address, mp->ip6_src, mp->ip6_src_len,
1976              clib_net_to_host_u32 (mp->domain_index));
1977     }
1978   else
1979     {
1980       print (vam->ofp,
1981              "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U (ip6-src) index: %u",
1982              format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1983              format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1984              format_ip6_address, mp->ip6_src,
1985              clib_net_to_host_u32 (mp->domain_index));
1986     }
1987   print (vam->ofp, "  ea-len %d psid-offset %d psid-len %d mtu %d %s",
1988          mp->ea_bits_len, mp->psid_offset, mp->psid_length, mp->mtu,
1989          mp->is_translation ? "map-t" : "");
1990 }
1991
1992 static void vl_api_map_rule_details_t_handler_json
1993   (vl_api_map_rule_details_t * mp)
1994 {
1995   struct in6_addr ip6;
1996   vat_json_node_t *node = NULL;
1997   vat_main_t *vam = &vat_main;
1998
1999   if (VAT_JSON_ARRAY != vam->json_tree.type)
2000     {
2001       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2002       vat_json_init_array (&vam->json_tree);
2003     }
2004
2005   node = vat_json_array_add (&vam->json_tree);
2006   vat_json_init_object (node);
2007
2008   vat_json_object_add_uint (node, "psid", clib_net_to_host_u16 (mp->psid));
2009   clib_memcpy (&ip6, mp->ip6_dst, sizeof (ip6));
2010   vat_json_object_add_ip6 (node, "ip6_dst", ip6);
2011 }
2012
2013 static void
2014 vl_api_map_rule_details_t_handler (vl_api_map_rule_details_t * mp)
2015 {
2016   vat_main_t *vam = &vat_main;
2017   print (vam->ofp, " %d (psid) %U (ip6-dst)",
2018          clib_net_to_host_u16 (mp->psid), format_ip6_address, mp->ip6_dst);
2019 }
2020
2021 static void
2022 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
2023 {
2024   errmsg ("DHCP compl event: pid %d %s hostname %s host_addr %U "
2025           "router_addr %U host_mac %U",
2026           ntohl (mp->pid), mp->is_ipv6 ? "ipv6" : "ipv4", mp->hostname,
2027           format_ip4_address, &mp->host_address,
2028           format_ip4_address, &mp->router_address,
2029           format_ethernet_address, mp->host_mac);
2030 }
2031
2032 static void vl_api_dhcp_compl_event_t_handler_json
2033   (vl_api_dhcp_compl_event_t * mp)
2034 {
2035   /* JSON output not supported */
2036 }
2037
2038 static void
2039 set_simple_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
2040                               u32 counter)
2041 {
2042   vat_main_t *vam = &vat_main;
2043   static u64 default_counter = 0;
2044
2045   vec_validate_init_empty (vam->simple_interface_counters, vnet_counter_type,
2046                            NULL);
2047   vec_validate_init_empty (vam->simple_interface_counters[vnet_counter_type],
2048                            sw_if_index, default_counter);
2049   vam->simple_interface_counters[vnet_counter_type][sw_if_index] = counter;
2050 }
2051
2052 static void
2053 set_combined_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
2054                                 interface_counter_t counter)
2055 {
2056   vat_main_t *vam = &vat_main;
2057   static interface_counter_t default_counter = { 0, };
2058
2059   vec_validate_init_empty (vam->combined_interface_counters,
2060                            vnet_counter_type, NULL);
2061   vec_validate_init_empty (vam->combined_interface_counters
2062                            [vnet_counter_type], sw_if_index, default_counter);
2063   vam->combined_interface_counters[vnet_counter_type][sw_if_index] = counter;
2064 }
2065
2066 static void vl_api_vnet_interface_simple_counters_t_handler
2067   (vl_api_vnet_interface_simple_counters_t * mp)
2068 {
2069   /* not supported */
2070 }
2071
2072 static void vl_api_vnet_interface_combined_counters_t_handler
2073   (vl_api_vnet_interface_combined_counters_t * mp)
2074 {
2075   /* not supported */
2076 }
2077
2078 static void vl_api_vnet_interface_simple_counters_t_handler_json
2079   (vl_api_vnet_interface_simple_counters_t * mp)
2080 {
2081   u64 *v_packets;
2082   u64 packets;
2083   u32 count;
2084   u32 first_sw_if_index;
2085   int i;
2086
2087   count = ntohl (mp->count);
2088   first_sw_if_index = ntohl (mp->first_sw_if_index);
2089
2090   v_packets = (u64 *) & mp->data;
2091   for (i = 0; i < count; i++)
2092     {
2093       packets = clib_net_to_host_u64 (clib_mem_unaligned (v_packets, u64));
2094       set_simple_interface_counter (mp->vnet_counter_type,
2095                                     first_sw_if_index + i, packets);
2096       v_packets++;
2097     }
2098 }
2099
2100 static void vl_api_vnet_interface_combined_counters_t_handler_json
2101   (vl_api_vnet_interface_combined_counters_t * mp)
2102 {
2103   interface_counter_t counter;
2104   vlib_counter_t *v;
2105   u32 first_sw_if_index;
2106   int i;
2107   u32 count;
2108
2109   count = ntohl (mp->count);
2110   first_sw_if_index = ntohl (mp->first_sw_if_index);
2111
2112   v = (vlib_counter_t *) & mp->data;
2113   for (i = 0; i < count; i++)
2114     {
2115       counter.packets =
2116         clib_net_to_host_u64 (clib_mem_unaligned (&v->packets, u64));
2117       counter.bytes =
2118         clib_net_to_host_u64 (clib_mem_unaligned (&v->bytes, u64));
2119       set_combined_interface_counter (mp->vnet_counter_type,
2120                                       first_sw_if_index + i, counter);
2121       v++;
2122     }
2123 }
2124
2125 static u32
2126 ip4_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2127 {
2128   vat_main_t *vam = &vat_main;
2129   u32 i;
2130
2131   for (i = 0; i < vec_len (vam->ip4_fib_counters_vrf_id_by_index); i++)
2132     {
2133       if (vam->ip4_fib_counters_vrf_id_by_index[i] == vrf_id)
2134         {
2135           return i;
2136         }
2137     }
2138   return ~0;
2139 }
2140
2141 static u32
2142 ip6_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2143 {
2144   vat_main_t *vam = &vat_main;
2145   u32 i;
2146
2147   for (i = 0; i < vec_len (vam->ip6_fib_counters_vrf_id_by_index); i++)
2148     {
2149       if (vam->ip6_fib_counters_vrf_id_by_index[i] == vrf_id)
2150         {
2151           return i;
2152         }
2153     }
2154   return ~0;
2155 }
2156
2157 static void vl_api_vnet_ip4_fib_counters_t_handler
2158   (vl_api_vnet_ip4_fib_counters_t * mp)
2159 {
2160   /* not supported */
2161 }
2162
2163 static void vl_api_vnet_ip4_fib_counters_t_handler_json
2164   (vl_api_vnet_ip4_fib_counters_t * mp)
2165 {
2166   vat_main_t *vam = &vat_main;
2167   vl_api_ip4_fib_counter_t *v;
2168   ip4_fib_counter_t *counter;
2169   struct in_addr ip4;
2170   u32 vrf_id;
2171   u32 vrf_index;
2172   u32 count;
2173   int i;
2174
2175   vrf_id = ntohl (mp->vrf_id);
2176   vrf_index = ip4_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2177   if (~0 == vrf_index)
2178     {
2179       vrf_index = vec_len (vam->ip4_fib_counters_vrf_id_by_index);
2180       vec_validate (vam->ip4_fib_counters_vrf_id_by_index, vrf_index);
2181       vam->ip4_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2182       vec_validate (vam->ip4_fib_counters, vrf_index);
2183       vam->ip4_fib_counters[vrf_index] = NULL;
2184     }
2185
2186   vec_free (vam->ip4_fib_counters[vrf_index]);
2187   v = (vl_api_ip4_fib_counter_t *) & mp->c;
2188   count = ntohl (mp->count);
2189   for (i = 0; i < count; i++)
2190     {
2191       vec_validate (vam->ip4_fib_counters[vrf_index], i);
2192       counter = &vam->ip4_fib_counters[vrf_index][i];
2193       clib_memcpy (&ip4, &v->address, sizeof (ip4));
2194       counter->address = ip4;
2195       counter->address_length = v->address_length;
2196       counter->packets = clib_net_to_host_u64 (v->packets);
2197       counter->bytes = clib_net_to_host_u64 (v->bytes);
2198       v++;
2199     }
2200 }
2201
2202 static void vl_api_vnet_ip4_nbr_counters_t_handler
2203   (vl_api_vnet_ip4_nbr_counters_t * mp)
2204 {
2205   /* not supported */
2206 }
2207
2208 static void vl_api_vnet_ip4_nbr_counters_t_handler_json
2209   (vl_api_vnet_ip4_nbr_counters_t * mp)
2210 {
2211   vat_main_t *vam = &vat_main;
2212   vl_api_ip4_nbr_counter_t *v;
2213   ip4_nbr_counter_t *counter;
2214   u32 sw_if_index;
2215   u32 count;
2216   int i;
2217
2218   sw_if_index = ntohl (mp->sw_if_index);
2219   count = ntohl (mp->count);
2220   vec_validate (vam->ip4_nbr_counters, sw_if_index);
2221
2222   if (mp->begin)
2223     vec_free (vam->ip4_nbr_counters[sw_if_index]);
2224
2225   v = (vl_api_ip4_nbr_counter_t *) & mp->c;
2226   for (i = 0; i < count; i++)
2227     {
2228       vec_validate (vam->ip4_nbr_counters[sw_if_index], i);
2229       counter = &vam->ip4_nbr_counters[sw_if_index][i];
2230       counter->address.s_addr = v->address;
2231       counter->packets = clib_net_to_host_u64 (v->packets);
2232       counter->bytes = clib_net_to_host_u64 (v->bytes);
2233       counter->linkt = v->link_type;
2234       v++;
2235     }
2236 }
2237
2238 static void vl_api_vnet_ip6_fib_counters_t_handler
2239   (vl_api_vnet_ip6_fib_counters_t * mp)
2240 {
2241   /* not supported */
2242 }
2243
2244 static void vl_api_vnet_ip6_fib_counters_t_handler_json
2245   (vl_api_vnet_ip6_fib_counters_t * mp)
2246 {
2247   vat_main_t *vam = &vat_main;
2248   vl_api_ip6_fib_counter_t *v;
2249   ip6_fib_counter_t *counter;
2250   struct in6_addr ip6;
2251   u32 vrf_id;
2252   u32 vrf_index;
2253   u32 count;
2254   int i;
2255
2256   vrf_id = ntohl (mp->vrf_id);
2257   vrf_index = ip6_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2258   if (~0 == vrf_index)
2259     {
2260       vrf_index = vec_len (vam->ip6_fib_counters_vrf_id_by_index);
2261       vec_validate (vam->ip6_fib_counters_vrf_id_by_index, vrf_index);
2262       vam->ip6_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2263       vec_validate (vam->ip6_fib_counters, vrf_index);
2264       vam->ip6_fib_counters[vrf_index] = NULL;
2265     }
2266
2267   vec_free (vam->ip6_fib_counters[vrf_index]);
2268   v = (vl_api_ip6_fib_counter_t *) & mp->c;
2269   count = ntohl (mp->count);
2270   for (i = 0; i < count; i++)
2271     {
2272       vec_validate (vam->ip6_fib_counters[vrf_index], i);
2273       counter = &vam->ip6_fib_counters[vrf_index][i];
2274       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2275       counter->address = ip6;
2276       counter->address_length = v->address_length;
2277       counter->packets = clib_net_to_host_u64 (v->packets);
2278       counter->bytes = clib_net_to_host_u64 (v->bytes);
2279       v++;
2280     }
2281 }
2282
2283 static void vl_api_vnet_ip6_nbr_counters_t_handler
2284   (vl_api_vnet_ip6_nbr_counters_t * mp)
2285 {
2286   /* not supported */
2287 }
2288
2289 static void vl_api_vnet_ip6_nbr_counters_t_handler_json
2290   (vl_api_vnet_ip6_nbr_counters_t * mp)
2291 {
2292   vat_main_t *vam = &vat_main;
2293   vl_api_ip6_nbr_counter_t *v;
2294   ip6_nbr_counter_t *counter;
2295   struct in6_addr ip6;
2296   u32 sw_if_index;
2297   u32 count;
2298   int i;
2299
2300   sw_if_index = ntohl (mp->sw_if_index);
2301   count = ntohl (mp->count);
2302   vec_validate (vam->ip6_nbr_counters, sw_if_index);
2303
2304   if (mp->begin)
2305     vec_free (vam->ip6_nbr_counters[sw_if_index]);
2306
2307   v = (vl_api_ip6_nbr_counter_t *) & mp->c;
2308   for (i = 0; i < count; i++)
2309     {
2310       vec_validate (vam->ip6_nbr_counters[sw_if_index], i);
2311       counter = &vam->ip6_nbr_counters[sw_if_index][i];
2312       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2313       counter->address = ip6;
2314       counter->packets = clib_net_to_host_u64 (v->packets);
2315       counter->bytes = clib_net_to_host_u64 (v->bytes);
2316       v++;
2317     }
2318 }
2319
2320 static void vl_api_get_first_msg_id_reply_t_handler
2321   (vl_api_get_first_msg_id_reply_t * mp)
2322 {
2323   vat_main_t *vam = &vat_main;
2324   i32 retval = ntohl (mp->retval);
2325
2326   if (vam->async_mode)
2327     {
2328       vam->async_errors += (retval < 0);
2329     }
2330   else
2331     {
2332       vam->retval = retval;
2333       vam->result_ready = 1;
2334     }
2335   if (retval >= 0)
2336     {
2337       errmsg ("first message id %d", ntohs (mp->first_msg_id));
2338     }
2339 }
2340
2341 static void vl_api_get_first_msg_id_reply_t_handler_json
2342   (vl_api_get_first_msg_id_reply_t * mp)
2343 {
2344   vat_main_t *vam = &vat_main;
2345   vat_json_node_t node;
2346
2347   vat_json_init_object (&node);
2348   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2349   vat_json_object_add_uint (&node, "first_msg_id",
2350                             (uint) ntohs (mp->first_msg_id));
2351
2352   vat_json_print (vam->ofp, &node);
2353   vat_json_free (&node);
2354
2355   vam->retval = ntohl (mp->retval);
2356   vam->result_ready = 1;
2357 }
2358
2359 static void vl_api_get_node_graph_reply_t_handler
2360   (vl_api_get_node_graph_reply_t * mp)
2361 {
2362   vat_main_t *vam = &vat_main;
2363   api_main_t *am = &api_main;
2364   i32 retval = ntohl (mp->retval);
2365   u8 *pvt_copy, *reply;
2366   void *oldheap;
2367   vlib_node_t *node;
2368   int i;
2369
2370   if (vam->async_mode)
2371     {
2372       vam->async_errors += (retval < 0);
2373     }
2374   else
2375     {
2376       vam->retval = retval;
2377       vam->result_ready = 1;
2378     }
2379
2380   /* "Should never happen..." */
2381   if (retval != 0)
2382     return;
2383
2384   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2385   pvt_copy = vec_dup (reply);
2386
2387   /* Toss the shared-memory original... */
2388   pthread_mutex_lock (&am->vlib_rp->mutex);
2389   oldheap = svm_push_data_heap (am->vlib_rp);
2390
2391   vec_free (reply);
2392
2393   svm_pop_heap (oldheap);
2394   pthread_mutex_unlock (&am->vlib_rp->mutex);
2395
2396   if (vam->graph_nodes)
2397     {
2398       hash_free (vam->graph_node_index_by_name);
2399
2400       for (i = 0; i < vec_len (vam->graph_nodes); i++)
2401         {
2402           node = vam->graph_nodes[i];
2403           vec_free (node->name);
2404           vec_free (node->next_nodes);
2405           vec_free (node);
2406         }
2407       vec_free (vam->graph_nodes);
2408     }
2409
2410   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2411   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2412   vec_free (pvt_copy);
2413
2414   for (i = 0; i < vec_len (vam->graph_nodes); i++)
2415     {
2416       node = vam->graph_nodes[i];
2417       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2418     }
2419 }
2420
2421 static void vl_api_get_node_graph_reply_t_handler_json
2422   (vl_api_get_node_graph_reply_t * mp)
2423 {
2424   vat_main_t *vam = &vat_main;
2425   api_main_t *am = &api_main;
2426   void *oldheap;
2427   vat_json_node_t node;
2428   u8 *reply;
2429
2430   /* $$$$ make this real? */
2431   vat_json_init_object (&node);
2432   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2433   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2434
2435   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2436
2437   /* Toss the shared-memory original... */
2438   pthread_mutex_lock (&am->vlib_rp->mutex);
2439   oldheap = svm_push_data_heap (am->vlib_rp);
2440
2441   vec_free (reply);
2442
2443   svm_pop_heap (oldheap);
2444   pthread_mutex_unlock (&am->vlib_rp->mutex);
2445
2446   vat_json_print (vam->ofp, &node);
2447   vat_json_free (&node);
2448
2449   vam->retval = ntohl (mp->retval);
2450   vam->result_ready = 1;
2451 }
2452
2453 static void
2454 vl_api_one_locator_details_t_handler (vl_api_one_locator_details_t * mp)
2455 {
2456   vat_main_t *vam = &vat_main;
2457   u8 *s = 0;
2458
2459   if (mp->local)
2460     {
2461       s = format (s, "%=16d%=16d%=16d",
2462                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
2463     }
2464   else
2465     {
2466       s = format (s, "%=16U%=16d%=16d",
2467                   mp->is_ipv6 ? format_ip6_address :
2468                   format_ip4_address,
2469                   mp->ip_address, mp->priority, mp->weight);
2470     }
2471
2472   print (vam->ofp, "%v", s);
2473   vec_free (s);
2474 }
2475
2476 static void
2477 vl_api_one_locator_details_t_handler_json (vl_api_one_locator_details_t * mp)
2478 {
2479   vat_main_t *vam = &vat_main;
2480   vat_json_node_t *node = NULL;
2481   struct in6_addr ip6;
2482   struct in_addr ip4;
2483
2484   if (VAT_JSON_ARRAY != vam->json_tree.type)
2485     {
2486       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2487       vat_json_init_array (&vam->json_tree);
2488     }
2489   node = vat_json_array_add (&vam->json_tree);
2490   vat_json_init_object (node);
2491
2492   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2493   vat_json_object_add_uint (node, "priority", mp->priority);
2494   vat_json_object_add_uint (node, "weight", mp->weight);
2495
2496   if (mp->local)
2497     vat_json_object_add_uint (node, "sw_if_index",
2498                               clib_net_to_host_u32 (mp->sw_if_index));
2499   else
2500     {
2501       if (mp->is_ipv6)
2502         {
2503           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2504           vat_json_object_add_ip6 (node, "address", ip6);
2505         }
2506       else
2507         {
2508           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2509           vat_json_object_add_ip4 (node, "address", ip4);
2510         }
2511     }
2512 }
2513
2514 static void
2515 vl_api_one_locator_set_details_t_handler (vl_api_one_locator_set_details_t *
2516                                           mp)
2517 {
2518   vat_main_t *vam = &vat_main;
2519   u8 *ls_name = 0;
2520
2521   ls_name = format (0, "%s", mp->ls_name);
2522
2523   print (vam->ofp, "%=10d%=15v", clib_net_to_host_u32 (mp->ls_index),
2524          ls_name);
2525   vec_free (ls_name);
2526 }
2527
2528 static void
2529   vl_api_one_locator_set_details_t_handler_json
2530   (vl_api_one_locator_set_details_t * mp)
2531 {
2532   vat_main_t *vam = &vat_main;
2533   vat_json_node_t *node = 0;
2534   u8 *ls_name = 0;
2535
2536   ls_name = format (0, "%s", mp->ls_name);
2537   vec_add1 (ls_name, 0);
2538
2539   if (VAT_JSON_ARRAY != vam->json_tree.type)
2540     {
2541       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2542       vat_json_init_array (&vam->json_tree);
2543     }
2544   node = vat_json_array_add (&vam->json_tree);
2545
2546   vat_json_init_object (node);
2547   vat_json_object_add_string_copy (node, "ls_name", ls_name);
2548   vat_json_object_add_uint (node, "ls_index",
2549                             clib_net_to_host_u32 (mp->ls_index));
2550   vec_free (ls_name);
2551 }
2552
2553 static u8 *
2554 format_lisp_flat_eid (u8 * s, va_list * args)
2555 {
2556   u32 type = va_arg (*args, u32);
2557   u8 *eid = va_arg (*args, u8 *);
2558   u32 eid_len = va_arg (*args, u32);
2559
2560   switch (type)
2561     {
2562     case 0:
2563       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
2564     case 1:
2565       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
2566     case 2:
2567       return format (s, "%U", format_ethernet_address, eid);
2568     }
2569   return 0;
2570 }
2571
2572 static u8 *
2573 format_lisp_eid_vat (u8 * s, va_list * args)
2574 {
2575   u32 type = va_arg (*args, u32);
2576   u8 *eid = va_arg (*args, u8 *);
2577   u32 eid_len = va_arg (*args, u32);
2578   u8 *seid = va_arg (*args, u8 *);
2579   u32 seid_len = va_arg (*args, u32);
2580   u32 is_src_dst = va_arg (*args, u32);
2581
2582   if (is_src_dst)
2583     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
2584
2585   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
2586
2587   return s;
2588 }
2589
2590 static void
2591 vl_api_one_eid_table_details_t_handler (vl_api_one_eid_table_details_t * mp)
2592 {
2593   vat_main_t *vam = &vat_main;
2594   u8 *s = 0, *eid = 0;
2595
2596   if (~0 == mp->locator_set_index)
2597     s = format (0, "action: %d", mp->action);
2598   else
2599     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
2600
2601   eid = format (0, "%U", format_lisp_eid_vat,
2602                 mp->eid_type,
2603                 mp->eid,
2604                 mp->eid_prefix_len,
2605                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2606   vec_add1 (eid, 0);
2607
2608   print (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s",
2609          clib_net_to_host_u32 (mp->vni),
2610          eid,
2611          mp->is_local ? "local" : "remote",
2612          s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
2613          clib_net_to_host_u16 (mp->key_id), mp->key);
2614
2615   vec_free (s);
2616   vec_free (eid);
2617 }
2618
2619 static void
2620 vl_api_one_eid_table_details_t_handler_json (vl_api_one_eid_table_details_t
2621                                              * mp)
2622 {
2623   vat_main_t *vam = &vat_main;
2624   vat_json_node_t *node = 0;
2625   u8 *eid = 0;
2626
2627   if (VAT_JSON_ARRAY != vam->json_tree.type)
2628     {
2629       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2630       vat_json_init_array (&vam->json_tree);
2631     }
2632   node = vat_json_array_add (&vam->json_tree);
2633
2634   vat_json_init_object (node);
2635   if (~0 == mp->locator_set_index)
2636     vat_json_object_add_uint (node, "action", mp->action);
2637   else
2638     vat_json_object_add_uint (node, "locator_set_index",
2639                               clib_net_to_host_u32 (mp->locator_set_index));
2640
2641   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
2642   eid = format (0, "%U", format_lisp_eid_vat,
2643                 mp->eid_type,
2644                 mp->eid,
2645                 mp->eid_prefix_len,
2646                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2647   vec_add1 (eid, 0);
2648   vat_json_object_add_string_copy (node, "eid", eid);
2649   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2650   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
2651   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
2652
2653   if (mp->key_id)
2654     {
2655       vat_json_object_add_uint (node, "key_id",
2656                                 clib_net_to_host_u16 (mp->key_id));
2657       vat_json_object_add_string_copy (node, "key", mp->key);
2658     }
2659   vec_free (eid);
2660 }
2661
2662 static void
2663 vl_api_one_stats_details_t_handler (vl_api_one_stats_details_t * mp)
2664 {
2665   vat_main_t *vam = &vat_main;
2666   u8 *seid = 0, *deid = 0;
2667   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
2668
2669   deid = format (0, "%U", format_lisp_eid_vat,
2670                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
2671
2672   seid = format (0, "%U", format_lisp_eid_vat,
2673                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
2674
2675   vec_add1 (deid, 0);
2676   vec_add1 (seid, 0);
2677
2678   if (mp->is_ip4)
2679     format_ip_address_fcn = format_ip4_address;
2680   else
2681     format_ip_address_fcn = format_ip6_address;
2682
2683
2684   print (vam->ofp, "([%d] %s %s) (%U %U) %u %u",
2685          clib_net_to_host_u32 (mp->vni),
2686          seid, deid,
2687          format_ip_address_fcn, mp->lloc,
2688          format_ip_address_fcn, mp->rloc,
2689          clib_net_to_host_u32 (mp->pkt_count),
2690          clib_net_to_host_u32 (mp->bytes));
2691
2692   vec_free (deid);
2693   vec_free (seid);
2694 }
2695
2696 static void
2697 vl_api_one_stats_details_t_handler_json (vl_api_one_stats_details_t * mp)
2698 {
2699   struct in6_addr ip6;
2700   struct in_addr ip4;
2701   vat_main_t *vam = &vat_main;
2702   vat_json_node_t *node = 0;
2703   u8 *deid = 0, *seid = 0;
2704
2705   if (VAT_JSON_ARRAY != vam->json_tree.type)
2706     {
2707       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2708       vat_json_init_array (&vam->json_tree);
2709     }
2710   node = vat_json_array_add (&vam->json_tree);
2711
2712   vat_json_init_object (node);
2713   deid = format (0, "%U", format_lisp_eid_vat,
2714                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
2715
2716   seid = format (0, "%U", format_lisp_eid_vat,
2717                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
2718
2719   vec_add1 (deid, 0);
2720   vec_add1 (seid, 0);
2721
2722   vat_json_object_add_string_copy (node, "seid", seid);
2723   vat_json_object_add_string_copy (node, "deid", deid);
2724   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2725
2726   if (mp->is_ip4)
2727     {
2728       clib_memcpy (&ip4, mp->lloc, sizeof (ip4));
2729       vat_json_object_add_ip4 (node, "lloc", ip4);
2730       clib_memcpy (&ip4, mp->rloc, sizeof (ip4));
2731       vat_json_object_add_ip4 (node, "rloc", ip4);
2732     }
2733   else
2734     {
2735       clib_memcpy (&ip6, mp->lloc, sizeof (ip6));
2736       vat_json_object_add_ip6 (node, "lloc", ip6);
2737       clib_memcpy (&ip6, mp->rloc, sizeof (ip6));
2738       vat_json_object_add_ip6 (node, "rloc", ip6);
2739     }
2740   vat_json_object_add_uint (node, "pkt_count",
2741                             clib_net_to_host_u32 (mp->pkt_count));
2742   vat_json_object_add_uint (node, "bytes", clib_net_to_host_u32 (mp->bytes));
2743
2744   vec_free (deid);
2745   vec_free (seid);
2746 }
2747
2748 static void
2749   vl_api_one_eid_table_map_details_t_handler
2750   (vl_api_one_eid_table_map_details_t * mp)
2751 {
2752   vat_main_t *vam = &vat_main;
2753
2754   u8 *line = format (0, "%=10d%=10d",
2755                      clib_net_to_host_u32 (mp->vni),
2756                      clib_net_to_host_u32 (mp->dp_table));
2757   print (vam->ofp, "%v", line);
2758   vec_free (line);
2759 }
2760
2761 static void
2762   vl_api_one_eid_table_map_details_t_handler_json
2763   (vl_api_one_eid_table_map_details_t * mp)
2764 {
2765   vat_main_t *vam = &vat_main;
2766   vat_json_node_t *node = NULL;
2767
2768   if (VAT_JSON_ARRAY != vam->json_tree.type)
2769     {
2770       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2771       vat_json_init_array (&vam->json_tree);
2772     }
2773   node = vat_json_array_add (&vam->json_tree);
2774   vat_json_init_object (node);
2775   vat_json_object_add_uint (node, "dp_table",
2776                             clib_net_to_host_u32 (mp->dp_table));
2777   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2778 }
2779
2780 static void
2781   vl_api_one_eid_table_vni_details_t_handler
2782   (vl_api_one_eid_table_vni_details_t * mp)
2783 {
2784   vat_main_t *vam = &vat_main;
2785
2786   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
2787   print (vam->ofp, "%v", line);
2788   vec_free (line);
2789 }
2790
2791 static void
2792   vl_api_one_eid_table_vni_details_t_handler_json
2793   (vl_api_one_eid_table_vni_details_t * mp)
2794 {
2795   vat_main_t *vam = &vat_main;
2796   vat_json_node_t *node = NULL;
2797
2798   if (VAT_JSON_ARRAY != vam->json_tree.type)
2799     {
2800       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2801       vat_json_init_array (&vam->json_tree);
2802     }
2803   node = vat_json_array_add (&vam->json_tree);
2804   vat_json_init_object (node);
2805   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2806 }
2807
2808 static void
2809   vl_api_show_one_map_register_state_reply_t_handler
2810   (vl_api_show_one_map_register_state_reply_t * mp)
2811 {
2812   vat_main_t *vam = &vat_main;
2813   int retval = clib_net_to_host_u32 (mp->retval);
2814
2815   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
2816
2817   vam->retval = retval;
2818   vam->result_ready = 1;
2819 }
2820
2821 static void
2822   vl_api_show_one_map_register_state_reply_t_handler_json
2823   (vl_api_show_one_map_register_state_reply_t * mp)
2824 {
2825   vat_main_t *vam = &vat_main;
2826   vat_json_node_t _node, *node = &_node;
2827   int retval = clib_net_to_host_u32 (mp->retval);
2828
2829   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
2830
2831   vat_json_init_object (node);
2832   vat_json_object_add_string_copy (node, "state", s);
2833
2834   vat_json_print (vam->ofp, node);
2835   vat_json_free (node);
2836
2837   vam->retval = retval;
2838   vam->result_ready = 1;
2839   vec_free (s);
2840 }
2841
2842 static void
2843   vl_api_show_one_rloc_probe_state_reply_t_handler
2844   (vl_api_show_one_rloc_probe_state_reply_t * mp)
2845 {
2846   vat_main_t *vam = &vat_main;
2847   int retval = clib_net_to_host_u32 (mp->retval);
2848
2849   if (retval)
2850     goto end;
2851
2852   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
2853 end:
2854   vam->retval = retval;
2855   vam->result_ready = 1;
2856 }
2857
2858 static void
2859   vl_api_show_one_rloc_probe_state_reply_t_handler_json
2860   (vl_api_show_one_rloc_probe_state_reply_t * mp)
2861 {
2862   vat_main_t *vam = &vat_main;
2863   vat_json_node_t _node, *node = &_node;
2864   int retval = clib_net_to_host_u32 (mp->retval);
2865
2866   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
2867   vat_json_init_object (node);
2868   vat_json_object_add_string_copy (node, "state", s);
2869
2870   vat_json_print (vam->ofp, node);
2871   vat_json_free (node);
2872
2873   vam->retval = retval;
2874   vam->result_ready = 1;
2875   vec_free (s);
2876 }
2877
2878 static void
2879   vl_api_show_one_stats_enable_disable_reply_t_handler
2880   (vl_api_show_one_stats_enable_disable_reply_t * mp)
2881 {
2882   vat_main_t *vam = &vat_main;
2883   int retval = clib_net_to_host_u32 (mp->retval);
2884
2885   if (retval)
2886     goto end;
2887
2888   print (vam->ofp, "%s", mp->is_en ? "enabled" : "disabled");
2889 end:
2890   vam->retval = retval;
2891   vam->result_ready = 1;
2892 }
2893
2894 static void
2895   vl_api_show_one_stats_enable_disable_reply_t_handler_json
2896   (vl_api_show_one_stats_enable_disable_reply_t * mp)
2897 {
2898   vat_main_t *vam = &vat_main;
2899   vat_json_node_t _node, *node = &_node;
2900   int retval = clib_net_to_host_u32 (mp->retval);
2901
2902   u8 *s = format (0, "%s", mp->is_en ? "enabled" : "disabled");
2903   vat_json_init_object (node);
2904   vat_json_object_add_string_copy (node, "state", s);
2905
2906   vat_json_print (vam->ofp, node);
2907   vat_json_free (node);
2908
2909   vam->retval = retval;
2910   vam->result_ready = 1;
2911   vec_free (s);
2912 }
2913
2914 static void
2915 api_gpe_fwd_entry_net_to_host (vl_api_gpe_fwd_entry_t * e)
2916 {
2917   e->dp_table = clib_net_to_host_u32 (e->dp_table);
2918   e->fwd_entry_index = clib_net_to_host_u32 (e->fwd_entry_index);
2919   e->vni = clib_net_to_host_u32 (e->vni);
2920 }
2921
2922 static void
2923   gpe_fwd_entries_get_reply_t_net_to_host
2924   (vl_api_gpe_fwd_entries_get_reply_t * mp)
2925 {
2926   u32 i;
2927
2928   mp->count = clib_net_to_host_u32 (mp->count);
2929   for (i = 0; i < mp->count; i++)
2930     {
2931       api_gpe_fwd_entry_net_to_host (&mp->entries[i]);
2932     }
2933 }
2934
2935 static u8 *
2936 format_gpe_encap_mode (u8 * s, va_list * args)
2937 {
2938   u32 mode = va_arg (*args, u32);
2939
2940   switch (mode)
2941     {
2942     case 0:
2943       return format (s, "lisp");
2944     case 1:
2945       return format (s, "vxlan");
2946     }
2947   return 0;
2948 }
2949
2950 static void
2951   vl_api_gpe_get_encap_mode_reply_t_handler
2952   (vl_api_gpe_get_encap_mode_reply_t * mp)
2953 {
2954   vat_main_t *vam = &vat_main;
2955
2956   print (vam->ofp, "gpe mode: %U", format_gpe_encap_mode, mp->encap_mode);
2957   vam->retval = ntohl (mp->retval);
2958   vam->result_ready = 1;
2959 }
2960
2961 static void
2962   vl_api_gpe_get_encap_mode_reply_t_handler_json
2963   (vl_api_gpe_get_encap_mode_reply_t * mp)
2964 {
2965   vat_main_t *vam = &vat_main;
2966   vat_json_node_t node;
2967
2968   u8 *encap_mode = format (0, "%U", format_gpe_encap_mode, mp->encap_mode);
2969   vec_add1 (encap_mode, 0);
2970
2971   vat_json_init_object (&node);
2972   vat_json_object_add_string_copy (&node, "gpe_mode", encap_mode);
2973
2974   vec_free (encap_mode);
2975   vat_json_print (vam->ofp, &node);
2976   vat_json_free (&node);
2977
2978   vam->retval = ntohl (mp->retval);
2979   vam->result_ready = 1;
2980 }
2981
2982 static void
2983   vl_api_gpe_fwd_entry_path_details_t_handler
2984   (vl_api_gpe_fwd_entry_path_details_t * mp)
2985 {
2986   vat_main_t *vam = &vat_main;
2987   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
2988
2989   if (mp->lcl_loc.is_ip4)
2990     format_ip_address_fcn = format_ip4_address;
2991   else
2992     format_ip_address_fcn = format_ip6_address;
2993
2994   print (vam->ofp, "w:%d %30U %30U", mp->rmt_loc.weight,
2995          format_ip_address_fcn, &mp->lcl_loc,
2996          format_ip_address_fcn, &mp->rmt_loc);
2997 }
2998
2999 static void
3000 lisp_fill_locator_node (vat_json_node_t * n, vl_api_gpe_locator_t * loc)
3001 {
3002   struct in6_addr ip6;
3003   struct in_addr ip4;
3004
3005   if (loc->is_ip4)
3006     {
3007       clib_memcpy (&ip4, loc->addr, sizeof (ip4));
3008       vat_json_object_add_ip4 (n, "address", ip4);
3009     }
3010   else
3011     {
3012       clib_memcpy (&ip6, loc->addr, sizeof (ip6));
3013       vat_json_object_add_ip6 (n, "address", ip6);
3014     }
3015   vat_json_object_add_uint (n, "weight", loc->weight);
3016 }
3017
3018 static void
3019   vl_api_gpe_fwd_entry_path_details_t_handler_json
3020   (vl_api_gpe_fwd_entry_path_details_t * mp)
3021 {
3022   vat_main_t *vam = &vat_main;
3023   vat_json_node_t *node = NULL;
3024   vat_json_node_t *loc_node;
3025
3026   if (VAT_JSON_ARRAY != vam->json_tree.type)
3027     {
3028       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3029       vat_json_init_array (&vam->json_tree);
3030     }
3031   node = vat_json_array_add (&vam->json_tree);
3032   vat_json_init_object (node);
3033
3034   loc_node = vat_json_object_add (node, "local_locator");
3035   vat_json_init_object (loc_node);
3036   lisp_fill_locator_node (loc_node, &mp->lcl_loc);
3037
3038   loc_node = vat_json_object_add (node, "remote_locator");
3039   vat_json_init_object (loc_node);
3040   lisp_fill_locator_node (loc_node, &mp->rmt_loc);
3041 }
3042
3043 static void
3044   vl_api_gpe_fwd_entries_get_reply_t_handler
3045   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3046 {
3047   vat_main_t *vam = &vat_main;
3048   u32 i;
3049   int retval = clib_net_to_host_u32 (mp->retval);
3050   vl_api_gpe_fwd_entry_t *e;
3051
3052   if (retval)
3053     goto end;
3054
3055   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3056
3057   for (i = 0; i < mp->count; i++)
3058     {
3059       e = &mp->entries[i];
3060       print (vam->ofp, "%10d %10d %U %40U", e->fwd_entry_index, e->dp_table,
3061              format_lisp_flat_eid, e->eid_type, e->leid, e->leid_prefix_len,
3062              format_lisp_flat_eid, e->eid_type, e->reid, e->reid_prefix_len);
3063     }
3064
3065 end:
3066   vam->retval = retval;
3067   vam->result_ready = 1;
3068 }
3069
3070 static void
3071   vl_api_gpe_fwd_entries_get_reply_t_handler_json
3072   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3073 {
3074   u8 *s = 0;
3075   vat_main_t *vam = &vat_main;
3076   vat_json_node_t *e = 0, root;
3077   u32 i;
3078   int retval = clib_net_to_host_u32 (mp->retval);
3079   vl_api_gpe_fwd_entry_t *fwd;
3080
3081   if (retval)
3082     goto end;
3083
3084   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3085   vat_json_init_array (&root);
3086
3087   for (i = 0; i < mp->count; i++)
3088     {
3089       e = vat_json_array_add (&root);
3090       fwd = &mp->entries[i];
3091
3092       vat_json_init_object (e);
3093       vat_json_object_add_int (e, "fwd_entry_index", fwd->fwd_entry_index);
3094       vat_json_object_add_int (e, "dp_table", fwd->dp_table);
3095       vat_json_object_add_int (e, "vni", fwd->vni);
3096       vat_json_object_add_int (e, "action", fwd->action);
3097
3098       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->leid,
3099                   fwd->leid_prefix_len);
3100       vec_add1 (s, 0);
3101       vat_json_object_add_string_copy (e, "leid", s);
3102       vec_free (s);
3103
3104       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->reid,
3105                   fwd->reid_prefix_len);
3106       vec_add1 (s, 0);
3107       vat_json_object_add_string_copy (e, "reid", s);
3108       vec_free (s);
3109     }
3110
3111   vat_json_print (vam->ofp, &root);
3112   vat_json_free (&root);
3113
3114 end:
3115   vam->retval = retval;
3116   vam->result_ready = 1;
3117 }
3118
3119 static void
3120   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler
3121   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3122 {
3123   vat_main_t *vam = &vat_main;
3124   u32 i, n;
3125   int retval = clib_net_to_host_u32 (mp->retval);
3126
3127   if (retval)
3128     goto end;
3129
3130   n = clib_net_to_host_u32 (mp->count);
3131
3132   for (i = 0; i < n; i++)
3133     print (vam->ofp, "%d", clib_net_to_host_u32 (mp->vnis[i]));
3134
3135 end:
3136   vam->retval = retval;
3137   vam->result_ready = 1;
3138 }
3139
3140 static void
3141   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler_json
3142   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3143 {
3144   vat_main_t *vam = &vat_main;
3145   vat_json_node_t root;
3146   u32 i, n;
3147   int retval = clib_net_to_host_u32 (mp->retval);
3148
3149   if (retval)
3150     goto end;
3151
3152   n = clib_net_to_host_u32 (mp->count);
3153   vat_json_init_array (&root);
3154
3155   for (i = 0; i < n; i++)
3156     vat_json_array_add_uint (&root, clib_net_to_host_u32 (mp->vnis[i]));
3157
3158   vat_json_print (vam->ofp, &root);
3159   vat_json_free (&root);
3160
3161 end:
3162   vam->retval = retval;
3163   vam->result_ready = 1;
3164 }
3165
3166 static void
3167   vl_api_one_l2_arp_entries_get_reply_t_handler
3168   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3169 {
3170   vat_main_t *vam = &vat_main;
3171   u32 i, n;
3172   int retval = clib_net_to_host_u32 (mp->retval);
3173
3174   if (retval)
3175     goto end;
3176
3177   n = clib_net_to_host_u32 (mp->count);
3178
3179   for (i = 0; i < n; i++)
3180     print (vam->ofp, "%U -> %U", format_ip4_address, &mp->entries[i].ip4,
3181            format_ethernet_address, mp->entries[i].mac);
3182
3183 end:
3184   vam->retval = retval;
3185   vam->result_ready = 1;
3186 }
3187
3188 static void
3189   vl_api_one_l2_arp_entries_get_reply_t_handler_json
3190   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3191 {
3192   u8 *s = 0;
3193   vat_main_t *vam = &vat_main;
3194   vat_json_node_t *e = 0, root;
3195   u32 i, n;
3196   int retval = clib_net_to_host_u32 (mp->retval);
3197   vl_api_one_l2_arp_entry_t *arp_entry;
3198
3199   if (retval)
3200     goto end;
3201
3202   n = clib_net_to_host_u32 (mp->count);
3203   vat_json_init_array (&root);
3204
3205   for (i = 0; i < n; i++)
3206     {
3207       e = vat_json_array_add (&root);
3208       arp_entry = &mp->entries[i];
3209
3210       vat_json_init_object (e);
3211       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3212       vec_add1 (s, 0);
3213
3214       vat_json_object_add_string_copy (e, "mac", s);
3215       vec_free (s);
3216
3217       s = format (0, "%U", format_ip4_address, &arp_entry->ip4);
3218       vec_add1 (s, 0);
3219       vat_json_object_add_string_copy (e, "ip4", s);
3220       vec_free (s);
3221     }
3222
3223   vat_json_print (vam->ofp, &root);
3224   vat_json_free (&root);
3225
3226 end:
3227   vam->retval = retval;
3228   vam->result_ready = 1;
3229 }
3230
3231 static void
3232   vl_api_one_l2_arp_bd_get_reply_t_handler
3233   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3234 {
3235   vat_main_t *vam = &vat_main;
3236   u32 i, n;
3237   int retval = clib_net_to_host_u32 (mp->retval);
3238
3239   if (retval)
3240     goto end;
3241
3242   n = clib_net_to_host_u32 (mp->count);
3243
3244   for (i = 0; i < n; i++)
3245     {
3246       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3247     }
3248
3249 end:
3250   vam->retval = retval;
3251   vam->result_ready = 1;
3252 }
3253
3254 static void
3255   vl_api_one_l2_arp_bd_get_reply_t_handler_json
3256   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3257 {
3258   vat_main_t *vam = &vat_main;
3259   vat_json_node_t root;
3260   u32 i, n;
3261   int retval = clib_net_to_host_u32 (mp->retval);
3262
3263   if (retval)
3264     goto end;
3265
3266   n = clib_net_to_host_u32 (mp->count);
3267   vat_json_init_array (&root);
3268
3269   for (i = 0; i < n; i++)
3270     {
3271       vat_json_array_add_uint (&root,
3272                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3273     }
3274
3275   vat_json_print (vam->ofp, &root);
3276   vat_json_free (&root);
3277
3278 end:
3279   vam->retval = retval;
3280   vam->result_ready = 1;
3281 }
3282
3283 static void
3284   vl_api_one_adjacencies_get_reply_t_handler
3285   (vl_api_one_adjacencies_get_reply_t * mp)
3286 {
3287   vat_main_t *vam = &vat_main;
3288   u32 i, n;
3289   int retval = clib_net_to_host_u32 (mp->retval);
3290   vl_api_one_adjacency_t *a;
3291
3292   if (retval)
3293     goto end;
3294
3295   n = clib_net_to_host_u32 (mp->count);
3296
3297   for (i = 0; i < n; i++)
3298     {
3299       a = &mp->adjacencies[i];
3300       print (vam->ofp, "%U %40U",
3301              format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
3302              format_lisp_flat_eid, a->eid_type, a->reid, a->reid_prefix_len);
3303     }
3304
3305 end:
3306   vam->retval = retval;
3307   vam->result_ready = 1;
3308 }
3309
3310 static void
3311   vl_api_one_adjacencies_get_reply_t_handler_json
3312   (vl_api_one_adjacencies_get_reply_t * mp)
3313 {
3314   u8 *s = 0;
3315   vat_main_t *vam = &vat_main;
3316   vat_json_node_t *e = 0, root;
3317   u32 i, n;
3318   int retval = clib_net_to_host_u32 (mp->retval);
3319   vl_api_one_adjacency_t *a;
3320
3321   if (retval)
3322     goto end;
3323
3324   n = clib_net_to_host_u32 (mp->count);
3325   vat_json_init_array (&root);
3326
3327   for (i = 0; i < n; i++)
3328     {
3329       e = vat_json_array_add (&root);
3330       a = &mp->adjacencies[i];
3331
3332       vat_json_init_object (e);
3333       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
3334                   a->leid_prefix_len);
3335       vec_add1 (s, 0);
3336       vat_json_object_add_string_copy (e, "leid", s);
3337       vec_free (s);
3338
3339       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
3340                   a->reid_prefix_len);
3341       vec_add1 (s, 0);
3342       vat_json_object_add_string_copy (e, "reid", s);
3343       vec_free (s);
3344     }
3345
3346   vat_json_print (vam->ofp, &root);
3347   vat_json_free (&root);
3348
3349 end:
3350   vam->retval = retval;
3351   vam->result_ready = 1;
3352 }
3353
3354 static void
3355 vl_api_one_map_server_details_t_handler (vl_api_one_map_server_details_t * mp)
3356 {
3357   vat_main_t *vam = &vat_main;
3358
3359   print (vam->ofp, "%=20U",
3360          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
3361          mp->ip_address);
3362 }
3363
3364 static void
3365   vl_api_one_map_server_details_t_handler_json
3366   (vl_api_one_map_server_details_t * mp)
3367 {
3368   vat_main_t *vam = &vat_main;
3369   vat_json_node_t *node = NULL;
3370   struct in6_addr ip6;
3371   struct in_addr ip4;
3372
3373   if (VAT_JSON_ARRAY != vam->json_tree.type)
3374     {
3375       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3376       vat_json_init_array (&vam->json_tree);
3377     }
3378   node = vat_json_array_add (&vam->json_tree);
3379
3380   vat_json_init_object (node);
3381   if (mp->is_ipv6)
3382     {
3383       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
3384       vat_json_object_add_ip6 (node, "map-server", ip6);
3385     }
3386   else
3387     {
3388       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
3389       vat_json_object_add_ip4 (node, "map-server", ip4);
3390     }
3391 }
3392
3393 static void
3394 vl_api_one_map_resolver_details_t_handler (vl_api_one_map_resolver_details_t
3395                                            * mp)
3396 {
3397   vat_main_t *vam = &vat_main;
3398
3399   print (vam->ofp, "%=20U",
3400          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
3401          mp->ip_address);
3402 }
3403
3404 static void
3405   vl_api_one_map_resolver_details_t_handler_json
3406   (vl_api_one_map_resolver_details_t * mp)
3407 {
3408   vat_main_t *vam = &vat_main;
3409   vat_json_node_t *node = NULL;
3410   struct in6_addr ip6;
3411   struct in_addr ip4;
3412
3413   if (VAT_JSON_ARRAY != vam->json_tree.type)
3414     {
3415       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3416       vat_json_init_array (&vam->json_tree);
3417     }
3418   node = vat_json_array_add (&vam->json_tree);
3419
3420   vat_json_init_object (node);
3421   if (mp->is_ipv6)
3422     {
3423       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
3424       vat_json_object_add_ip6 (node, "map resolver", ip6);
3425     }
3426   else
3427     {
3428       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
3429       vat_json_object_add_ip4 (node, "map resolver", ip4);
3430     }
3431 }
3432
3433 static void
3434 vl_api_show_one_status_reply_t_handler (vl_api_show_one_status_reply_t * mp)
3435 {
3436   vat_main_t *vam = &vat_main;
3437   i32 retval = ntohl (mp->retval);
3438
3439   if (0 <= retval)
3440     {
3441       print (vam->ofp, "feature: %s\ngpe: %s",
3442              mp->feature_status ? "enabled" : "disabled",
3443              mp->gpe_status ? "enabled" : "disabled");
3444     }
3445
3446   vam->retval = retval;
3447   vam->result_ready = 1;
3448 }
3449
3450 static void
3451   vl_api_show_one_status_reply_t_handler_json
3452   (vl_api_show_one_status_reply_t * mp)
3453 {
3454   vat_main_t *vam = &vat_main;
3455   vat_json_node_t node;
3456   u8 *gpe_status = NULL;
3457   u8 *feature_status = NULL;
3458
3459   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
3460   feature_status = format (0, "%s",
3461                            mp->feature_status ? "enabled" : "disabled");
3462   vec_add1 (gpe_status, 0);
3463   vec_add1 (feature_status, 0);
3464
3465   vat_json_init_object (&node);
3466   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
3467   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
3468
3469   vec_free (gpe_status);
3470   vec_free (feature_status);
3471
3472   vat_json_print (vam->ofp, &node);
3473   vat_json_free (&node);
3474
3475   vam->retval = ntohl (mp->retval);
3476   vam->result_ready = 1;
3477 }
3478
3479 static void
3480   vl_api_one_get_map_request_itr_rlocs_reply_t_handler
3481   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
3482 {
3483   vat_main_t *vam = &vat_main;
3484   i32 retval = ntohl (mp->retval);
3485
3486   if (retval >= 0)
3487     {
3488       print (vam->ofp, "%=20s", mp->locator_set_name);
3489     }
3490
3491   vam->retval = retval;
3492   vam->result_ready = 1;
3493 }
3494
3495 static void
3496   vl_api_one_get_map_request_itr_rlocs_reply_t_handler_json
3497   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
3498 {
3499   vat_main_t *vam = &vat_main;
3500   vat_json_node_t *node = NULL;
3501
3502   if (VAT_JSON_ARRAY != vam->json_tree.type)
3503     {
3504       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3505       vat_json_init_array (&vam->json_tree);
3506     }
3507   node = vat_json_array_add (&vam->json_tree);
3508
3509   vat_json_init_object (node);
3510   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
3511
3512   vat_json_print (vam->ofp, node);
3513   vat_json_free (node);
3514
3515   vam->retval = ntohl (mp->retval);
3516   vam->result_ready = 1;
3517 }
3518
3519 static u8 *
3520 format_lisp_map_request_mode (u8 * s, va_list * args)
3521 {
3522   u32 mode = va_arg (*args, u32);
3523
3524   switch (mode)
3525     {
3526     case 0:
3527       return format (0, "dst-only");
3528     case 1:
3529       return format (0, "src-dst");
3530     }
3531   return 0;
3532 }
3533
3534 static void
3535   vl_api_show_one_map_request_mode_reply_t_handler
3536   (vl_api_show_one_map_request_mode_reply_t * mp)
3537 {
3538   vat_main_t *vam = &vat_main;
3539   i32 retval = ntohl (mp->retval);
3540
3541   if (0 <= retval)
3542     {
3543       u32 mode = mp->mode;
3544       print (vam->ofp, "map_request_mode: %U",
3545              format_lisp_map_request_mode, mode);
3546     }
3547
3548   vam->retval = retval;
3549   vam->result_ready = 1;
3550 }
3551
3552 static void
3553   vl_api_show_one_map_request_mode_reply_t_handler_json
3554   (vl_api_show_one_map_request_mode_reply_t * mp)
3555 {
3556   vat_main_t *vam = &vat_main;
3557   vat_json_node_t node;
3558   u8 *s = 0;
3559   u32 mode;
3560
3561   mode = mp->mode;
3562   s = format (0, "%U", format_lisp_map_request_mode, mode);
3563   vec_add1 (s, 0);
3564
3565   vat_json_init_object (&node);
3566   vat_json_object_add_string_copy (&node, "map_request_mode", s);
3567   vat_json_print (vam->ofp, &node);
3568   vat_json_free (&node);
3569
3570   vec_free (s);
3571   vam->retval = ntohl (mp->retval);
3572   vam->result_ready = 1;
3573 }
3574
3575 static void
3576   vl_api_show_one_use_petr_reply_t_handler
3577   (vl_api_show_one_use_petr_reply_t * mp)
3578 {
3579   vat_main_t *vam = &vat_main;
3580   i32 retval = ntohl (mp->retval);
3581
3582   if (0 <= retval)
3583     {
3584       print (vam->ofp, "%s\n", mp->status ? "enabled" : "disabled");
3585       if (mp->status)
3586         {
3587           print (vam->ofp, "Proxy-ETR address; %U",
3588                  mp->is_ip4 ? format_ip4_address : format_ip6_address,
3589                  mp->address);
3590         }
3591     }
3592
3593   vam->retval = retval;
3594   vam->result_ready = 1;
3595 }
3596
3597 static void
3598   vl_api_show_one_use_petr_reply_t_handler_json
3599   (vl_api_show_one_use_petr_reply_t * mp)
3600 {
3601   vat_main_t *vam = &vat_main;
3602   vat_json_node_t node;
3603   u8 *status = 0;
3604   struct in_addr ip4;
3605   struct in6_addr ip6;
3606
3607   status = format (0, "%s", mp->status ? "enabled" : "disabled");
3608   vec_add1 (status, 0);
3609
3610   vat_json_init_object (&node);
3611   vat_json_object_add_string_copy (&node, "status", status);
3612   if (mp->status)
3613     {
3614       if (mp->is_ip4)
3615         {
3616           clib_memcpy (&ip6, mp->address, sizeof (ip6));
3617           vat_json_object_add_ip6 (&node, "address", ip6);
3618         }
3619       else
3620         {
3621           clib_memcpy (&ip4, mp->address, sizeof (ip4));
3622           vat_json_object_add_ip4 (&node, "address", ip4);
3623         }
3624     }
3625
3626   vec_free (status);
3627
3628   vat_json_print (vam->ofp, &node);
3629   vat_json_free (&node);
3630
3631   vam->retval = ntohl (mp->retval);
3632   vam->result_ready = 1;
3633 }
3634
3635 static void
3636 vl_api_show_one_pitr_reply_t_handler (vl_api_show_one_pitr_reply_t * mp)
3637 {
3638   vat_main_t *vam = &vat_main;
3639   i32 retval = ntohl (mp->retval);
3640
3641   if (0 <= retval)
3642     {
3643       print (vam->ofp, "%-20s%-16s",
3644              mp->status ? "enabled" : "disabled",
3645              mp->status ? (char *) mp->locator_set_name : "");
3646     }
3647
3648   vam->retval = retval;
3649   vam->result_ready = 1;
3650 }
3651
3652 static void
3653 vl_api_show_one_pitr_reply_t_handler_json (vl_api_show_one_pitr_reply_t * mp)
3654 {
3655   vat_main_t *vam = &vat_main;
3656   vat_json_node_t node;
3657   u8 *status = 0;
3658
3659   status = format (0, "%s", mp->status ? "enabled" : "disabled");
3660   vec_add1 (status, 0);
3661
3662   vat_json_init_object (&node);
3663   vat_json_object_add_string_copy (&node, "status", status);
3664   if (mp->status)
3665     {
3666       vat_json_object_add_string_copy (&node, "locator_set",
3667                                        mp->locator_set_name);
3668     }
3669
3670   vec_free (status);
3671
3672   vat_json_print (vam->ofp, &node);
3673   vat_json_free (&node);
3674
3675   vam->retval = ntohl (mp->retval);
3676   vam->result_ready = 1;
3677 }
3678
3679 static u8 *
3680 format_policer_type (u8 * s, va_list * va)
3681 {
3682   u32 i = va_arg (*va, u32);
3683
3684   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
3685     s = format (s, "1r2c");
3686   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
3687     s = format (s, "1r3c");
3688   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
3689     s = format (s, "2r3c-2698");
3690   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
3691     s = format (s, "2r3c-4115");
3692   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
3693     s = format (s, "2r3c-mef5cf1");
3694   else
3695     s = format (s, "ILLEGAL");
3696   return s;
3697 }
3698
3699 static u8 *
3700 format_policer_rate_type (u8 * s, va_list * va)
3701 {
3702   u32 i = va_arg (*va, u32);
3703
3704   if (i == SSE2_QOS_RATE_KBPS)
3705     s = format (s, "kbps");
3706   else if (i == SSE2_QOS_RATE_PPS)
3707     s = format (s, "pps");
3708   else
3709     s = format (s, "ILLEGAL");
3710   return s;
3711 }
3712
3713 static u8 *
3714 format_policer_round_type (u8 * s, va_list * va)
3715 {
3716   u32 i = va_arg (*va, u32);
3717
3718   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
3719     s = format (s, "closest");
3720   else if (i == SSE2_QOS_ROUND_TO_UP)
3721     s = format (s, "up");
3722   else if (i == SSE2_QOS_ROUND_TO_DOWN)
3723     s = format (s, "down");
3724   else
3725     s = format (s, "ILLEGAL");
3726   return s;
3727 }
3728
3729 static u8 *
3730 format_policer_action_type (u8 * s, va_list * va)
3731 {
3732   u32 i = va_arg (*va, u32);
3733
3734   if (i == SSE2_QOS_ACTION_DROP)
3735     s = format (s, "drop");
3736   else if (i == SSE2_QOS_ACTION_TRANSMIT)
3737     s = format (s, "transmit");
3738   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3739     s = format (s, "mark-and-transmit");
3740   else
3741     s = format (s, "ILLEGAL");
3742   return s;
3743 }
3744
3745 static u8 *
3746 format_dscp (u8 * s, va_list * va)
3747 {
3748   u32 i = va_arg (*va, u32);
3749   char *t = 0;
3750
3751   switch (i)
3752     {
3753 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
3754       foreach_vnet_dscp
3755 #undef _
3756     default:
3757       return format (s, "ILLEGAL");
3758     }
3759   s = format (s, "%s", t);
3760   return s;
3761 }
3762
3763 static void
3764 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
3765 {
3766   vat_main_t *vam = &vat_main;
3767   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
3768
3769   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3770     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
3771   else
3772     conform_dscp_str = format (0, "");
3773
3774   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3775     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
3776   else
3777     exceed_dscp_str = format (0, "");
3778
3779   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3780     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
3781   else
3782     violate_dscp_str = format (0, "");
3783
3784   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
3785          "rate type %U, round type %U, %s rate, %s color-aware, "
3786          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
3787          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
3788          "conform action %U%s, exceed action %U%s, violate action %U%s",
3789          mp->name,
3790          format_policer_type, mp->type,
3791          ntohl (mp->cir),
3792          ntohl (mp->eir),
3793          clib_net_to_host_u64 (mp->cb),
3794          clib_net_to_host_u64 (mp->eb),
3795          format_policer_rate_type, mp->rate_type,
3796          format_policer_round_type, mp->round_type,
3797          mp->single_rate ? "single" : "dual",
3798          mp->color_aware ? "is" : "not",
3799          ntohl (mp->cir_tokens_per_period),
3800          ntohl (mp->pir_tokens_per_period),
3801          ntohl (mp->scale),
3802          ntohl (mp->current_limit),
3803          ntohl (mp->current_bucket),
3804          ntohl (mp->extended_limit),
3805          ntohl (mp->extended_bucket),
3806          clib_net_to_host_u64 (mp->last_update_time),
3807          format_policer_action_type, mp->conform_action_type,
3808          conform_dscp_str,
3809          format_policer_action_type, mp->exceed_action_type,
3810          exceed_dscp_str,
3811          format_policer_action_type, mp->violate_action_type,
3812          violate_dscp_str);
3813
3814   vec_free (conform_dscp_str);
3815   vec_free (exceed_dscp_str);
3816   vec_free (violate_dscp_str);
3817 }
3818
3819 static void vl_api_policer_details_t_handler_json
3820   (vl_api_policer_details_t * mp)
3821 {
3822   vat_main_t *vam = &vat_main;
3823   vat_json_node_t *node;
3824   u8 *rate_type_str, *round_type_str, *type_str;
3825   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
3826
3827   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
3828   round_type_str =
3829     format (0, "%U", format_policer_round_type, mp->round_type);
3830   type_str = format (0, "%U", format_policer_type, mp->type);
3831   conform_action_str = format (0, "%U", format_policer_action_type,
3832                                mp->conform_action_type);
3833   exceed_action_str = format (0, "%U", format_policer_action_type,
3834                               mp->exceed_action_type);
3835   violate_action_str = format (0, "%U", format_policer_action_type,
3836                                mp->violate_action_type);
3837
3838   if (VAT_JSON_ARRAY != vam->json_tree.type)
3839     {
3840       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3841       vat_json_init_array (&vam->json_tree);
3842     }
3843   node = vat_json_array_add (&vam->json_tree);
3844
3845   vat_json_init_object (node);
3846   vat_json_object_add_string_copy (node, "name", mp->name);
3847   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
3848   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
3849   vat_json_object_add_uint (node, "cb", clib_net_to_host_u64 (mp->cb));
3850   vat_json_object_add_uint (node, "eb", clib_net_to_host_u64 (mp->eb));
3851   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
3852   vat_json_object_add_string_copy (node, "round_type", round_type_str);
3853   vat_json_object_add_string_copy (node, "type", type_str);
3854   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
3855   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
3856   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
3857   vat_json_object_add_uint (node, "cir_tokens_per_period",
3858                             ntohl (mp->cir_tokens_per_period));
3859   vat_json_object_add_uint (node, "eir_tokens_per_period",
3860                             ntohl (mp->pir_tokens_per_period));
3861   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
3862   vat_json_object_add_uint (node, "current_bucket",
3863                             ntohl (mp->current_bucket));
3864   vat_json_object_add_uint (node, "extended_limit",
3865                             ntohl (mp->extended_limit));
3866   vat_json_object_add_uint (node, "extended_bucket",
3867                             ntohl (mp->extended_bucket));
3868   vat_json_object_add_uint (node, "last_update_time",
3869                             ntohl (mp->last_update_time));
3870   vat_json_object_add_string_copy (node, "conform_action",
3871                                    conform_action_str);
3872   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3873     {
3874       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
3875       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
3876       vec_free (dscp_str);
3877     }
3878   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
3879   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3880     {
3881       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
3882       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
3883       vec_free (dscp_str);
3884     }
3885   vat_json_object_add_string_copy (node, "violate_action",
3886                                    violate_action_str);
3887   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3888     {
3889       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
3890       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
3891       vec_free (dscp_str);
3892     }
3893
3894   vec_free (rate_type_str);
3895   vec_free (round_type_str);
3896   vec_free (type_str);
3897   vec_free (conform_action_str);
3898   vec_free (exceed_action_str);
3899   vec_free (violate_action_str);
3900 }
3901
3902 static void
3903 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
3904                                            mp)
3905 {
3906   vat_main_t *vam = &vat_main;
3907   int i, count = ntohl (mp->count);
3908
3909   if (count > 0)
3910     print (vam->ofp, "classify table ids (%d) : ", count);
3911   for (i = 0; i < count; i++)
3912     {
3913       print (vam->ofp, "%d", ntohl (mp->ids[i]));
3914       print (vam->ofp, (i < count - 1) ? "," : "");
3915     }
3916   vam->retval = ntohl (mp->retval);
3917   vam->result_ready = 1;
3918 }
3919
3920 static void
3921   vl_api_classify_table_ids_reply_t_handler_json
3922   (vl_api_classify_table_ids_reply_t * mp)
3923 {
3924   vat_main_t *vam = &vat_main;
3925   int i, count = ntohl (mp->count);
3926
3927   if (count > 0)
3928     {
3929       vat_json_node_t node;
3930
3931       vat_json_init_object (&node);
3932       for (i = 0; i < count; i++)
3933         {
3934           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
3935         }
3936       vat_json_print (vam->ofp, &node);
3937       vat_json_free (&node);
3938     }
3939   vam->retval = ntohl (mp->retval);
3940   vam->result_ready = 1;
3941 }
3942
3943 static void
3944   vl_api_classify_table_by_interface_reply_t_handler
3945   (vl_api_classify_table_by_interface_reply_t * mp)
3946 {
3947   vat_main_t *vam = &vat_main;
3948   u32 table_id;
3949
3950   table_id = ntohl (mp->l2_table_id);
3951   if (table_id != ~0)
3952     print (vam->ofp, "l2 table id : %d", table_id);
3953   else
3954     print (vam->ofp, "l2 table id : No input ACL tables configured");
3955   table_id = ntohl (mp->ip4_table_id);
3956   if (table_id != ~0)
3957     print (vam->ofp, "ip4 table id : %d", table_id);
3958   else
3959     print (vam->ofp, "ip4 table id : No input ACL tables configured");
3960   table_id = ntohl (mp->ip6_table_id);
3961   if (table_id != ~0)
3962     print (vam->ofp, "ip6 table id : %d", table_id);
3963   else
3964     print (vam->ofp, "ip6 table id : No input ACL tables configured");
3965   vam->retval = ntohl (mp->retval);
3966   vam->result_ready = 1;
3967 }
3968
3969 static void
3970   vl_api_classify_table_by_interface_reply_t_handler_json
3971   (vl_api_classify_table_by_interface_reply_t * mp)
3972 {
3973   vat_main_t *vam = &vat_main;
3974   vat_json_node_t node;
3975
3976   vat_json_init_object (&node);
3977
3978   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
3979   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
3980   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
3981
3982   vat_json_print (vam->ofp, &node);
3983   vat_json_free (&node);
3984
3985   vam->retval = ntohl (mp->retval);
3986   vam->result_ready = 1;
3987 }
3988
3989 static void vl_api_policer_add_del_reply_t_handler
3990   (vl_api_policer_add_del_reply_t * mp)
3991 {
3992   vat_main_t *vam = &vat_main;
3993   i32 retval = ntohl (mp->retval);
3994   if (vam->async_mode)
3995     {
3996       vam->async_errors += (retval < 0);
3997     }
3998   else
3999     {
4000       vam->retval = retval;
4001       vam->result_ready = 1;
4002       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
4003         /*
4004          * Note: this is just barely thread-safe, depends on
4005          * the main thread spinning waiting for an answer...
4006          */
4007         errmsg ("policer index %d", ntohl (mp->policer_index));
4008     }
4009 }
4010
4011 static void vl_api_policer_add_del_reply_t_handler_json
4012   (vl_api_policer_add_del_reply_t * mp)
4013 {
4014   vat_main_t *vam = &vat_main;
4015   vat_json_node_t node;
4016
4017   vat_json_init_object (&node);
4018   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
4019   vat_json_object_add_uint (&node, "policer_index",
4020                             ntohl (mp->policer_index));
4021
4022   vat_json_print (vam->ofp, &node);
4023   vat_json_free (&node);
4024
4025   vam->retval = ntohl (mp->retval);
4026   vam->result_ready = 1;
4027 }
4028
4029 /* Format hex dump. */
4030 u8 *
4031 format_hex_bytes (u8 * s, va_list * va)
4032 {
4033   u8 *bytes = va_arg (*va, u8 *);
4034   int n_bytes = va_arg (*va, int);
4035   uword i;
4036
4037   /* Print short or long form depending on byte count. */
4038   uword short_form = n_bytes <= 32;
4039   uword indent = format_get_indent (s);
4040
4041   if (n_bytes == 0)
4042     return s;
4043
4044   for (i = 0; i < n_bytes; i++)
4045     {
4046       if (!short_form && (i % 32) == 0)
4047         s = format (s, "%08x: ", i);
4048       s = format (s, "%02x", bytes[i]);
4049       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
4050         s = format (s, "\n%U", format_white_space, indent);
4051     }
4052
4053   return s;
4054 }
4055
4056 static void
4057 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
4058                                             * mp)
4059 {
4060   vat_main_t *vam = &vat_main;
4061   i32 retval = ntohl (mp->retval);
4062   if (retval == 0)
4063     {
4064       print (vam->ofp, "classify table info :");
4065       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
4066              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
4067              ntohl (mp->miss_next_index));
4068       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
4069              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
4070              ntohl (mp->match_n_vectors));
4071       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
4072              ntohl (mp->mask_length));
4073     }
4074   vam->retval = retval;
4075   vam->result_ready = 1;
4076 }
4077
4078 static void
4079   vl_api_classify_table_info_reply_t_handler_json
4080   (vl_api_classify_table_info_reply_t * mp)
4081 {
4082   vat_main_t *vam = &vat_main;
4083   vat_json_node_t node;
4084
4085   i32 retval = ntohl (mp->retval);
4086   if (retval == 0)
4087     {
4088       vat_json_init_object (&node);
4089
4090       vat_json_object_add_int (&node, "sessions",
4091                                ntohl (mp->active_sessions));
4092       vat_json_object_add_int (&node, "nexttbl",
4093                                ntohl (mp->next_table_index));
4094       vat_json_object_add_int (&node, "nextnode",
4095                                ntohl (mp->miss_next_index));
4096       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
4097       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
4098       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
4099       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
4100                       ntohl (mp->mask_length), 0);
4101       vat_json_object_add_string_copy (&node, "mask", s);
4102
4103       vat_json_print (vam->ofp, &node);
4104       vat_json_free (&node);
4105     }
4106   vam->retval = ntohl (mp->retval);
4107   vam->result_ready = 1;
4108 }
4109
4110 static void
4111 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
4112                                            mp)
4113 {
4114   vat_main_t *vam = &vat_main;
4115
4116   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
4117          ntohl (mp->hit_next_index), ntohl (mp->advance),
4118          ntohl (mp->opaque_index));
4119   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
4120          ntohl (mp->match_length));
4121 }
4122
4123 static void
4124   vl_api_classify_session_details_t_handler_json
4125   (vl_api_classify_session_details_t * mp)
4126 {
4127   vat_main_t *vam = &vat_main;
4128   vat_json_node_t *node = NULL;
4129
4130   if (VAT_JSON_ARRAY != vam->json_tree.type)
4131     {
4132       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4133       vat_json_init_array (&vam->json_tree);
4134     }
4135   node = vat_json_array_add (&vam->json_tree);
4136
4137   vat_json_init_object (node);
4138   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
4139   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
4140   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
4141   u8 *s =
4142     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
4143             0);
4144   vat_json_object_add_string_copy (node, "match", s);
4145 }
4146
4147 static void vl_api_pg_create_interface_reply_t_handler
4148   (vl_api_pg_create_interface_reply_t * mp)
4149 {
4150   vat_main_t *vam = &vat_main;
4151
4152   vam->retval = ntohl (mp->retval);
4153   vam->result_ready = 1;
4154 }
4155
4156 static void vl_api_pg_create_interface_reply_t_handler_json
4157   (vl_api_pg_create_interface_reply_t * mp)
4158 {
4159   vat_main_t *vam = &vat_main;
4160   vat_json_node_t node;
4161
4162   i32 retval = ntohl (mp->retval);
4163   if (retval == 0)
4164     {
4165       vat_json_init_object (&node);
4166
4167       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
4168
4169       vat_json_print (vam->ofp, &node);
4170       vat_json_free (&node);
4171     }
4172   vam->retval = ntohl (mp->retval);
4173   vam->result_ready = 1;
4174 }
4175
4176 static void vl_api_policer_classify_details_t_handler
4177   (vl_api_policer_classify_details_t * mp)
4178 {
4179   vat_main_t *vam = &vat_main;
4180
4181   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
4182          ntohl (mp->table_index));
4183 }
4184
4185 static void vl_api_policer_classify_details_t_handler_json
4186   (vl_api_policer_classify_details_t * mp)
4187 {
4188   vat_main_t *vam = &vat_main;
4189   vat_json_node_t *node;
4190
4191   if (VAT_JSON_ARRAY != vam->json_tree.type)
4192     {
4193       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4194       vat_json_init_array (&vam->json_tree);
4195     }
4196   node = vat_json_array_add (&vam->json_tree);
4197
4198   vat_json_init_object (node);
4199   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
4200   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
4201 }
4202
4203 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler
4204   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
4205 {
4206   vat_main_t *vam = &vat_main;
4207   i32 retval = ntohl (mp->retval);
4208   if (vam->async_mode)
4209     {
4210       vam->async_errors += (retval < 0);
4211     }
4212   else
4213     {
4214       vam->retval = retval;
4215       vam->sw_if_index = ntohl (mp->sw_if_index);
4216       vam->result_ready = 1;
4217     }
4218 }
4219
4220 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler_json
4221   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
4222 {
4223   vat_main_t *vam = &vat_main;
4224   vat_json_node_t node;
4225
4226   vat_json_init_object (&node);
4227   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
4228   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
4229
4230   vat_json_print (vam->ofp, &node);
4231   vat_json_free (&node);
4232
4233   vam->retval = ntohl (mp->retval);
4234   vam->result_ready = 1;
4235 }
4236
4237 static void vl_api_flow_classify_details_t_handler
4238   (vl_api_flow_classify_details_t * mp)
4239 {
4240   vat_main_t *vam = &vat_main;
4241
4242   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
4243          ntohl (mp->table_index));
4244 }
4245
4246 static void vl_api_flow_classify_details_t_handler_json
4247   (vl_api_flow_classify_details_t * mp)
4248 {
4249   vat_main_t *vam = &vat_main;
4250   vat_json_node_t *node;
4251
4252   if (VAT_JSON_ARRAY != vam->json_tree.type)
4253     {
4254       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4255       vat_json_init_array (&vam->json_tree);
4256     }
4257   node = vat_json_array_add (&vam->json_tree);
4258
4259   vat_json_init_object (node);
4260   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
4261   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
4262 }
4263
4264 #define vl_api_vnet_interface_simple_counters_t_endian vl_noop_handler
4265 #define vl_api_vnet_interface_simple_counters_t_print vl_noop_handler
4266 #define vl_api_vnet_interface_combined_counters_t_endian vl_noop_handler
4267 #define vl_api_vnet_interface_combined_counters_t_print vl_noop_handler
4268 #define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
4269 #define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler
4270 #define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler
4271 #define vl_api_vnet_ip6_fib_counters_t_print vl_noop_handler
4272 #define vl_api_vnet_ip4_nbr_counters_t_endian vl_noop_handler
4273 #define vl_api_vnet_ip4_nbr_counters_t_print vl_noop_handler
4274 #define vl_api_vnet_ip6_nbr_counters_t_endian vl_noop_handler
4275 #define vl_api_vnet_ip6_nbr_counters_t_print vl_noop_handler
4276 #define vl_api_one_adjacencies_get_reply_t_endian vl_noop_handler
4277 #define vl_api_one_adjacencies_get_reply_t_print vl_noop_handler
4278 #define vl_api_one_l2_arp_bd_get_reply_t_print vl_noop_handler
4279 #define vl_api_one_l2_arp_entries_get_reply_t_endian vl_noop_handler
4280 #define vl_api_one_l2_arp_entries_get_reply_t_print vl_noop_handler
4281 #define vl_api_one_l2_arp_bd_get_reply_t_endian vl_noop_handler
4282
4283 /*
4284  * Generate boilerplate reply handlers, which
4285  * dig the return value out of the xxx_reply_t API message,
4286  * stick it into vam->retval, and set vam->result_ready
4287  *
4288  * Could also do this by pointing N message decode slots at
4289  * a single function, but that could break in subtle ways.
4290  */
4291
4292 #define foreach_standard_reply_retval_handler           \
4293 _(sw_interface_set_flags_reply)                         \
4294 _(sw_interface_add_del_address_reply)                   \
4295 _(sw_interface_set_table_reply)                         \
4296 _(sw_interface_set_mpls_enable_reply)                   \
4297 _(sw_interface_set_vpath_reply)                         \
4298 _(sw_interface_set_vxlan_bypass_reply)                  \
4299 _(sw_interface_set_l2_bridge_reply)                     \
4300 _(bridge_domain_add_del_reply)                          \
4301 _(sw_interface_set_l2_xconnect_reply)                   \
4302 _(l2fib_add_del_reply)                                  \
4303 _(l2fib_flush_int_reply)                                \
4304 _(l2fib_flush_bd_reply)                                 \
4305 _(ip_add_del_route_reply)                               \
4306 _(ip_mroute_add_del_reply)                              \
4307 _(mpls_route_add_del_reply)                             \
4308 _(mpls_ip_bind_unbind_reply)                            \
4309 _(proxy_arp_add_del_reply)                              \
4310 _(proxy_arp_intfc_enable_disable_reply)                 \
4311 _(sw_interface_set_unnumbered_reply)                    \
4312 _(ip_neighbor_add_del_reply)                            \
4313 _(reset_vrf_reply)                                      \
4314 _(oam_add_del_reply)                                    \
4315 _(reset_fib_reply)                                      \
4316 _(dhcp_proxy_config_reply)                              \
4317 _(dhcp_proxy_set_vss_reply)                             \
4318 _(dhcp_client_config_reply)                             \
4319 _(set_ip_flow_hash_reply)                               \
4320 _(sw_interface_ip6_enable_disable_reply)                \
4321 _(sw_interface_ip6_set_link_local_address_reply)        \
4322 _(ip6nd_proxy_add_del_reply)                            \
4323 _(sw_interface_ip6nd_ra_prefix_reply)                   \
4324 _(sw_interface_ip6nd_ra_config_reply)                   \
4325 _(set_arp_neighbor_limit_reply)                         \
4326 _(l2_patch_add_del_reply)                               \
4327 _(sr_policy_add_reply)                                  \
4328 _(sr_policy_mod_reply)                                  \
4329 _(sr_policy_del_reply)                                  \
4330 _(sr_localsid_add_del_reply)                            \
4331 _(sr_steering_add_del_reply)                            \
4332 _(classify_add_del_session_reply)                       \
4333 _(classify_set_interface_ip_table_reply)                \
4334 _(classify_set_interface_l2_tables_reply)               \
4335 _(l2tpv3_set_tunnel_cookies_reply)                      \
4336 _(l2tpv3_interface_enable_disable_reply)                \
4337 _(l2tpv3_set_lookup_key_reply)                          \
4338 _(l2_fib_clear_table_reply)                             \
4339 _(l2_interface_efp_filter_reply)                        \
4340 _(l2_interface_vlan_tag_rewrite_reply)                  \
4341 _(modify_vhost_user_if_reply)                           \
4342 _(delete_vhost_user_if_reply)                           \
4343 _(want_ip4_arp_events_reply)                            \
4344 _(want_ip6_nd_events_reply)                             \
4345 _(input_acl_set_interface_reply)                        \
4346 _(ipsec_spd_add_del_reply)                              \
4347 _(ipsec_interface_add_del_spd_reply)                    \
4348 _(ipsec_spd_add_del_entry_reply)                        \
4349 _(ipsec_sad_add_del_entry_reply)                        \
4350 _(ipsec_sa_set_key_reply)                               \
4351 _(ipsec_tunnel_if_add_del_reply)                        \
4352 _(ikev2_profile_add_del_reply)                          \
4353 _(ikev2_profile_set_auth_reply)                         \
4354 _(ikev2_profile_set_id_reply)                           \
4355 _(ikev2_profile_set_ts_reply)                           \
4356 _(ikev2_set_local_key_reply)                            \
4357 _(ikev2_set_responder_reply)                            \
4358 _(ikev2_set_ike_transforms_reply)                       \
4359 _(ikev2_set_esp_transforms_reply)                       \
4360 _(ikev2_set_sa_lifetime_reply)                          \
4361 _(ikev2_initiate_sa_init_reply)                         \
4362 _(ikev2_initiate_del_ike_sa_reply)                      \
4363 _(ikev2_initiate_del_child_sa_reply)                    \
4364 _(ikev2_initiate_rekey_child_sa_reply)                  \
4365 _(delete_loopback_reply)                                \
4366 _(bd_ip_mac_add_del_reply)                              \
4367 _(map_del_domain_reply)                                 \
4368 _(map_add_del_rule_reply)                               \
4369 _(want_interface_events_reply)                          \
4370 _(want_stats_reply)                                     \
4371 _(cop_interface_enable_disable_reply)                   \
4372 _(cop_whitelist_enable_disable_reply)                   \
4373 _(sw_interface_clear_stats_reply)                       \
4374 _(ioam_enable_reply)                              \
4375 _(ioam_disable_reply)                              \
4376 _(one_add_del_locator_reply)                            \
4377 _(one_add_del_local_eid_reply)                          \
4378 _(one_add_del_remote_mapping_reply)                     \
4379 _(one_add_del_adjacency_reply)                          \
4380 _(one_add_del_map_resolver_reply)                       \
4381 _(one_add_del_map_server_reply)                         \
4382 _(one_enable_disable_reply)                             \
4383 _(one_rloc_probe_enable_disable_reply)                  \
4384 _(one_map_register_enable_disable_reply)                \
4385 _(one_pitr_set_locator_set_reply)                       \
4386 _(one_map_request_mode_reply)                           \
4387 _(one_add_del_map_request_itr_rlocs_reply)              \
4388 _(one_eid_table_add_del_map_reply)                      \
4389 _(one_use_petr_reply)                                   \
4390 _(one_stats_enable_disable_reply)                       \
4391 _(one_add_del_l2_arp_entry_reply)                       \
4392 _(one_stats_flush_reply)                                \
4393 _(gpe_add_del_fwd_entry_reply)                          \
4394 _(gpe_enable_disable_reply)                             \
4395 _(gpe_set_encap_mode_reply)                             \
4396 _(gpe_add_del_iface_reply)                              \
4397 _(vxlan_gpe_add_del_tunnel_reply)                       \
4398 _(af_packet_delete_reply)                               \
4399 _(policer_classify_set_interface_reply)                 \
4400 _(netmap_create_reply)                                  \
4401 _(netmap_delete_reply)                                  \
4402 _(set_ipfix_exporter_reply)                             \
4403 _(set_ipfix_classify_stream_reply)                      \
4404 _(ipfix_classify_table_add_del_reply)                   \
4405 _(flow_classify_set_interface_reply)                    \
4406 _(sw_interface_span_enable_disable_reply)               \
4407 _(pg_capture_reply)                                     \
4408 _(pg_enable_disable_reply)                              \
4409 _(ip_source_and_port_range_check_add_del_reply)         \
4410 _(ip_source_and_port_range_check_interface_add_del_reply)\
4411 _(delete_subif_reply)                                   \
4412 _(l2_interface_pbb_tag_rewrite_reply)                   \
4413 _(punt_reply)                                           \
4414 _(feature_enable_disable_reply)                         \
4415 _(sw_interface_tag_add_del_reply)                       \
4416 _(sw_interface_set_mtu_reply)
4417
4418 #define _(n)                                    \
4419     static void vl_api_##n##_t_handler          \
4420     (vl_api_##n##_t * mp)                       \
4421     {                                           \
4422         vat_main_t * vam = &vat_main;           \
4423         i32 retval = ntohl(mp->retval);         \
4424         if (vam->async_mode) {                  \
4425             vam->async_errors += (retval < 0);  \
4426         } else {                                \
4427             vam->retval = retval;               \
4428             vam->result_ready = 1;              \
4429         }                                       \
4430     }
4431 foreach_standard_reply_retval_handler;
4432 #undef _
4433
4434 #define _(n)                                    \
4435     static void vl_api_##n##_t_handler_json     \
4436     (vl_api_##n##_t * mp)                       \
4437     {                                           \
4438         vat_main_t * vam = &vat_main;           \
4439         vat_json_node_t node;                   \
4440         vat_json_init_object(&node);            \
4441         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
4442         vat_json_print(vam->ofp, &node);        \
4443         vam->retval = ntohl(mp->retval);        \
4444         vam->result_ready = 1;                  \
4445     }
4446 foreach_standard_reply_retval_handler;
4447 #undef _
4448
4449 /*
4450  * Table of message reply handlers, must include boilerplate handlers
4451  * we just generated
4452  */
4453
4454 #define foreach_vpe_api_reply_msg                                       \
4455 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
4456 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
4457 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
4458 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
4459 _(CONTROL_PING_REPLY, control_ping_reply)                               \
4460 _(CLI_REPLY, cli_reply)                                                 \
4461 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
4462 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
4463   sw_interface_add_del_address_reply)                                   \
4464 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
4465 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
4466 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
4467 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
4468 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
4469   sw_interface_set_l2_xconnect_reply)                                   \
4470 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
4471   sw_interface_set_l2_bridge_reply)                                     \
4472 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
4473 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
4474 _(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply)     \
4475 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
4476 _(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply)                         \
4477 _(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply)                           \
4478 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
4479 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
4480 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
4481 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
4482 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
4483 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
4484 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
4485 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
4486 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
4487 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
4488 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
4489 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
4490   proxy_arp_intfc_enable_disable_reply)                                 \
4491 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
4492 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
4493   sw_interface_set_unnumbered_reply)                                    \
4494 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
4495 _(RESET_VRF_REPLY, reset_vrf_reply)                                     \
4496 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
4497 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
4498 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
4499 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
4500 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
4501 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
4502 _(DHCP_PROXY_DETAILS, dhcp_proxy_details)                               \
4503 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
4504 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
4505 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
4506   sw_interface_ip6_enable_disable_reply)                                \
4507 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY,                        \
4508   sw_interface_ip6_set_link_local_address_reply)                        \
4509 _(IP6ND_PROXY_ADD_DEL_REPLY, ip6nd_proxy_add_del_reply)                 \
4510 _(IP6ND_PROXY_DETAILS, ip6nd_proxy_details)                             \
4511 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
4512   sw_interface_ip6nd_ra_prefix_reply)                                   \
4513 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
4514   sw_interface_ip6nd_ra_config_reply)                                   \
4515 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
4516 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
4517 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
4518 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
4519 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
4520 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
4521 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
4522 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
4523 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
4524 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
4525 classify_set_interface_ip_table_reply)                                  \
4526 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
4527   classify_set_interface_l2_tables_reply)                               \
4528 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
4529 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
4530 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
4531 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
4532 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
4533   l2tpv3_interface_enable_disable_reply)                                \
4534 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
4535 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
4536 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
4537 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
4538 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
4539 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
4540 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
4541 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
4542 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
4543 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
4544 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
4545 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
4546 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
4547 _(SHOW_VERSION_REPLY, show_version_reply)                               \
4548 _(L2_FIB_TABLE_DETAILS, l2_fib_table_details)                           \
4549 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)           \
4550 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
4551 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
4552 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
4553 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
4554 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
4555 _(IP6_ND_EVENT, ip6_nd_event)                                           \
4556 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
4557 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
4558 _(IP_DETAILS, ip_details)                                               \
4559 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
4560 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
4561 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
4562 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
4563 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
4564 _(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply)         \
4565 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
4566 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
4567 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
4568 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
4569 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
4570 _(IKEV2_SET_RESPONDER_REPLY, ikev2_set_responder_reply)                 \
4571 _(IKEV2_SET_IKE_TRANSFORMS_REPLY, ikev2_set_ike_transforms_reply)       \
4572 _(IKEV2_SET_ESP_TRANSFORMS_REPLY, ikev2_set_esp_transforms_reply)       \
4573 _(IKEV2_SET_SA_LIFETIME_REPLY, ikev2_set_sa_lifetime_reply)             \
4574 _(IKEV2_INITIATE_SA_INIT_REPLY, ikev2_initiate_sa_init_reply)           \
4575 _(IKEV2_INITIATE_DEL_IKE_SA_REPLY, ikev2_initiate_del_ike_sa_reply)     \
4576 _(IKEV2_INITIATE_DEL_CHILD_SA_REPLY, ikev2_initiate_del_child_sa_reply) \
4577 _(IKEV2_INITIATE_REKEY_CHILD_SA_REPLY, ikev2_initiate_rekey_child_sa_reply) \
4578 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
4579 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
4580 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
4581 _(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply)                           \
4582 _(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply)                           \
4583 _(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply)                       \
4584 _(MAP_DOMAIN_DETAILS, map_domain_details)                               \
4585 _(MAP_RULE_DETAILS, map_rule_details)                                   \
4586 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
4587 _(WANT_STATS_REPLY, want_stats_reply)                                   \
4588 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
4589 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
4590 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
4591 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
4592 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
4593 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
4594 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
4595 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
4596 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
4597 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
4598 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
4599 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
4600 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
4601 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
4602 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
4603 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
4604   one_map_register_enable_disable_reply)                                \
4605 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
4606   one_rloc_probe_enable_disable_reply)                                  \
4607 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
4608 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
4609 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
4610 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
4611 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
4612 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
4613 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
4614 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
4615 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
4616 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
4617 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
4618 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
4619 _(ONE_STATS_DETAILS, one_stats_details)                                 \
4620 _(ONE_STATS_FLUSH_REPLY, one_stats_flush_reply)                         \
4621 _(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply)       \
4622 _(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,                                  \
4623   show_one_stats_enable_disable_reply)                                  \
4624 _(ONE_ADD_DEL_L2_ARP_ENTRY_REPLY, one_add_del_l2_arp_entry_reply)       \
4625 _(ONE_L2_ARP_BD_GET_REPLY, one_l2_arp_bd_get_reply)                     \
4626 _(ONE_L2_ARP_ENTRIES_GET_REPLY, one_l2_arp_entries_get_reply)           \
4627 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
4628 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
4629 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
4630 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
4631 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
4632 _(GPE_FWD_ENTRY_VNIS_GET_REPLY, gpe_fwd_entry_vnis_get_reply)           \
4633 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
4634 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
4635   gpe_fwd_entry_path_details)                                           \
4636 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
4637 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
4638   one_add_del_map_request_itr_rlocs_reply)                              \
4639 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
4640   one_get_map_request_itr_rlocs_reply)                                  \
4641 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
4642 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
4643 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
4644 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
4645 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
4646   show_one_map_register_state_reply)                                    \
4647 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
4648 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
4649 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
4650 _(POLICER_DETAILS, policer_details)                                     \
4651 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
4652 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
4653 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
4654 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
4655 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
4656 _(MPLS_FIB_DETAILS, mpls_fib_details)                                   \
4657 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
4658 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
4659 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
4660 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
4661 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
4662 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
4663 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
4664 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
4665 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
4666 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
4667 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
4668 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
4669 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
4670 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
4671 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
4672 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
4673 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
4674 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
4675 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
4676  ip_source_and_port_range_check_add_del_reply)                          \
4677 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
4678  ip_source_and_port_range_check_interface_add_del_reply)                \
4679 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
4680 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
4681 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
4682 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
4683 _(PUNT_REPLY, punt_reply)                                               \
4684 _(IP_FIB_DETAILS, ip_fib_details)                                       \
4685 _(IP6_FIB_DETAILS, ip6_fib_details)                                     \
4686 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
4687 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
4688 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
4689 _(SW_INTERFACE_SET_MTU_REPLY, sw_interface_set_mtu_reply)               \
4690 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
4691 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)
4692
4693 #define foreach_standalone_reply_msg                                    \
4694 _(SW_INTERFACE_SET_FLAGS, sw_interface_set_flags)                       \
4695 _(VNET_INTERFACE_SIMPLE_COUNTERS, vnet_interface_simple_counters)       \
4696 _(VNET_INTERFACE_COMBINED_COUNTERS, vnet_interface_combined_counters)   \
4697 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
4698 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
4699 _(VNET_IP4_NBR_COUNTERS, vnet_ip4_nbr_counters)                         \
4700 _(VNET_IP6_NBR_COUNTERS, vnet_ip6_nbr_counters)
4701
4702 typedef struct
4703 {
4704   u8 *name;
4705   u32 value;
4706 } name_sort_t;
4707
4708
4709 #define STR_VTR_OP_CASE(op)     \
4710     case L2_VTR_ ## op:         \
4711         return "" # op;
4712
4713 static const char *
4714 str_vtr_op (u32 vtr_op)
4715 {
4716   switch (vtr_op)
4717     {
4718       STR_VTR_OP_CASE (DISABLED);
4719       STR_VTR_OP_CASE (PUSH_1);
4720       STR_VTR_OP_CASE (PUSH_2);
4721       STR_VTR_OP_CASE (POP_1);
4722       STR_VTR_OP_CASE (POP_2);
4723       STR_VTR_OP_CASE (TRANSLATE_1_1);
4724       STR_VTR_OP_CASE (TRANSLATE_1_2);
4725       STR_VTR_OP_CASE (TRANSLATE_2_1);
4726       STR_VTR_OP_CASE (TRANSLATE_2_2);
4727     }
4728
4729   return "UNKNOWN";
4730 }
4731
4732 static int
4733 dump_sub_interface_table (vat_main_t * vam)
4734 {
4735   const sw_interface_subif_t *sub = NULL;
4736
4737   if (vam->json_output)
4738     {
4739       clib_warning
4740         ("JSON output supported only for VPE API calls and dump_stats_table");
4741       return -99;
4742     }
4743
4744   print (vam->ofp,
4745          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
4746          "Interface", "sw_if_index",
4747          "sub id", "dot1ad", "tags", "outer id",
4748          "inner id", "exact", "default", "outer any", "inner any");
4749
4750   vec_foreach (sub, vam->sw_if_subif_table)
4751   {
4752     print (vam->ofp,
4753            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
4754            sub->interface_name,
4755            sub->sw_if_index,
4756            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
4757            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
4758            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
4759            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
4760     if (sub->vtr_op != L2_VTR_DISABLED)
4761       {
4762         print (vam->ofp,
4763                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
4764                "tag1: %d tag2: %d ]",
4765                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
4766                sub->vtr_tag1, sub->vtr_tag2);
4767       }
4768   }
4769
4770   return 0;
4771 }
4772
4773 static int
4774 name_sort_cmp (void *a1, void *a2)
4775 {
4776   name_sort_t *n1 = a1;
4777   name_sort_t *n2 = a2;
4778
4779   return strcmp ((char *) n1->name, (char *) n2->name);
4780 }
4781
4782 static int
4783 dump_interface_table (vat_main_t * vam)
4784 {
4785   hash_pair_t *p;
4786   name_sort_t *nses = 0, *ns;
4787
4788   if (vam->json_output)
4789     {
4790       clib_warning
4791         ("JSON output supported only for VPE API calls and dump_stats_table");
4792       return -99;
4793     }
4794
4795   /* *INDENT-OFF* */
4796   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
4797   ({
4798     vec_add2 (nses, ns, 1);
4799     ns->name = (u8 *)(p->key);
4800     ns->value = (u32) p->value[0];
4801   }));
4802   /* *INDENT-ON* */
4803
4804   vec_sort_with_function (nses, name_sort_cmp);
4805
4806   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
4807   vec_foreach (ns, nses)
4808   {
4809     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
4810   }
4811   vec_free (nses);
4812   return 0;
4813 }
4814
4815 static int
4816 dump_ip_table (vat_main_t * vam, int is_ipv6)
4817 {
4818   const ip_details_t *det = NULL;
4819   const ip_address_details_t *address = NULL;
4820   u32 i = ~0;
4821
4822   print (vam->ofp, "%-12s", "sw_if_index");
4823
4824   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
4825   {
4826     i++;
4827     if (!det->present)
4828       {
4829         continue;
4830       }
4831     print (vam->ofp, "%-12d", i);
4832     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
4833     if (!det->addr)
4834       {
4835         continue;
4836       }
4837     vec_foreach (address, det->addr)
4838     {
4839       print (vam->ofp,
4840              "            %-30U%-13d",
4841              is_ipv6 ? format_ip6_address : format_ip4_address,
4842              address->ip, address->prefix_length);
4843     }
4844   }
4845
4846   return 0;
4847 }
4848
4849 static int
4850 dump_ipv4_table (vat_main_t * vam)
4851 {
4852   if (vam->json_output)
4853     {
4854       clib_warning
4855         ("JSON output supported only for VPE API calls and dump_stats_table");
4856       return -99;
4857     }
4858
4859   return dump_ip_table (vam, 0);
4860 }
4861
4862 static int
4863 dump_ipv6_table (vat_main_t * vam)
4864 {
4865   if (vam->json_output)
4866     {
4867       clib_warning
4868         ("JSON output supported only for VPE API calls and dump_stats_table");
4869       return -99;
4870     }
4871
4872   return dump_ip_table (vam, 1);
4873 }
4874
4875 static char *
4876 counter_type_to_str (u8 counter_type, u8 is_combined)
4877 {
4878   if (!is_combined)
4879     {
4880       switch (counter_type)
4881         {
4882         case VNET_INTERFACE_COUNTER_DROP:
4883           return "drop";
4884         case VNET_INTERFACE_COUNTER_PUNT:
4885           return "punt";
4886         case VNET_INTERFACE_COUNTER_IP4:
4887           return "ip4";
4888         case VNET_INTERFACE_COUNTER_IP6:
4889           return "ip6";
4890         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
4891           return "rx-no-buf";
4892         case VNET_INTERFACE_COUNTER_RX_MISS:
4893           return "rx-miss";
4894         case VNET_INTERFACE_COUNTER_RX_ERROR:
4895           return "rx-error";
4896         case VNET_INTERFACE_COUNTER_TX_ERROR:
4897           return "tx-error";
4898         default:
4899           return "INVALID-COUNTER-TYPE";
4900         }
4901     }
4902   else
4903     {
4904       switch (counter_type)
4905         {
4906         case VNET_INTERFACE_COUNTER_RX:
4907           return "rx";
4908         case VNET_INTERFACE_COUNTER_TX:
4909           return "tx";
4910         default:
4911           return "INVALID-COUNTER-TYPE";
4912         }
4913     }
4914 }
4915
4916 static int
4917 dump_stats_table (vat_main_t * vam)
4918 {
4919   vat_json_node_t node;
4920   vat_json_node_t *msg_array;
4921   vat_json_node_t *msg;
4922   vat_json_node_t *counter_array;
4923   vat_json_node_t *counter;
4924   interface_counter_t c;
4925   u64 packets;
4926   ip4_fib_counter_t *c4;
4927   ip6_fib_counter_t *c6;
4928   ip4_nbr_counter_t *n4;
4929   ip6_nbr_counter_t *n6;
4930   int i, j;
4931
4932   if (!vam->json_output)
4933     {
4934       clib_warning ("dump_stats_table supported only in JSON format");
4935       return -99;
4936     }
4937
4938   vat_json_init_object (&node);
4939
4940   /* interface counters */
4941   msg_array = vat_json_object_add (&node, "interface_counters");
4942   vat_json_init_array (msg_array);
4943   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
4944     {
4945       msg = vat_json_array_add (msg_array);
4946       vat_json_init_object (msg);
4947       vat_json_object_add_string_copy (msg, "vnet_counter_type",
4948                                        (u8 *) counter_type_to_str (i, 0));
4949       vat_json_object_add_int (msg, "is_combined", 0);
4950       counter_array = vat_json_object_add (msg, "data");
4951       vat_json_init_array (counter_array);
4952       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
4953         {
4954           packets = vam->simple_interface_counters[i][j];
4955           vat_json_array_add_uint (counter_array, packets);
4956         }
4957     }
4958   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
4959     {
4960       msg = vat_json_array_add (msg_array);
4961       vat_json_init_object (msg);
4962       vat_json_object_add_string_copy (msg, "vnet_counter_type",
4963                                        (u8 *) counter_type_to_str (i, 1));
4964       vat_json_object_add_int (msg, "is_combined", 1);
4965       counter_array = vat_json_object_add (msg, "data");
4966       vat_json_init_array (counter_array);
4967       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
4968         {
4969           c = vam->combined_interface_counters[i][j];
4970           counter = vat_json_array_add (counter_array);
4971           vat_json_init_object (counter);
4972           vat_json_object_add_uint (counter, "packets", c.packets);
4973           vat_json_object_add_uint (counter, "bytes", c.bytes);
4974         }
4975     }
4976
4977   /* ip4 fib counters */
4978   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
4979   vat_json_init_array (msg_array);
4980   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
4981     {
4982       msg = vat_json_array_add (msg_array);
4983       vat_json_init_object (msg);
4984       vat_json_object_add_uint (msg, "vrf_id",
4985                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
4986       counter_array = vat_json_object_add (msg, "c");
4987       vat_json_init_array (counter_array);
4988       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
4989         {
4990           counter = vat_json_array_add (counter_array);
4991           vat_json_init_object (counter);
4992           c4 = &vam->ip4_fib_counters[i][j];
4993           vat_json_object_add_ip4 (counter, "address", c4->address);
4994           vat_json_object_add_uint (counter, "address_length",
4995                                     c4->address_length);
4996           vat_json_object_add_uint (counter, "packets", c4->packets);
4997           vat_json_object_add_uint (counter, "bytes", c4->bytes);
4998         }
4999     }
5000
5001   /* ip6 fib counters */
5002   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
5003   vat_json_init_array (msg_array);
5004   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
5005     {
5006       msg = vat_json_array_add (msg_array);
5007       vat_json_init_object (msg);
5008       vat_json_object_add_uint (msg, "vrf_id",
5009                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
5010       counter_array = vat_json_object_add (msg, "c");
5011       vat_json_init_array (counter_array);
5012       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
5013         {
5014           counter = vat_json_array_add (counter_array);
5015           vat_json_init_object (counter);
5016           c6 = &vam->ip6_fib_counters[i][j];
5017           vat_json_object_add_ip6 (counter, "address", c6->address);
5018           vat_json_object_add_uint (counter, "address_length",
5019                                     c6->address_length);
5020           vat_json_object_add_uint (counter, "packets", c6->packets);
5021           vat_json_object_add_uint (counter, "bytes", c6->bytes);
5022         }
5023     }
5024
5025   /* ip4 nbr counters */
5026   msg_array = vat_json_object_add (&node, "ip4_nbr_counters");
5027   vat_json_init_array (msg_array);
5028   for (i = 0; i < vec_len (vam->ip4_nbr_counters); i++)
5029     {
5030       msg = vat_json_array_add (msg_array);
5031       vat_json_init_object (msg);
5032       vat_json_object_add_uint (msg, "sw_if_index", i);
5033       counter_array = vat_json_object_add (msg, "c");
5034       vat_json_init_array (counter_array);
5035       for (j = 0; j < vec_len (vam->ip4_nbr_counters[i]); j++)
5036         {
5037           counter = vat_json_array_add (counter_array);
5038           vat_json_init_object (counter);
5039           n4 = &vam->ip4_nbr_counters[i][j];
5040           vat_json_object_add_ip4 (counter, "address", n4->address);
5041           vat_json_object_add_uint (counter, "link-type", n4->linkt);
5042           vat_json_object_add_uint (counter, "packets", n4->packets);
5043           vat_json_object_add_uint (counter, "bytes", n4->bytes);
5044         }
5045     }
5046
5047   /* ip6 nbr counters */
5048   msg_array = vat_json_object_add (&node, "ip6_nbr_counters");
5049   vat_json_init_array (msg_array);
5050   for (i = 0; i < vec_len (vam->ip6_nbr_counters); i++)
5051     {
5052       msg = vat_json_array_add (msg_array);
5053       vat_json_init_object (msg);
5054       vat_json_object_add_uint (msg, "sw_if_index", i);
5055       counter_array = vat_json_object_add (msg, "c");
5056       vat_json_init_array (counter_array);
5057       for (j = 0; j < vec_len (vam->ip6_nbr_counters[i]); j++)
5058         {
5059           counter = vat_json_array_add (counter_array);
5060           vat_json_init_object (counter);
5061           n6 = &vam->ip6_nbr_counters[i][j];
5062           vat_json_object_add_ip6 (counter, "address", n6->address);
5063           vat_json_object_add_uint (counter, "packets", n6->packets);
5064           vat_json_object_add_uint (counter, "bytes", n6->bytes);
5065         }
5066     }
5067
5068   vat_json_print (vam->ofp, &node);
5069   vat_json_free (&node);
5070
5071   return 0;
5072 }
5073
5074 int
5075 exec (vat_main_t * vam)
5076 {
5077   api_main_t *am = &api_main;
5078   vl_api_cli_t *mp;
5079   f64 timeout;
5080   void *oldheap;
5081   u8 *cmd = 0;
5082   unformat_input_t *i = vam->input;
5083
5084   if (vec_len (i->buffer) == 0)
5085     return -1;
5086
5087   if (vam->exec_mode == 0 && unformat (i, "mode"))
5088     {
5089       vam->exec_mode = 1;
5090       return 0;
5091     }
5092   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
5093     {
5094       vam->exec_mode = 0;
5095       return 0;
5096     }
5097
5098
5099   M (CLI, mp);
5100
5101   /*
5102    * Copy cmd into shared memory.
5103    * In order for the CLI command to work, it
5104    * must be a vector ending in \n, not a C-string ending
5105    * in \n\0.
5106    */
5107   pthread_mutex_lock (&am->vlib_rp->mutex);
5108   oldheap = svm_push_data_heap (am->vlib_rp);
5109
5110   vec_validate (cmd, vec_len (vam->input->buffer) - 1);
5111   clib_memcpy (cmd, vam->input->buffer, vec_len (vam->input->buffer));
5112
5113   svm_pop_heap (oldheap);
5114   pthread_mutex_unlock (&am->vlib_rp->mutex);
5115
5116   mp->cmd_in_shmem = pointer_to_uword (cmd);
5117   S (mp);
5118   timeout = vat_time_now (vam) + 10.0;
5119
5120   while (vat_time_now (vam) < timeout)
5121     {
5122       if (vam->result_ready == 1)
5123         {
5124           u8 *free_me;
5125           if (vam->shmem_result != NULL)
5126             print (vam->ofp, "%s", vam->shmem_result);
5127           pthread_mutex_lock (&am->vlib_rp->mutex);
5128           oldheap = svm_push_data_heap (am->vlib_rp);
5129
5130           free_me = (u8 *) vam->shmem_result;
5131           vec_free (free_me);
5132
5133           svm_pop_heap (oldheap);
5134           pthread_mutex_unlock (&am->vlib_rp->mutex);
5135           return 0;
5136         }
5137     }
5138   return -99;
5139 }
5140
5141 /*
5142  * Future replacement of exec() that passes CLI buffers directly in
5143  * the API messages instead of an additional shared memory area.
5144  */
5145 static int
5146 exec_inband (vat_main_t * vam)
5147 {
5148   vl_api_cli_inband_t *mp;
5149   unformat_input_t *i = vam->input;
5150   int ret;
5151
5152   if (vec_len (i->buffer) == 0)
5153     return -1;
5154
5155   if (vam->exec_mode == 0 && unformat (i, "mode"))
5156     {
5157       vam->exec_mode = 1;
5158       return 0;
5159     }
5160   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
5161     {
5162       vam->exec_mode = 0;
5163       return 0;
5164     }
5165
5166   /*
5167    * In order for the CLI command to work, it
5168    * must be a vector ending in \n, not a C-string ending
5169    * in \n\0.
5170    */
5171   u32 len = vec_len (vam->input->buffer);
5172   M2 (CLI_INBAND, mp, len);
5173   clib_memcpy (mp->cmd, vam->input->buffer, len);
5174   mp->length = htonl (len);
5175
5176   S (mp);
5177   W2 (ret, print (vam->ofp, "%s", vam->cmd_reply));
5178   return ret;
5179 }
5180
5181 static int
5182 api_create_loopback (vat_main_t * vam)
5183 {
5184   unformat_input_t *i = vam->input;
5185   vl_api_create_loopback_t *mp;
5186   vl_api_create_loopback_instance_t *mp_lbi;
5187   u8 mac_address[6];
5188   u8 mac_set = 0;
5189   u8 is_specified = 0;
5190   u32 user_instance = 0;
5191   int ret;
5192
5193   memset (mac_address, 0, sizeof (mac_address));
5194
5195   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5196     {
5197       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5198         mac_set = 1;
5199       if (unformat (i, "instance %d", &user_instance))
5200         is_specified = 1;
5201       else
5202         break;
5203     }
5204
5205   if (is_specified)
5206     {
5207       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
5208       mp_lbi->is_specified = is_specified;
5209       if (is_specified)
5210         mp_lbi->user_instance = htonl (user_instance);
5211       if (mac_set)
5212         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
5213       S (mp_lbi);
5214     }
5215   else
5216     {
5217       /* Construct the API message */
5218       M (CREATE_LOOPBACK, mp);
5219       if (mac_set)
5220         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
5221       S (mp);
5222     }
5223
5224   W (ret);
5225   return ret;
5226 }
5227
5228 static int
5229 api_delete_loopback (vat_main_t * vam)
5230 {
5231   unformat_input_t *i = vam->input;
5232   vl_api_delete_loopback_t *mp;
5233   u32 sw_if_index = ~0;
5234   int ret;
5235
5236   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5237     {
5238       if (unformat (i, "sw_if_index %d", &sw_if_index))
5239         ;
5240       else
5241         break;
5242     }
5243
5244   if (sw_if_index == ~0)
5245     {
5246       errmsg ("missing sw_if_index");
5247       return -99;
5248     }
5249
5250   /* Construct the API message */
5251   M (DELETE_LOOPBACK, mp);
5252   mp->sw_if_index = ntohl (sw_if_index);
5253
5254   S (mp);
5255   W (ret);
5256   return ret;
5257 }
5258
5259 static int
5260 api_want_stats (vat_main_t * vam)
5261 {
5262   unformat_input_t *i = vam->input;
5263   vl_api_want_stats_t *mp;
5264   int enable = -1;
5265   int ret;
5266
5267   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5268     {
5269       if (unformat (i, "enable"))
5270         enable = 1;
5271       else if (unformat (i, "disable"))
5272         enable = 0;
5273       else
5274         break;
5275     }
5276
5277   if (enable == -1)
5278     {
5279       errmsg ("missing enable|disable");
5280       return -99;
5281     }
5282
5283   M (WANT_STATS, mp);
5284   mp->enable_disable = enable;
5285
5286   S (mp);
5287   W (ret);
5288   return ret;
5289 }
5290
5291 static int
5292 api_want_interface_events (vat_main_t * vam)
5293 {
5294   unformat_input_t *i = vam->input;
5295   vl_api_want_interface_events_t *mp;
5296   int enable = -1;
5297   int ret;
5298
5299   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5300     {
5301       if (unformat (i, "enable"))
5302         enable = 1;
5303       else if (unformat (i, "disable"))
5304         enable = 0;
5305       else
5306         break;
5307     }
5308
5309   if (enable == -1)
5310     {
5311       errmsg ("missing enable|disable");
5312       return -99;
5313     }
5314
5315   M (WANT_INTERFACE_EVENTS, mp);
5316   mp->enable_disable = enable;
5317
5318   vam->interface_event_display = enable;
5319
5320   S (mp);
5321   W (ret);
5322   return ret;
5323 }
5324
5325
5326 /* Note: non-static, called once to set up the initial intfc table */
5327 int
5328 api_sw_interface_dump (vat_main_t * vam)
5329 {
5330   vl_api_sw_interface_dump_t *mp;
5331   vl_api_control_ping_t *mp_ping;
5332   hash_pair_t *p;
5333   name_sort_t *nses = 0, *ns;
5334   sw_interface_subif_t *sub = NULL;
5335   int ret;
5336
5337   /* Toss the old name table */
5338   /* *INDENT-OFF* */
5339   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5340   ({
5341     vec_add2 (nses, ns, 1);
5342     ns->name = (u8 *)(p->key);
5343     ns->value = (u32) p->value[0];
5344   }));
5345   /* *INDENT-ON* */
5346
5347   hash_free (vam->sw_if_index_by_interface_name);
5348
5349   vec_foreach (ns, nses) vec_free (ns->name);
5350
5351   vec_free (nses);
5352
5353   vec_foreach (sub, vam->sw_if_subif_table)
5354   {
5355     vec_free (sub->interface_name);
5356   }
5357   vec_free (vam->sw_if_subif_table);
5358
5359   /* recreate the interface name hash table */
5360   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
5361
5362   /* Get list of ethernets */
5363   M (SW_INTERFACE_DUMP, mp);
5364   mp->name_filter_valid = 1;
5365   strncpy ((char *) mp->name_filter, "Ether", sizeof (mp->name_filter) - 1);
5366   S (mp);
5367
5368   /* and local / loopback interfaces */
5369   M (SW_INTERFACE_DUMP, mp);
5370   mp->name_filter_valid = 1;
5371   strncpy ((char *) mp->name_filter, "lo", sizeof (mp->name_filter) - 1);
5372   S (mp);
5373
5374   /* and packet-generator interfaces */
5375   M (SW_INTERFACE_DUMP, mp);
5376   mp->name_filter_valid = 1;
5377   strncpy ((char *) mp->name_filter, "pg", sizeof (mp->name_filter) - 1);
5378   S (mp);
5379
5380   /* and vxlan-gpe tunnel interfaces */
5381   M (SW_INTERFACE_DUMP, mp);
5382   mp->name_filter_valid = 1;
5383   strncpy ((char *) mp->name_filter, "vxlan_gpe",
5384            sizeof (mp->name_filter) - 1);
5385   S (mp);
5386
5387   /* and vxlan tunnel interfaces */
5388   M (SW_INTERFACE_DUMP, mp);
5389   mp->name_filter_valid = 1;
5390   strncpy ((char *) mp->name_filter, "vxlan", sizeof (mp->name_filter) - 1);
5391   S (mp);
5392
5393   /* and host (af_packet) interfaces */
5394   M (SW_INTERFACE_DUMP, mp);
5395   mp->name_filter_valid = 1;
5396   strncpy ((char *) mp->name_filter, "host", sizeof (mp->name_filter) - 1);
5397   S (mp);
5398
5399   /* and l2tpv3 tunnel interfaces */
5400   M (SW_INTERFACE_DUMP, mp);
5401   mp->name_filter_valid = 1;
5402   strncpy ((char *) mp->name_filter, "l2tpv3_tunnel",
5403            sizeof (mp->name_filter) - 1);
5404   S (mp);
5405
5406   /* and GRE tunnel interfaces */
5407   M (SW_INTERFACE_DUMP, mp);
5408   mp->name_filter_valid = 1;
5409   strncpy ((char *) mp->name_filter, "gre", sizeof (mp->name_filter) - 1);
5410   S (mp);
5411
5412   /* and LISP-GPE interfaces */
5413   M (SW_INTERFACE_DUMP, mp);
5414   mp->name_filter_valid = 1;
5415   strncpy ((char *) mp->name_filter, "lisp_gpe",
5416            sizeof (mp->name_filter) - 1);
5417   S (mp);
5418
5419   /* and IPSEC tunnel interfaces */
5420   M (SW_INTERFACE_DUMP, mp);
5421   mp->name_filter_valid = 1;
5422   strncpy ((char *) mp->name_filter, "ipsec", sizeof (mp->name_filter) - 1);
5423   S (mp);
5424
5425   /* Use a control ping for synchronization */
5426   M (CONTROL_PING, mp_ping);
5427   S (mp_ping);
5428
5429   W (ret);
5430   return ret;
5431 }
5432
5433 static int
5434 api_sw_interface_set_flags (vat_main_t * vam)
5435 {
5436   unformat_input_t *i = vam->input;
5437   vl_api_sw_interface_set_flags_t *mp;
5438   u32 sw_if_index;
5439   u8 sw_if_index_set = 0;
5440   u8 admin_up = 0, link_up = 0;
5441   int ret;
5442
5443   /* Parse args required to build the message */
5444   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5445     {
5446       if (unformat (i, "admin-up"))
5447         admin_up = 1;
5448       else if (unformat (i, "admin-down"))
5449         admin_up = 0;
5450       else if (unformat (i, "link-up"))
5451         link_up = 1;
5452       else if (unformat (i, "link-down"))
5453         link_up = 0;
5454       else
5455         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5456         sw_if_index_set = 1;
5457       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5458         sw_if_index_set = 1;
5459       else
5460         break;
5461     }
5462
5463   if (sw_if_index_set == 0)
5464     {
5465       errmsg ("missing interface name or sw_if_index");
5466       return -99;
5467     }
5468
5469   /* Construct the API message */
5470   M (SW_INTERFACE_SET_FLAGS, mp);
5471   mp->sw_if_index = ntohl (sw_if_index);
5472   mp->admin_up_down = admin_up;
5473   mp->link_up_down = link_up;
5474
5475   /* send it... */
5476   S (mp);
5477
5478   /* Wait for a reply, return the good/bad news... */
5479   W (ret);
5480   return ret;
5481 }
5482
5483 static int
5484 api_sw_interface_clear_stats (vat_main_t * vam)
5485 {
5486   unformat_input_t *i = vam->input;
5487   vl_api_sw_interface_clear_stats_t *mp;
5488   u32 sw_if_index;
5489   u8 sw_if_index_set = 0;
5490   int ret;
5491
5492   /* Parse args required to build the message */
5493   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5494     {
5495       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5496         sw_if_index_set = 1;
5497       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5498         sw_if_index_set = 1;
5499       else
5500         break;
5501     }
5502
5503   /* Construct the API message */
5504   M (SW_INTERFACE_CLEAR_STATS, mp);
5505
5506   if (sw_if_index_set == 1)
5507     mp->sw_if_index = ntohl (sw_if_index);
5508   else
5509     mp->sw_if_index = ~0;
5510
5511   /* send it... */
5512   S (mp);
5513
5514   /* Wait for a reply, return the good/bad news... */
5515   W (ret);
5516   return ret;
5517 }
5518
5519 static int
5520 api_sw_interface_add_del_address (vat_main_t * vam)
5521 {
5522   unformat_input_t *i = vam->input;
5523   vl_api_sw_interface_add_del_address_t *mp;
5524   u32 sw_if_index;
5525   u8 sw_if_index_set = 0;
5526   u8 is_add = 1, del_all = 0;
5527   u32 address_length = 0;
5528   u8 v4_address_set = 0;
5529   u8 v6_address_set = 0;
5530   ip4_address_t v4address;
5531   ip6_address_t v6address;
5532   int ret;
5533
5534   /* Parse args required to build the message */
5535   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5536     {
5537       if (unformat (i, "del-all"))
5538         del_all = 1;
5539       else if (unformat (i, "del"))
5540         is_add = 0;
5541       else
5542         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5543         sw_if_index_set = 1;
5544       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5545         sw_if_index_set = 1;
5546       else if (unformat (i, "%U/%d",
5547                          unformat_ip4_address, &v4address, &address_length))
5548         v4_address_set = 1;
5549       else if (unformat (i, "%U/%d",
5550                          unformat_ip6_address, &v6address, &address_length))
5551         v6_address_set = 1;
5552       else
5553         break;
5554     }
5555
5556   if (sw_if_index_set == 0)
5557     {
5558       errmsg ("missing interface name or sw_if_index");
5559       return -99;
5560     }
5561   if (v4_address_set && v6_address_set)
5562     {
5563       errmsg ("both v4 and v6 addresses set");
5564       return -99;
5565     }
5566   if (!v4_address_set && !v6_address_set && !del_all)
5567     {
5568       errmsg ("no addresses set");
5569       return -99;
5570     }
5571
5572   /* Construct the API message */
5573   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
5574
5575   mp->sw_if_index = ntohl (sw_if_index);
5576   mp->is_add = is_add;
5577   mp->del_all = del_all;
5578   if (v6_address_set)
5579     {
5580       mp->is_ipv6 = 1;
5581       clib_memcpy (mp->address, &v6address, sizeof (v6address));
5582     }
5583   else
5584     {
5585       clib_memcpy (mp->address, &v4address, sizeof (v4address));
5586     }
5587   mp->address_length = address_length;
5588
5589   /* send it... */
5590   S (mp);
5591
5592   /* Wait for a reply, return good/bad news  */
5593   W (ret);
5594   return ret;
5595 }
5596
5597 static int
5598 api_sw_interface_set_mpls_enable (vat_main_t * vam)
5599 {
5600   unformat_input_t *i = vam->input;
5601   vl_api_sw_interface_set_mpls_enable_t *mp;
5602   u32 sw_if_index;
5603   u8 sw_if_index_set = 0;
5604   u8 enable = 1;
5605   int ret;
5606
5607   /* Parse args required to build the message */
5608   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5609     {
5610       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5611         sw_if_index_set = 1;
5612       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5613         sw_if_index_set = 1;
5614       else if (unformat (i, "disable"))
5615         enable = 0;
5616       else if (unformat (i, "dis"))
5617         enable = 0;
5618       else
5619         break;
5620     }
5621
5622   if (sw_if_index_set == 0)
5623     {
5624       errmsg ("missing interface name or sw_if_index");
5625       return -99;
5626     }
5627
5628   /* Construct the API message */
5629   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
5630
5631   mp->sw_if_index = ntohl (sw_if_index);
5632   mp->enable = enable;
5633
5634   /* send it... */
5635   S (mp);
5636
5637   /* Wait for a reply... */
5638   W (ret);
5639   return ret;
5640 }
5641
5642 static int
5643 api_sw_interface_set_table (vat_main_t * vam)
5644 {
5645   unformat_input_t *i = vam->input;
5646   vl_api_sw_interface_set_table_t *mp;
5647   u32 sw_if_index, vrf_id = 0;
5648   u8 sw_if_index_set = 0;
5649   u8 is_ipv6 = 0;
5650   int ret;
5651
5652   /* Parse args required to build the message */
5653   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5654     {
5655       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5656         sw_if_index_set = 1;
5657       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5658         sw_if_index_set = 1;
5659       else if (unformat (i, "vrf %d", &vrf_id))
5660         ;
5661       else if (unformat (i, "ipv6"))
5662         is_ipv6 = 1;
5663       else
5664         break;
5665     }
5666
5667   if (sw_if_index_set == 0)
5668     {
5669       errmsg ("missing interface name or sw_if_index");
5670       return -99;
5671     }
5672
5673   /* Construct the API message */
5674   M (SW_INTERFACE_SET_TABLE, mp);
5675
5676   mp->sw_if_index = ntohl (sw_if_index);
5677   mp->is_ipv6 = is_ipv6;
5678   mp->vrf_id = ntohl (vrf_id);
5679
5680   /* send it... */
5681   S (mp);
5682
5683   /* Wait for a reply... */
5684   W (ret);
5685   return ret;
5686 }
5687
5688 static void vl_api_sw_interface_get_table_reply_t_handler
5689   (vl_api_sw_interface_get_table_reply_t * mp)
5690 {
5691   vat_main_t *vam = &vat_main;
5692
5693   print (vam->ofp, "%d", ntohl (mp->vrf_id));
5694
5695   vam->retval = ntohl (mp->retval);
5696   vam->result_ready = 1;
5697
5698 }
5699
5700 static void vl_api_sw_interface_get_table_reply_t_handler_json
5701   (vl_api_sw_interface_get_table_reply_t * mp)
5702 {
5703   vat_main_t *vam = &vat_main;
5704   vat_json_node_t node;
5705
5706   vat_json_init_object (&node);
5707   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
5708   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
5709
5710   vat_json_print (vam->ofp, &node);
5711   vat_json_free (&node);
5712
5713   vam->retval = ntohl (mp->retval);
5714   vam->result_ready = 1;
5715 }
5716
5717 static int
5718 api_sw_interface_get_table (vat_main_t * vam)
5719 {
5720   unformat_input_t *i = vam->input;
5721   vl_api_sw_interface_get_table_t *mp;
5722   u32 sw_if_index;
5723   u8 sw_if_index_set = 0;
5724   u8 is_ipv6 = 0;
5725   int ret;
5726
5727   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5728     {
5729       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5730         sw_if_index_set = 1;
5731       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5732         sw_if_index_set = 1;
5733       else if (unformat (i, "ipv6"))
5734         is_ipv6 = 1;
5735       else
5736         break;
5737     }
5738
5739   if (sw_if_index_set == 0)
5740     {
5741       errmsg ("missing interface name or sw_if_index");
5742       return -99;
5743     }
5744
5745   M (SW_INTERFACE_GET_TABLE, mp);
5746   mp->sw_if_index = htonl (sw_if_index);
5747   mp->is_ipv6 = is_ipv6;
5748
5749   S (mp);
5750   W (ret);
5751   return ret;
5752 }
5753
5754 static int
5755 api_sw_interface_set_vpath (vat_main_t * vam)
5756 {
5757   unformat_input_t *i = vam->input;
5758   vl_api_sw_interface_set_vpath_t *mp;
5759   u32 sw_if_index = 0;
5760   u8 sw_if_index_set = 0;
5761   u8 is_enable = 0;
5762   int ret;
5763
5764   /* Parse args required to build the message */
5765   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5766     {
5767       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5768         sw_if_index_set = 1;
5769       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5770         sw_if_index_set = 1;
5771       else if (unformat (i, "enable"))
5772         is_enable = 1;
5773       else if (unformat (i, "disable"))
5774         is_enable = 0;
5775       else
5776         break;
5777     }
5778
5779   if (sw_if_index_set == 0)
5780     {
5781       errmsg ("missing interface name or sw_if_index");
5782       return -99;
5783     }
5784
5785   /* Construct the API message */
5786   M (SW_INTERFACE_SET_VPATH, mp);
5787
5788   mp->sw_if_index = ntohl (sw_if_index);
5789   mp->enable = is_enable;
5790
5791   /* send it... */
5792   S (mp);
5793
5794   /* Wait for a reply... */
5795   W (ret);
5796   return ret;
5797 }
5798
5799 static int
5800 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
5801 {
5802   unformat_input_t *i = vam->input;
5803   vl_api_sw_interface_set_vxlan_bypass_t *mp;
5804   u32 sw_if_index = 0;
5805   u8 sw_if_index_set = 0;
5806   u8 is_enable = 1;
5807   u8 is_ipv6 = 0;
5808   int ret;
5809
5810   /* Parse args required to build the message */
5811   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5812     {
5813       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5814         sw_if_index_set = 1;
5815       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5816         sw_if_index_set = 1;
5817       else if (unformat (i, "enable"))
5818         is_enable = 1;
5819       else if (unformat (i, "disable"))
5820         is_enable = 0;
5821       else if (unformat (i, "ip4"))
5822         is_ipv6 = 0;
5823       else if (unformat (i, "ip6"))
5824         is_ipv6 = 1;
5825       else
5826         break;
5827     }
5828
5829   if (sw_if_index_set == 0)
5830     {
5831       errmsg ("missing interface name or sw_if_index");
5832       return -99;
5833     }
5834
5835   /* Construct the API message */
5836   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
5837
5838   mp->sw_if_index = ntohl (sw_if_index);
5839   mp->enable = is_enable;
5840   mp->is_ipv6 = is_ipv6;
5841
5842   /* send it... */
5843   S (mp);
5844
5845   /* Wait for a reply... */
5846   W (ret);
5847   return ret;
5848 }
5849
5850 static int
5851 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
5852 {
5853   unformat_input_t *i = vam->input;
5854   vl_api_sw_interface_set_l2_xconnect_t *mp;
5855   u32 rx_sw_if_index;
5856   u8 rx_sw_if_index_set = 0;
5857   u32 tx_sw_if_index;
5858   u8 tx_sw_if_index_set = 0;
5859   u8 enable = 1;
5860   int ret;
5861
5862   /* Parse args required to build the message */
5863   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5864     {
5865       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
5866         rx_sw_if_index_set = 1;
5867       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
5868         tx_sw_if_index_set = 1;
5869       else if (unformat (i, "rx"))
5870         {
5871           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5872             {
5873               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
5874                             &rx_sw_if_index))
5875                 rx_sw_if_index_set = 1;
5876             }
5877           else
5878             break;
5879         }
5880       else if (unformat (i, "tx"))
5881         {
5882           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5883             {
5884               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
5885                             &tx_sw_if_index))
5886                 tx_sw_if_index_set = 1;
5887             }
5888           else
5889             break;
5890         }
5891       else if (unformat (i, "enable"))
5892         enable = 1;
5893       else if (unformat (i, "disable"))
5894         enable = 0;
5895       else
5896         break;
5897     }
5898
5899   if (rx_sw_if_index_set == 0)
5900     {
5901       errmsg ("missing rx interface name or rx_sw_if_index");
5902       return -99;
5903     }
5904
5905   if (enable && (tx_sw_if_index_set == 0))
5906     {
5907       errmsg ("missing tx interface name or tx_sw_if_index");
5908       return -99;
5909     }
5910
5911   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
5912
5913   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
5914   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
5915   mp->enable = enable;
5916
5917   S (mp);
5918   W (ret);
5919   return ret;
5920 }
5921
5922 static int
5923 api_sw_interface_set_l2_bridge (vat_main_t * vam)
5924 {
5925   unformat_input_t *i = vam->input;
5926   vl_api_sw_interface_set_l2_bridge_t *mp;
5927   u32 rx_sw_if_index;
5928   u8 rx_sw_if_index_set = 0;
5929   u32 bd_id;
5930   u8 bd_id_set = 0;
5931   u8 bvi = 0;
5932   u32 shg = 0;
5933   u8 enable = 1;
5934   int ret;
5935
5936   /* Parse args required to build the message */
5937   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5938     {
5939       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
5940         rx_sw_if_index_set = 1;
5941       else if (unformat (i, "bd_id %d", &bd_id))
5942         bd_id_set = 1;
5943       else
5944         if (unformat
5945             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
5946         rx_sw_if_index_set = 1;
5947       else if (unformat (i, "shg %d", &shg))
5948         ;
5949       else if (unformat (i, "bvi"))
5950         bvi = 1;
5951       else if (unformat (i, "enable"))
5952         enable = 1;
5953       else if (unformat (i, "disable"))
5954         enable = 0;
5955       else
5956         break;
5957     }
5958
5959   if (rx_sw_if_index_set == 0)
5960     {
5961       errmsg ("missing rx interface name or sw_if_index");
5962       return -99;
5963     }
5964
5965   if (enable && (bd_id_set == 0))
5966     {
5967       errmsg ("missing bridge domain");
5968       return -99;
5969     }
5970
5971   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
5972
5973   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
5974   mp->bd_id = ntohl (bd_id);
5975   mp->shg = (u8) shg;
5976   mp->bvi = bvi;
5977   mp->enable = enable;
5978
5979   S (mp);
5980   W (ret);
5981   return ret;
5982 }
5983
5984 static int
5985 api_bridge_domain_dump (vat_main_t * vam)
5986 {
5987   unformat_input_t *i = vam->input;
5988   vl_api_bridge_domain_dump_t *mp;
5989   vl_api_control_ping_t *mp_ping;
5990   u32 bd_id = ~0;
5991   int ret;
5992
5993   /* Parse args required to build the message */
5994   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5995     {
5996       if (unformat (i, "bd_id %d", &bd_id))
5997         ;
5998       else
5999         break;
6000     }
6001
6002   M (BRIDGE_DOMAIN_DUMP, mp);
6003   mp->bd_id = ntohl (bd_id);
6004   S (mp);
6005
6006   /* Use a control ping for synchronization */
6007   M (CONTROL_PING, mp_ping);
6008   S (mp_ping);
6009
6010   W (ret);
6011   return ret;
6012 }
6013
6014 static int
6015 api_bridge_domain_add_del (vat_main_t * vam)
6016 {
6017   unformat_input_t *i = vam->input;
6018   vl_api_bridge_domain_add_del_t *mp;
6019   u32 bd_id = ~0;
6020   u8 is_add = 1;
6021   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
6022   u32 mac_age = 0;
6023   int ret;
6024
6025   /* Parse args required to build the message */
6026   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6027     {
6028       if (unformat (i, "bd_id %d", &bd_id))
6029         ;
6030       else if (unformat (i, "flood %d", &flood))
6031         ;
6032       else if (unformat (i, "uu-flood %d", &uu_flood))
6033         ;
6034       else if (unformat (i, "forward %d", &forward))
6035         ;
6036       else if (unformat (i, "learn %d", &learn))
6037         ;
6038       else if (unformat (i, "arp-term %d", &arp_term))
6039         ;
6040       else if (unformat (i, "mac-age %d", &mac_age))
6041         ;
6042       else if (unformat (i, "del"))
6043         {
6044           is_add = 0;
6045           flood = uu_flood = forward = learn = 0;
6046         }
6047       else
6048         break;
6049     }
6050
6051   if (bd_id == ~0)
6052     {
6053       errmsg ("missing bridge domain");
6054       return -99;
6055     }
6056
6057   if (mac_age > 255)
6058     {
6059       errmsg ("mac age must be less than 256 ");
6060       return -99;
6061     }
6062
6063   M (BRIDGE_DOMAIN_ADD_DEL, mp);
6064
6065   mp->bd_id = ntohl (bd_id);
6066   mp->flood = flood;
6067   mp->uu_flood = uu_flood;
6068   mp->forward = forward;
6069   mp->learn = learn;
6070   mp->arp_term = arp_term;
6071   mp->is_add = is_add;
6072   mp->mac_age = (u8) mac_age;
6073
6074   S (mp);
6075   W (ret);
6076   return ret;
6077 }
6078
6079 static int
6080 api_l2fib_flush_bd (vat_main_t * vam)
6081 {
6082   unformat_input_t *i = vam->input;
6083   vl_api_l2fib_flush_bd_t *mp;
6084   u32 bd_id = ~0;
6085   int ret;
6086
6087   /* Parse args required to build the message */
6088   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6089     {
6090       if (unformat (i, "bd_id %d", &bd_id));
6091       else
6092         break;
6093     }
6094
6095   if (bd_id == ~0)
6096     {
6097       errmsg ("missing bridge domain");
6098       return -99;
6099     }
6100
6101   M (L2FIB_FLUSH_BD, mp);
6102
6103   mp->bd_id = htonl (bd_id);
6104
6105   S (mp);
6106   W (ret);
6107   return ret;
6108 }
6109
6110 static int
6111 api_l2fib_flush_int (vat_main_t * vam)
6112 {
6113   unformat_input_t *i = vam->input;
6114   vl_api_l2fib_flush_int_t *mp;
6115   u32 sw_if_index = ~0;
6116   int ret;
6117
6118   /* Parse args required to build the message */
6119   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6120     {
6121       if (unformat (i, "sw_if_index %d", &sw_if_index));
6122       else
6123         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
6124       else
6125         break;
6126     }
6127
6128   if (sw_if_index == ~0)
6129     {
6130       errmsg ("missing interface name or sw_if_index");
6131       return -99;
6132     }
6133
6134   M (L2FIB_FLUSH_INT, mp);
6135
6136   mp->sw_if_index = ntohl (sw_if_index);
6137
6138   S (mp);
6139   W (ret);
6140   return ret;
6141 }
6142
6143 static int
6144 api_l2fib_add_del (vat_main_t * vam)
6145 {
6146   unformat_input_t *i = vam->input;
6147   vl_api_l2fib_add_del_t *mp;
6148   f64 timeout;
6149   u64 mac = 0;
6150   u8 mac_set = 0;
6151   u32 bd_id;
6152   u8 bd_id_set = 0;
6153   u32 sw_if_index = ~0;
6154   u8 sw_if_index_set = 0;
6155   u8 is_add = 1;
6156   u8 static_mac = 0;
6157   u8 filter_mac = 0;
6158   u8 bvi_mac = 0;
6159   int count = 1;
6160   f64 before = 0;
6161   int j;
6162
6163   /* Parse args required to build the message */
6164   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6165     {
6166       if (unformat (i, "mac %U", unformat_ethernet_address, &mac))
6167         mac_set = 1;
6168       else if (unformat (i, "bd_id %d", &bd_id))
6169         bd_id_set = 1;
6170       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6171         sw_if_index_set = 1;
6172       else if (unformat (i, "sw_if"))
6173         {
6174           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6175             {
6176               if (unformat
6177                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6178                 sw_if_index_set = 1;
6179             }
6180           else
6181             break;
6182         }
6183       else if (unformat (i, "static"))
6184         static_mac = 1;
6185       else if (unformat (i, "filter"))
6186         {
6187           filter_mac = 1;
6188           static_mac = 1;
6189         }
6190       else if (unformat (i, "bvi"))
6191         {
6192           bvi_mac = 1;
6193           static_mac = 1;
6194         }
6195       else if (unformat (i, "del"))
6196         is_add = 0;
6197       else if (unformat (i, "count %d", &count))
6198         ;
6199       else
6200         break;
6201     }
6202
6203   if (mac_set == 0)
6204     {
6205       errmsg ("missing mac address");
6206       return -99;
6207     }
6208
6209   if (bd_id_set == 0)
6210     {
6211       errmsg ("missing bridge domain");
6212       return -99;
6213     }
6214
6215   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
6216     {
6217       errmsg ("missing interface name or sw_if_index");
6218       return -99;
6219     }
6220
6221   if (count > 1)
6222     {
6223       /* Turn on async mode */
6224       vam->async_mode = 1;
6225       vam->async_errors = 0;
6226       before = vat_time_now (vam);
6227     }
6228
6229   for (j = 0; j < count; j++)
6230     {
6231       M (L2FIB_ADD_DEL, mp);
6232
6233       mp->mac = mac;
6234       mp->bd_id = ntohl (bd_id);
6235       mp->is_add = is_add;
6236
6237       if (is_add)
6238         {
6239           mp->sw_if_index = ntohl (sw_if_index);
6240           mp->static_mac = static_mac;
6241           mp->filter_mac = filter_mac;
6242           mp->bvi_mac = bvi_mac;
6243         }
6244       increment_mac_address (&mac);
6245       /* send it... */
6246       S (mp);
6247     }
6248
6249   if (count > 1)
6250     {
6251       vl_api_control_ping_t *mp_ping;
6252       f64 after;
6253
6254       /* Shut off async mode */
6255       vam->async_mode = 0;
6256
6257       M (CONTROL_PING, mp_ping);
6258       S (mp_ping);
6259
6260       timeout = vat_time_now (vam) + 1.0;
6261       while (vat_time_now (vam) < timeout)
6262         if (vam->result_ready == 1)
6263           goto out;
6264       vam->retval = -99;
6265
6266     out:
6267       if (vam->retval == -99)
6268         errmsg ("timeout");
6269
6270       if (vam->async_errors > 0)
6271         {
6272           errmsg ("%d asynchronous errors", vam->async_errors);
6273           vam->retval = -98;
6274         }
6275       vam->async_errors = 0;
6276       after = vat_time_now (vam);
6277
6278       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6279              count, after - before, count / (after - before));
6280     }
6281   else
6282     {
6283       int ret;
6284
6285       /* Wait for a reply... */
6286       W (ret);
6287       return ret;
6288     }
6289   /* Return the good/bad news */
6290   return (vam->retval);
6291 }
6292
6293 static int
6294 api_bridge_domain_set_mac_age (vat_main_t * vam)
6295 {
6296   unformat_input_t *i = vam->input;
6297   vl_api_bridge_domain_set_mac_age_t *mp;
6298   u32 bd_id = ~0;
6299   u32 mac_age = 0;
6300   int ret;
6301
6302   /* Parse args required to build the message */
6303   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6304     {
6305       if (unformat (i, "bd_id %d", &bd_id));
6306       else if (unformat (i, "mac-age %d", &mac_age));
6307       else
6308         break;
6309     }
6310
6311   if (bd_id == ~0)
6312     {
6313       errmsg ("missing bridge domain");
6314       return -99;
6315     }
6316
6317   if (mac_age > 255)
6318     {
6319       errmsg ("mac age must be less than 256 ");
6320       return -99;
6321     }
6322
6323   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
6324
6325   mp->bd_id = htonl (bd_id);
6326   mp->mac_age = (u8) mac_age;
6327
6328   S (mp);
6329   W (ret);
6330   return ret;
6331 }
6332
6333 static int
6334 api_l2_flags (vat_main_t * vam)
6335 {
6336   unformat_input_t *i = vam->input;
6337   vl_api_l2_flags_t *mp;
6338   u32 sw_if_index;
6339   u32 feature_bitmap = 0;
6340   u8 sw_if_index_set = 0;
6341   int ret;
6342
6343   /* Parse args required to build the message */
6344   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6345     {
6346       if (unformat (i, "sw_if_index %d", &sw_if_index))
6347         sw_if_index_set = 1;
6348       else if (unformat (i, "sw_if"))
6349         {
6350           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6351             {
6352               if (unformat
6353                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6354                 sw_if_index_set = 1;
6355             }
6356           else
6357             break;
6358         }
6359       else if (unformat (i, "learn"))
6360         feature_bitmap |= L2INPUT_FEAT_LEARN;
6361       else if (unformat (i, "forward"))
6362         feature_bitmap |= L2INPUT_FEAT_FWD;
6363       else if (unformat (i, "flood"))
6364         feature_bitmap |= L2INPUT_FEAT_FLOOD;
6365       else if (unformat (i, "uu-flood"))
6366         feature_bitmap |= L2INPUT_FEAT_UU_FLOOD;
6367       else
6368         break;
6369     }
6370
6371   if (sw_if_index_set == 0)
6372     {
6373       errmsg ("missing interface name or sw_if_index");
6374       return -99;
6375     }
6376
6377   M (L2_FLAGS, mp);
6378
6379   mp->sw_if_index = ntohl (sw_if_index);
6380   mp->feature_bitmap = ntohl (feature_bitmap);
6381
6382   S (mp);
6383   W (ret);
6384   return ret;
6385 }
6386
6387 static int
6388 api_bridge_flags (vat_main_t * vam)
6389 {
6390   unformat_input_t *i = vam->input;
6391   vl_api_bridge_flags_t *mp;
6392   u32 bd_id;
6393   u8 bd_id_set = 0;
6394   u8 is_set = 1;
6395   u32 flags = 0;
6396   int ret;
6397
6398   /* Parse args required to build the message */
6399   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6400     {
6401       if (unformat (i, "bd_id %d", &bd_id))
6402         bd_id_set = 1;
6403       else if (unformat (i, "learn"))
6404         flags |= L2_LEARN;
6405       else if (unformat (i, "forward"))
6406         flags |= L2_FWD;
6407       else if (unformat (i, "flood"))
6408         flags |= L2_FLOOD;
6409       else if (unformat (i, "uu-flood"))
6410         flags |= L2_UU_FLOOD;
6411       else if (unformat (i, "arp-term"))
6412         flags |= L2_ARP_TERM;
6413       else if (unformat (i, "off"))
6414         is_set = 0;
6415       else if (unformat (i, "disable"))
6416         is_set = 0;
6417       else
6418         break;
6419     }
6420
6421   if (bd_id_set == 0)
6422     {
6423       errmsg ("missing bridge domain");
6424       return -99;
6425     }
6426
6427   M (BRIDGE_FLAGS, mp);
6428
6429   mp->bd_id = ntohl (bd_id);
6430   mp->feature_bitmap = ntohl (flags);
6431   mp->is_set = is_set;
6432
6433   S (mp);
6434   W (ret);
6435   return ret;
6436 }
6437
6438 static int
6439 api_bd_ip_mac_add_del (vat_main_t * vam)
6440 {
6441   unformat_input_t *i = vam->input;
6442   vl_api_bd_ip_mac_add_del_t *mp;
6443   u32 bd_id;
6444   u8 is_ipv6 = 0;
6445   u8 is_add = 1;
6446   u8 bd_id_set = 0;
6447   u8 ip_set = 0;
6448   u8 mac_set = 0;
6449   ip4_address_t v4addr;
6450   ip6_address_t v6addr;
6451   u8 macaddr[6];
6452   int ret;
6453
6454
6455   /* Parse args required to build the message */
6456   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6457     {
6458       if (unformat (i, "bd_id %d", &bd_id))
6459         {
6460           bd_id_set++;
6461         }
6462       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
6463         {
6464           ip_set++;
6465         }
6466       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
6467         {
6468           ip_set++;
6469           is_ipv6++;
6470         }
6471       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
6472         {
6473           mac_set++;
6474         }
6475       else if (unformat (i, "del"))
6476         is_add = 0;
6477       else
6478         break;
6479     }
6480
6481   if (bd_id_set == 0)
6482     {
6483       errmsg ("missing bridge domain");
6484       return -99;
6485     }
6486   else if (ip_set == 0)
6487     {
6488       errmsg ("missing IP address");
6489       return -99;
6490     }
6491   else if (mac_set == 0)
6492     {
6493       errmsg ("missing MAC address");
6494       return -99;
6495     }
6496
6497   M (BD_IP_MAC_ADD_DEL, mp);
6498
6499   mp->bd_id = ntohl (bd_id);
6500   mp->is_ipv6 = is_ipv6;
6501   mp->is_add = is_add;
6502   if (is_ipv6)
6503     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
6504   else
6505     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
6506   clib_memcpy (mp->mac_address, macaddr, 6);
6507   S (mp);
6508   W (ret);
6509   return ret;
6510 }
6511
6512 static int
6513 api_tap_connect (vat_main_t * vam)
6514 {
6515   unformat_input_t *i = vam->input;
6516   vl_api_tap_connect_t *mp;
6517   u8 mac_address[6];
6518   u8 random_mac = 1;
6519   u8 name_set = 0;
6520   u8 *tap_name;
6521   u8 *tag = 0;
6522   ip4_address_t ip4_address;
6523   u32 ip4_mask_width;
6524   int ip4_address_set = 0;
6525   ip6_address_t ip6_address;
6526   u32 ip6_mask_width;
6527   int ip6_address_set = 0;
6528   int ret;
6529
6530   memset (mac_address, 0, sizeof (mac_address));
6531
6532   /* Parse args required to build the message */
6533   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6534     {
6535       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6536         {
6537           random_mac = 0;
6538         }
6539       else if (unformat (i, "random-mac"))
6540         random_mac = 1;
6541       else if (unformat (i, "tapname %s", &tap_name))
6542         name_set = 1;
6543       else if (unformat (i, "tag %s", &tag))
6544         ;
6545       else if (unformat (i, "address %U/%d",
6546                          unformat_ip4_address, &ip4_address, &ip4_mask_width))
6547         ip4_address_set = 1;
6548       else if (unformat (i, "address %U/%d",
6549                          unformat_ip6_address, &ip6_address, &ip6_mask_width))
6550         ip6_address_set = 1;
6551       else
6552         break;
6553     }
6554
6555   if (name_set == 0)
6556     {
6557       errmsg ("missing tap name");
6558       return -99;
6559     }
6560   if (vec_len (tap_name) > 63)
6561     {
6562       errmsg ("tap name too long");
6563       return -99;
6564     }
6565   vec_add1 (tap_name, 0);
6566
6567   if (vec_len (tag) > 63)
6568     {
6569       errmsg ("tag too long");
6570       return -99;
6571     }
6572
6573   /* Construct the API message */
6574   M (TAP_CONNECT, mp);
6575
6576   mp->use_random_mac = random_mac;
6577   clib_memcpy (mp->mac_address, mac_address, 6);
6578   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
6579   if (tag)
6580     clib_memcpy (mp->tag, tag, vec_len (tag));
6581
6582   if (ip4_address_set)
6583     {
6584       mp->ip4_address_set = 1;
6585       clib_memcpy (mp->ip4_address, &ip4_address, sizeof (mp->ip4_address));
6586       mp->ip4_mask_width = ip4_mask_width;
6587     }
6588   if (ip6_address_set)
6589     {
6590       mp->ip6_address_set = 1;
6591       clib_memcpy (mp->ip6_address, &ip6_address, sizeof (mp->ip6_address));
6592       mp->ip6_mask_width = ip6_mask_width;
6593     }
6594
6595   vec_free (tap_name);
6596   vec_free (tag);
6597
6598   /* send it... */
6599   S (mp);
6600
6601   /* Wait for a reply... */
6602   W (ret);
6603   return ret;
6604 }
6605
6606 static int
6607 api_tap_modify (vat_main_t * vam)
6608 {
6609   unformat_input_t *i = vam->input;
6610   vl_api_tap_modify_t *mp;
6611   u8 mac_address[6];
6612   u8 random_mac = 1;
6613   u8 name_set = 0;
6614   u8 *tap_name;
6615   u32 sw_if_index = ~0;
6616   u8 sw_if_index_set = 0;
6617   int ret;
6618
6619   memset (mac_address, 0, sizeof (mac_address));
6620
6621   /* Parse args required to build the message */
6622   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6623     {
6624       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6625         sw_if_index_set = 1;
6626       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6627         sw_if_index_set = 1;
6628       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6629         {
6630           random_mac = 0;
6631         }
6632       else if (unformat (i, "random-mac"))
6633         random_mac = 1;
6634       else if (unformat (i, "tapname %s", &tap_name))
6635         name_set = 1;
6636       else
6637         break;
6638     }
6639
6640   if (sw_if_index_set == 0)
6641     {
6642       errmsg ("missing vpp interface name");
6643       return -99;
6644     }
6645   if (name_set == 0)
6646     {
6647       errmsg ("missing tap name");
6648       return -99;
6649     }
6650   if (vec_len (tap_name) > 63)
6651     {
6652       errmsg ("tap name too long");
6653     }
6654   vec_add1 (tap_name, 0);
6655
6656   /* Construct the API message */
6657   M (TAP_MODIFY, mp);
6658
6659   mp->use_random_mac = random_mac;
6660   mp->sw_if_index = ntohl (sw_if_index);
6661   clib_memcpy (mp->mac_address, mac_address, 6);
6662   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
6663   vec_free (tap_name);
6664
6665   /* send it... */
6666   S (mp);
6667
6668   /* Wait for a reply... */
6669   W (ret);
6670   return ret;
6671 }
6672
6673 static int
6674 api_tap_delete (vat_main_t * vam)
6675 {
6676   unformat_input_t *i = vam->input;
6677   vl_api_tap_delete_t *mp;
6678   u32 sw_if_index = ~0;
6679   u8 sw_if_index_set = 0;
6680   int ret;
6681
6682   /* Parse args required to build the message */
6683   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6684     {
6685       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6686         sw_if_index_set = 1;
6687       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6688         sw_if_index_set = 1;
6689       else
6690         break;
6691     }
6692
6693   if (sw_if_index_set == 0)
6694     {
6695       errmsg ("missing vpp interface name");
6696       return -99;
6697     }
6698
6699   /* Construct the API message */
6700   M (TAP_DELETE, mp);
6701
6702   mp->sw_if_index = ntohl (sw_if_index);
6703
6704   /* send it... */
6705   S (mp);
6706
6707   /* Wait for a reply... */
6708   W (ret);
6709   return ret;
6710 }
6711
6712 static int
6713 api_ip_add_del_route (vat_main_t * vam)
6714 {
6715   unformat_input_t *i = vam->input;
6716   vl_api_ip_add_del_route_t *mp;
6717   u32 sw_if_index = ~0, vrf_id = 0;
6718   u8 is_ipv6 = 0;
6719   u8 is_local = 0, is_drop = 0;
6720   u8 is_unreach = 0, is_prohibit = 0;
6721   u8 create_vrf_if_needed = 0;
6722   u8 is_add = 1;
6723   u32 next_hop_weight = 1;
6724   u8 not_last = 0;
6725   u8 is_multipath = 0;
6726   u8 address_set = 0;
6727   u8 address_length_set = 0;
6728   u32 next_hop_table_id = 0;
6729   u32 resolve_attempts = 0;
6730   u32 dst_address_length = 0;
6731   u8 next_hop_set = 0;
6732   ip4_address_t v4_dst_address, v4_next_hop_address;
6733   ip6_address_t v6_dst_address, v6_next_hop_address;
6734   int count = 1;
6735   int j;
6736   f64 before = 0;
6737   u32 random_add_del = 0;
6738   u32 *random_vector = 0;
6739   uword *random_hash;
6740   u32 random_seed = 0xdeaddabe;
6741   u32 classify_table_index = ~0;
6742   u8 is_classify = 0;
6743   u8 resolve_host = 0, resolve_attached = 0;
6744   mpls_label_t *next_hop_out_label_stack = NULL;
6745   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
6746   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
6747
6748   /* Parse args required to build the message */
6749   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6750     {
6751       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6752         ;
6753       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6754         ;
6755       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
6756         {
6757           address_set = 1;
6758           is_ipv6 = 0;
6759         }
6760       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
6761         {
6762           address_set = 1;
6763           is_ipv6 = 1;
6764         }
6765       else if (unformat (i, "/%d", &dst_address_length))
6766         {
6767           address_length_set = 1;
6768         }
6769
6770       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
6771                                          &v4_next_hop_address))
6772         {
6773           next_hop_set = 1;
6774         }
6775       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
6776                                          &v6_next_hop_address))
6777         {
6778           next_hop_set = 1;
6779         }
6780       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
6781         ;
6782       else if (unformat (i, "weight %d", &next_hop_weight))
6783         ;
6784       else if (unformat (i, "drop"))
6785         {
6786           is_drop = 1;
6787         }
6788       else if (unformat (i, "null-send-unreach"))
6789         {
6790           is_unreach = 1;
6791         }
6792       else if (unformat (i, "null-send-prohibit"))
6793         {
6794           is_prohibit = 1;
6795         }
6796       else if (unformat (i, "local"))
6797         {
6798           is_local = 1;
6799         }
6800       else if (unformat (i, "classify %d", &classify_table_index))
6801         {
6802           is_classify = 1;
6803         }
6804       else if (unformat (i, "del"))
6805         is_add = 0;
6806       else if (unformat (i, "add"))
6807         is_add = 1;
6808       else if (unformat (i, "not-last"))
6809         not_last = 1;
6810       else if (unformat (i, "resolve-via-host"))
6811         resolve_host = 1;
6812       else if (unformat (i, "resolve-via-attached"))
6813         resolve_attached = 1;
6814       else if (unformat (i, "multipath"))
6815         is_multipath = 1;
6816       else if (unformat (i, "vrf %d", &vrf_id))
6817         ;
6818       else if (unformat (i, "create-vrf"))
6819         create_vrf_if_needed = 1;
6820       else if (unformat (i, "count %d", &count))
6821         ;
6822       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
6823         ;
6824       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
6825         ;
6826       else if (unformat (i, "out-label %d", &next_hop_out_label))
6827         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
6828       else if (unformat (i, "via-label %d", &next_hop_via_label))
6829         ;
6830       else if (unformat (i, "random"))
6831         random_add_del = 1;
6832       else if (unformat (i, "seed %d", &random_seed))
6833         ;
6834       else
6835         {
6836           clib_warning ("parse error '%U'", format_unformat_error, i);
6837           return -99;
6838         }
6839     }
6840
6841   if (!next_hop_set && !is_drop && !is_local &&
6842       !is_classify && !is_unreach && !is_prohibit &&
6843       MPLS_LABEL_INVALID == next_hop_via_label)
6844     {
6845       errmsg
6846         ("next hop / local / drop / unreach / prohibit / classify not set");
6847       return -99;
6848     }
6849
6850   if (next_hop_set && MPLS_LABEL_INVALID != next_hop_via_label)
6851     {
6852       errmsg ("next hop and next-hop via label set");
6853       return -99;
6854     }
6855   if (address_set == 0)
6856     {
6857       errmsg ("missing addresses");
6858       return -99;
6859     }
6860
6861   if (address_length_set == 0)
6862     {
6863       errmsg ("missing address length");
6864       return -99;
6865     }
6866
6867   /* Generate a pile of unique, random routes */
6868   if (random_add_del)
6869     {
6870       u32 this_random_address;
6871       random_hash = hash_create (count, sizeof (uword));
6872
6873       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
6874       for (j = 0; j <= count; j++)
6875         {
6876           do
6877             {
6878               this_random_address = random_u32 (&random_seed);
6879               this_random_address =
6880                 clib_host_to_net_u32 (this_random_address);
6881             }
6882           while (hash_get (random_hash, this_random_address));
6883           vec_add1 (random_vector, this_random_address);
6884           hash_set (random_hash, this_random_address, 1);
6885         }
6886       hash_free (random_hash);
6887       v4_dst_address.as_u32 = random_vector[0];
6888     }
6889
6890   if (count > 1)
6891     {
6892       /* Turn on async mode */
6893       vam->async_mode = 1;
6894       vam->async_errors = 0;
6895       before = vat_time_now (vam);
6896     }
6897
6898   for (j = 0; j < count; j++)
6899     {
6900       /* Construct the API message */
6901       M2 (IP_ADD_DEL_ROUTE, mp,
6902           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
6903
6904       mp->next_hop_sw_if_index = ntohl (sw_if_index);
6905       mp->table_id = ntohl (vrf_id);
6906       mp->create_vrf_if_needed = create_vrf_if_needed;
6907
6908       mp->is_add = is_add;
6909       mp->is_drop = is_drop;
6910       mp->is_unreach = is_unreach;
6911       mp->is_prohibit = is_prohibit;
6912       mp->is_ipv6 = is_ipv6;
6913       mp->is_local = is_local;
6914       mp->is_classify = is_classify;
6915       mp->is_multipath = is_multipath;
6916       mp->is_resolve_host = resolve_host;
6917       mp->is_resolve_attached = resolve_attached;
6918       mp->not_last = not_last;
6919       mp->next_hop_weight = next_hop_weight;
6920       mp->dst_address_length = dst_address_length;
6921       mp->next_hop_table_id = ntohl (next_hop_table_id);
6922       mp->classify_table_index = ntohl (classify_table_index);
6923       mp->next_hop_via_label = ntohl (next_hop_via_label);
6924       mp->next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
6925       if (0 != mp->next_hop_n_out_labels)
6926         {
6927           memcpy (mp->next_hop_out_label_stack,
6928                   next_hop_out_label_stack,
6929                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
6930           vec_free (next_hop_out_label_stack);
6931         }
6932
6933       if (is_ipv6)
6934         {
6935           clib_memcpy (mp->dst_address, &v6_dst_address,
6936                        sizeof (v6_dst_address));
6937           if (next_hop_set)
6938             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
6939                          sizeof (v6_next_hop_address));
6940           increment_v6_address (&v6_dst_address);
6941         }
6942       else
6943         {
6944           clib_memcpy (mp->dst_address, &v4_dst_address,
6945                        sizeof (v4_dst_address));
6946           if (next_hop_set)
6947             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
6948                          sizeof (v4_next_hop_address));
6949           if (random_add_del)
6950             v4_dst_address.as_u32 = random_vector[j + 1];
6951           else
6952             increment_v4_address (&v4_dst_address);
6953         }
6954       /* send it... */
6955       S (mp);
6956       /* If we receive SIGTERM, stop now... */
6957       if (vam->do_exit)
6958         break;
6959     }
6960
6961   /* When testing multiple add/del ops, use a control-ping to sync */
6962   if (count > 1)
6963     {
6964       vl_api_control_ping_t *mp_ping;
6965       f64 after;
6966       f64 timeout;
6967
6968       /* Shut off async mode */
6969       vam->async_mode = 0;
6970
6971       M (CONTROL_PING, mp_ping);
6972       S (mp_ping);
6973
6974       timeout = vat_time_now (vam) + 1.0;
6975       while (vat_time_now (vam) < timeout)
6976         if (vam->result_ready == 1)
6977           goto out;
6978       vam->retval = -99;
6979
6980     out:
6981       if (vam->retval == -99)
6982         errmsg ("timeout");
6983
6984       if (vam->async_errors > 0)
6985         {
6986           errmsg ("%d asynchronous errors", vam->async_errors);
6987           vam->retval = -98;
6988         }
6989       vam->async_errors = 0;
6990       after = vat_time_now (vam);
6991
6992       /* slim chance, but we might have eaten SIGTERM on the first iteration */
6993       if (j > 0)
6994         count = j;
6995
6996       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6997              count, after - before, count / (after - before));
6998     }
6999   else
7000     {
7001       int ret;
7002
7003       /* Wait for a reply... */
7004       W (ret);
7005       return ret;
7006     }
7007
7008   /* Return the good/bad news */
7009   return (vam->retval);
7010 }
7011
7012 static int
7013 api_ip_mroute_add_del (vat_main_t * vam)
7014 {
7015   unformat_input_t *i = vam->input;
7016   vl_api_ip_mroute_add_del_t *mp;
7017   u32 sw_if_index = ~0, vrf_id = 0;
7018   u8 is_ipv6 = 0;
7019   u8 is_local = 0;
7020   u8 create_vrf_if_needed = 0;
7021   u8 is_add = 1;
7022   u8 address_set = 0;
7023   u32 grp_address_length = 0;
7024   ip4_address_t v4_grp_address, v4_src_address;
7025   ip6_address_t v6_grp_address, v6_src_address;
7026   mfib_itf_flags_t iflags = 0;
7027   mfib_entry_flags_t eflags = 0;
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, "sw_if_index %d", &sw_if_index))
7034         ;
7035       else if (unformat (i, "%U %U",
7036                          unformat_ip4_address, &v4_src_address,
7037                          unformat_ip4_address, &v4_grp_address))
7038         {
7039           grp_address_length = 64;
7040           address_set = 1;
7041           is_ipv6 = 0;
7042         }
7043       else if (unformat (i, "%U %U",
7044                          unformat_ip6_address, &v6_src_address,
7045                          unformat_ip6_address, &v6_grp_address))
7046         {
7047           grp_address_length = 256;
7048           address_set = 1;
7049           is_ipv6 = 1;
7050         }
7051       else if (unformat (i, "%U", unformat_ip4_address, &v4_grp_address))
7052         {
7053           memset (&v4_src_address, 0, sizeof (v4_src_address));
7054           grp_address_length = 32;
7055           address_set = 1;
7056           is_ipv6 = 0;
7057         }
7058       else if (unformat (i, "%U", unformat_ip6_address, &v6_grp_address))
7059         {
7060           memset (&v6_src_address, 0, sizeof (v6_src_address));
7061           grp_address_length = 128;
7062           address_set = 1;
7063           is_ipv6 = 1;
7064         }
7065       else if (unformat (i, "/%d", &grp_address_length))
7066         ;
7067       else if (unformat (i, "local"))
7068         {
7069           is_local = 1;
7070         }
7071       else if (unformat (i, "del"))
7072         is_add = 0;
7073       else if (unformat (i, "add"))
7074         is_add = 1;
7075       else if (unformat (i, "vrf %d", &vrf_id))
7076         ;
7077       else if (unformat (i, "create-vrf"))
7078         create_vrf_if_needed = 1;
7079       else if (unformat (i, "%U", unformat_mfib_itf_flags, &iflags))
7080         ;
7081       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
7082         ;
7083       else
7084         {
7085           clib_warning ("parse error '%U'", format_unformat_error, i);
7086           return -99;
7087         }
7088     }
7089
7090   if (address_set == 0)
7091     {
7092       errmsg ("missing addresses\n");
7093       return -99;
7094     }
7095
7096   /* Construct the API message */
7097   M (IP_MROUTE_ADD_DEL, mp);
7098
7099   mp->next_hop_sw_if_index = ntohl (sw_if_index);
7100   mp->table_id = ntohl (vrf_id);
7101   mp->create_vrf_if_needed = create_vrf_if_needed;
7102
7103   mp->is_add = is_add;
7104   mp->is_ipv6 = is_ipv6;
7105   mp->is_local = is_local;
7106   mp->itf_flags = ntohl (iflags);
7107   mp->entry_flags = ntohl (eflags);
7108   mp->grp_address_length = grp_address_length;
7109   mp->grp_address_length = ntohs (mp->grp_address_length);
7110
7111   if (is_ipv6)
7112     {
7113       clib_memcpy (mp->grp_address, &v6_grp_address, sizeof (v6_grp_address));
7114       clib_memcpy (mp->src_address, &v6_src_address, sizeof (v6_src_address));
7115     }
7116   else
7117     {
7118       clib_memcpy (mp->grp_address, &v4_grp_address, sizeof (v4_grp_address));
7119       clib_memcpy (mp->src_address, &v4_src_address, sizeof (v4_src_address));
7120
7121     }
7122
7123   /* send it... */
7124   S (mp);
7125   /* Wait for a reply... */
7126   W (ret);
7127   return ret;
7128 }
7129
7130 static int
7131 api_mpls_route_add_del (vat_main_t * vam)
7132 {
7133   unformat_input_t *i = vam->input;
7134   vl_api_mpls_route_add_del_t *mp;
7135   u32 sw_if_index = ~0, table_id = 0;
7136   u8 create_table_if_needed = 0;
7137   u8 is_add = 1;
7138   u32 next_hop_weight = 1;
7139   u8 is_multipath = 0;
7140   u32 next_hop_table_id = 0;
7141   u8 next_hop_set = 0;
7142   ip4_address_t v4_next_hop_address = {
7143     .as_u32 = 0,
7144   };
7145   ip6_address_t v6_next_hop_address = { {0} };
7146   int count = 1;
7147   int j;
7148   f64 before = 0;
7149   u32 classify_table_index = ~0;
7150   u8 is_classify = 0;
7151   u8 resolve_host = 0, resolve_attached = 0;
7152   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
7153   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
7154   mpls_label_t *next_hop_out_label_stack = NULL;
7155   mpls_label_t local_label = MPLS_LABEL_INVALID;
7156   u8 is_eos = 0;
7157   u8 next_hop_proto_is_ip4 = 1;
7158
7159   /* Parse args required to build the message */
7160   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7161     {
7162       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7163         ;
7164       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7165         ;
7166       else if (unformat (i, "%d", &local_label))
7167         ;
7168       else if (unformat (i, "eos"))
7169         is_eos = 1;
7170       else if (unformat (i, "non-eos"))
7171         is_eos = 0;
7172       else if (unformat (i, "via %U", unformat_ip4_address,
7173                          &v4_next_hop_address))
7174         {
7175           next_hop_set = 1;
7176           next_hop_proto_is_ip4 = 1;
7177         }
7178       else if (unformat (i, "via %U", unformat_ip6_address,
7179                          &v6_next_hop_address))
7180         {
7181           next_hop_set = 1;
7182           next_hop_proto_is_ip4 = 0;
7183         }
7184       else if (unformat (i, "weight %d", &next_hop_weight))
7185         ;
7186       else if (unformat (i, "create-table"))
7187         create_table_if_needed = 1;
7188       else if (unformat (i, "classify %d", &classify_table_index))
7189         {
7190           is_classify = 1;
7191         }
7192       else if (unformat (i, "del"))
7193         is_add = 0;
7194       else if (unformat (i, "add"))
7195         is_add = 1;
7196       else if (unformat (i, "resolve-via-host"))
7197         resolve_host = 1;
7198       else if (unformat (i, "resolve-via-attached"))
7199         resolve_attached = 1;
7200       else if (unformat (i, "multipath"))
7201         is_multipath = 1;
7202       else if (unformat (i, "count %d", &count))
7203         ;
7204       else if (unformat (i, "lookup-in-ip4-table %d", &next_hop_table_id))
7205         {
7206           next_hop_set = 1;
7207           next_hop_proto_is_ip4 = 1;
7208         }
7209       else if (unformat (i, "lookup-in-ip6-table %d", &next_hop_table_id))
7210         {
7211           next_hop_set = 1;
7212           next_hop_proto_is_ip4 = 0;
7213         }
7214       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
7215         ;
7216       else if (unformat (i, "via-label %d", &next_hop_via_label))
7217         ;
7218       else if (unformat (i, "out-label %d", &next_hop_out_label))
7219         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
7220       else
7221         {
7222           clib_warning ("parse error '%U'", format_unformat_error, i);
7223           return -99;
7224         }
7225     }
7226
7227   if (!next_hop_set && !is_classify)
7228     {
7229       errmsg ("next hop / classify not set");
7230       return -99;
7231     }
7232
7233   if (MPLS_LABEL_INVALID == local_label)
7234     {
7235       errmsg ("missing label");
7236       return -99;
7237     }
7238
7239   if (count > 1)
7240     {
7241       /* Turn on async mode */
7242       vam->async_mode = 1;
7243       vam->async_errors = 0;
7244       before = vat_time_now (vam);
7245     }
7246
7247   for (j = 0; j < count; j++)
7248     {
7249       /* Construct the API message */
7250       M2 (MPLS_ROUTE_ADD_DEL, mp,
7251           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
7252
7253       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
7254       mp->mr_table_id = ntohl (table_id);
7255       mp->mr_create_table_if_needed = create_table_if_needed;
7256
7257       mp->mr_is_add = is_add;
7258       mp->mr_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
7259       mp->mr_is_classify = is_classify;
7260       mp->mr_is_multipath = is_multipath;
7261       mp->mr_is_resolve_host = resolve_host;
7262       mp->mr_is_resolve_attached = resolve_attached;
7263       mp->mr_next_hop_weight = next_hop_weight;
7264       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
7265       mp->mr_classify_table_index = ntohl (classify_table_index);
7266       mp->mr_next_hop_via_label = ntohl (next_hop_via_label);
7267       mp->mr_label = ntohl (local_label);
7268       mp->mr_eos = is_eos;
7269
7270       mp->mr_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
7271       if (0 != mp->mr_next_hop_n_out_labels)
7272         {
7273           memcpy (mp->mr_next_hop_out_label_stack,
7274                   next_hop_out_label_stack,
7275                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
7276           vec_free (next_hop_out_label_stack);
7277         }
7278
7279       if (next_hop_set)
7280         {
7281           if (next_hop_proto_is_ip4)
7282             {
7283               clib_memcpy (mp->mr_next_hop,
7284                            &v4_next_hop_address,
7285                            sizeof (v4_next_hop_address));
7286             }
7287           else
7288             {
7289               clib_memcpy (mp->mr_next_hop,
7290                            &v6_next_hop_address,
7291                            sizeof (v6_next_hop_address));
7292             }
7293         }
7294       local_label++;
7295
7296       /* send it... */
7297       S (mp);
7298       /* If we receive SIGTERM, stop now... */
7299       if (vam->do_exit)
7300         break;
7301     }
7302
7303   /* When testing multiple add/del ops, use a control-ping to sync */
7304   if (count > 1)
7305     {
7306       vl_api_control_ping_t *mp_ping;
7307       f64 after;
7308       f64 timeout;
7309
7310       /* Shut off async mode */
7311       vam->async_mode = 0;
7312
7313       M (CONTROL_PING, mp_ping);
7314       S (mp_ping);
7315
7316       timeout = vat_time_now (vam) + 1.0;
7317       while (vat_time_now (vam) < timeout)
7318         if (vam->result_ready == 1)
7319           goto out;
7320       vam->retval = -99;
7321
7322     out:
7323       if (vam->retval == -99)
7324         errmsg ("timeout");
7325
7326       if (vam->async_errors > 0)
7327         {
7328           errmsg ("%d asynchronous errors", vam->async_errors);
7329           vam->retval = -98;
7330         }
7331       vam->async_errors = 0;
7332       after = vat_time_now (vam);
7333
7334       /* slim chance, but we might have eaten SIGTERM on the first iteration */
7335       if (j > 0)
7336         count = j;
7337
7338       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
7339              count, after - before, count / (after - before));
7340     }
7341   else
7342     {
7343       int ret;
7344
7345       /* Wait for a reply... */
7346       W (ret);
7347       return ret;
7348     }
7349
7350   /* Return the good/bad news */
7351   return (vam->retval);
7352 }
7353
7354 static int
7355 api_mpls_ip_bind_unbind (vat_main_t * vam)
7356 {
7357   unformat_input_t *i = vam->input;
7358   vl_api_mpls_ip_bind_unbind_t *mp;
7359   u32 ip_table_id = 0;
7360   u8 create_table_if_needed = 0;
7361   u8 is_bind = 1;
7362   u8 is_ip4 = 1;
7363   ip4_address_t v4_address;
7364   ip6_address_t v6_address;
7365   u32 address_length;
7366   u8 address_set = 0;
7367   mpls_label_t local_label = MPLS_LABEL_INVALID;
7368   int ret;
7369
7370   /* Parse args required to build the message */
7371   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7372     {
7373       if (unformat (i, "%U/%d", unformat_ip4_address,
7374                     &v4_address, &address_length))
7375         {
7376           is_ip4 = 1;
7377           address_set = 1;
7378         }
7379       else if (unformat (i, "%U/%d", unformat_ip6_address,
7380                          &v6_address, &address_length))
7381         {
7382           is_ip4 = 0;
7383           address_set = 1;
7384         }
7385       else if (unformat (i, "%d", &local_label))
7386         ;
7387       else if (unformat (i, "create-table"))
7388         create_table_if_needed = 1;
7389       else if (unformat (i, "table-id %d", &ip_table_id))
7390         ;
7391       else if (unformat (i, "unbind"))
7392         is_bind = 0;
7393       else if (unformat (i, "bind"))
7394         is_bind = 1;
7395       else
7396         {
7397           clib_warning ("parse error '%U'", format_unformat_error, i);
7398           return -99;
7399         }
7400     }
7401
7402   if (!address_set)
7403     {
7404       errmsg ("IP addres not set");
7405       return -99;
7406     }
7407
7408   if (MPLS_LABEL_INVALID == local_label)
7409     {
7410       errmsg ("missing label");
7411       return -99;
7412     }
7413
7414   /* Construct the API message */
7415   M (MPLS_IP_BIND_UNBIND, mp);
7416
7417   mp->mb_create_table_if_needed = create_table_if_needed;
7418   mp->mb_is_bind = is_bind;
7419   mp->mb_is_ip4 = is_ip4;
7420   mp->mb_ip_table_id = ntohl (ip_table_id);
7421   mp->mb_mpls_table_id = 0;
7422   mp->mb_label = ntohl (local_label);
7423   mp->mb_address_length = address_length;
7424
7425   if (is_ip4)
7426     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
7427   else
7428     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
7429
7430   /* send it... */
7431   S (mp);
7432
7433   /* Wait for a reply... */
7434   W (ret);
7435   return ret;
7436 }
7437
7438 static int
7439 api_proxy_arp_add_del (vat_main_t * vam)
7440 {
7441   unformat_input_t *i = vam->input;
7442   vl_api_proxy_arp_add_del_t *mp;
7443   u32 vrf_id = 0;
7444   u8 is_add = 1;
7445   ip4_address_t lo, hi;
7446   u8 range_set = 0;
7447   int ret;
7448
7449   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7450     {
7451       if (unformat (i, "vrf %d", &vrf_id))
7452         ;
7453       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
7454                          unformat_ip4_address, &hi))
7455         range_set = 1;
7456       else if (unformat (i, "del"))
7457         is_add = 0;
7458       else
7459         {
7460           clib_warning ("parse error '%U'", format_unformat_error, i);
7461           return -99;
7462         }
7463     }
7464
7465   if (range_set == 0)
7466     {
7467       errmsg ("address range not set");
7468       return -99;
7469     }
7470
7471   M (PROXY_ARP_ADD_DEL, mp);
7472
7473   mp->vrf_id = ntohl (vrf_id);
7474   mp->is_add = is_add;
7475   clib_memcpy (mp->low_address, &lo, sizeof (mp->low_address));
7476   clib_memcpy (mp->hi_address, &hi, sizeof (mp->hi_address));
7477
7478   S (mp);
7479   W (ret);
7480   return ret;
7481 }
7482
7483 static int
7484 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
7485 {
7486   unformat_input_t *i = vam->input;
7487   vl_api_proxy_arp_intfc_enable_disable_t *mp;
7488   u32 sw_if_index;
7489   u8 enable = 1;
7490   u8 sw_if_index_set = 0;
7491   int ret;
7492
7493   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7494     {
7495       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7496         sw_if_index_set = 1;
7497       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7498         sw_if_index_set = 1;
7499       else if (unformat (i, "enable"))
7500         enable = 1;
7501       else if (unformat (i, "disable"))
7502         enable = 0;
7503       else
7504         {
7505           clib_warning ("parse error '%U'", format_unformat_error, i);
7506           return -99;
7507         }
7508     }
7509
7510   if (sw_if_index_set == 0)
7511     {
7512       errmsg ("missing interface name or sw_if_index");
7513       return -99;
7514     }
7515
7516   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
7517
7518   mp->sw_if_index = ntohl (sw_if_index);
7519   mp->enable_disable = enable;
7520
7521   S (mp);
7522   W (ret);
7523   return ret;
7524 }
7525
7526 static int
7527 api_mpls_tunnel_add_del (vat_main_t * vam)
7528 {
7529   unformat_input_t *i = vam->input;
7530   vl_api_mpls_tunnel_add_del_t *mp;
7531
7532   u8 is_add = 1;
7533   u8 l2_only = 0;
7534   u32 sw_if_index = ~0;
7535   u32 next_hop_sw_if_index = ~0;
7536   u32 next_hop_proto_is_ip4 = 1;
7537
7538   u32 next_hop_table_id = 0;
7539   ip4_address_t v4_next_hop_address = {
7540     .as_u32 = 0,
7541   };
7542   ip6_address_t v6_next_hop_address = { {0} };
7543   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID, *labels = NULL;
7544   int ret;
7545
7546   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7547     {
7548       if (unformat (i, "add"))
7549         is_add = 1;
7550       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
7551         is_add = 0;
7552       else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
7553         ;
7554       else if (unformat (i, "via %U",
7555                          unformat_ip4_address, &v4_next_hop_address))
7556         {
7557           next_hop_proto_is_ip4 = 1;
7558         }
7559       else if (unformat (i, "via %U",
7560                          unformat_ip6_address, &v6_next_hop_address))
7561         {
7562           next_hop_proto_is_ip4 = 0;
7563         }
7564       else if (unformat (i, "l2-only"))
7565         l2_only = 1;
7566       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
7567         ;
7568       else if (unformat (i, "out-label %d", &next_hop_out_label))
7569         vec_add1 (labels, ntohl (next_hop_out_label));
7570       else
7571         {
7572           clib_warning ("parse error '%U'", format_unformat_error, i);
7573           return -99;
7574         }
7575     }
7576
7577   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (mpls_label_t) * vec_len (labels));
7578
7579   mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
7580   mp->mt_sw_if_index = ntohl (sw_if_index);
7581   mp->mt_is_add = is_add;
7582   mp->mt_l2_only = l2_only;
7583   mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
7584   mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
7585
7586   mp->mt_next_hop_n_out_labels = vec_len (labels);
7587
7588   if (0 != mp->mt_next_hop_n_out_labels)
7589     {
7590       clib_memcpy (mp->mt_next_hop_out_label_stack, labels,
7591                    sizeof (mpls_label_t) * mp->mt_next_hop_n_out_labels);
7592       vec_free (labels);
7593     }
7594
7595   if (next_hop_proto_is_ip4)
7596     {
7597       clib_memcpy (mp->mt_next_hop,
7598                    &v4_next_hop_address, sizeof (v4_next_hop_address));
7599     }
7600   else
7601     {
7602       clib_memcpy (mp->mt_next_hop,
7603                    &v6_next_hop_address, sizeof (v6_next_hop_address));
7604     }
7605
7606   S (mp);
7607   W (ret);
7608   return ret;
7609 }
7610
7611 static int
7612 api_sw_interface_set_unnumbered (vat_main_t * vam)
7613 {
7614   unformat_input_t *i = vam->input;
7615   vl_api_sw_interface_set_unnumbered_t *mp;
7616   u32 sw_if_index;
7617   u32 unnum_sw_index = ~0;
7618   u8 is_add = 1;
7619   u8 sw_if_index_set = 0;
7620   int ret;
7621
7622   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7623     {
7624       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7625         sw_if_index_set = 1;
7626       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7627         sw_if_index_set = 1;
7628       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
7629         ;
7630       else if (unformat (i, "del"))
7631         is_add = 0;
7632       else
7633         {
7634           clib_warning ("parse error '%U'", format_unformat_error, i);
7635           return -99;
7636         }
7637     }
7638
7639   if (sw_if_index_set == 0)
7640     {
7641       errmsg ("missing interface name or sw_if_index");
7642       return -99;
7643     }
7644
7645   M (SW_INTERFACE_SET_UNNUMBERED, mp);
7646
7647   mp->sw_if_index = ntohl (sw_if_index);
7648   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
7649   mp->is_add = is_add;
7650
7651   S (mp);
7652   W (ret);
7653   return ret;
7654 }
7655
7656 static int
7657 api_ip_neighbor_add_del (vat_main_t * vam)
7658 {
7659   unformat_input_t *i = vam->input;
7660   vl_api_ip_neighbor_add_del_t *mp;
7661   u32 sw_if_index;
7662   u8 sw_if_index_set = 0;
7663   u8 is_add = 1;
7664   u8 is_static = 0;
7665   u8 is_no_fib_entry = 0;
7666   u8 mac_address[6];
7667   u8 mac_set = 0;
7668   u8 v4_address_set = 0;
7669   u8 v6_address_set = 0;
7670   ip4_address_t v4address;
7671   ip6_address_t v6address;
7672   int ret;
7673
7674   memset (mac_address, 0, sizeof (mac_address));
7675
7676   /* Parse args required to build the message */
7677   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7678     {
7679       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7680         {
7681           mac_set = 1;
7682         }
7683       else if (unformat (i, "del"))
7684         is_add = 0;
7685       else
7686         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7687         sw_if_index_set = 1;
7688       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7689         sw_if_index_set = 1;
7690       else if (unformat (i, "is_static"))
7691         is_static = 1;
7692       else if (unformat (i, "no-fib-entry"))
7693         is_no_fib_entry = 1;
7694       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
7695         v4_address_set = 1;
7696       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
7697         v6_address_set = 1;
7698       else
7699         {
7700           clib_warning ("parse error '%U'", format_unformat_error, i);
7701           return -99;
7702         }
7703     }
7704
7705   if (sw_if_index_set == 0)
7706     {
7707       errmsg ("missing interface name or sw_if_index");
7708       return -99;
7709     }
7710   if (v4_address_set && v6_address_set)
7711     {
7712       errmsg ("both v4 and v6 addresses set");
7713       return -99;
7714     }
7715   if (!v4_address_set && !v6_address_set)
7716     {
7717       errmsg ("no address set");
7718       return -99;
7719     }
7720
7721   /* Construct the API message */
7722   M (IP_NEIGHBOR_ADD_DEL, mp);
7723
7724   mp->sw_if_index = ntohl (sw_if_index);
7725   mp->is_add = is_add;
7726   mp->is_static = is_static;
7727   mp->is_no_adj_fib = is_no_fib_entry;
7728   if (mac_set)
7729     clib_memcpy (mp->mac_address, mac_address, 6);
7730   if (v6_address_set)
7731     {
7732       mp->is_ipv6 = 1;
7733       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
7734     }
7735   else
7736     {
7737       /* mp->is_ipv6 = 0; via memset in M macro above */
7738       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
7739     }
7740
7741   /* send it... */
7742   S (mp);
7743
7744   /* Wait for a reply, return good/bad news  */
7745   W (ret);
7746   return ret;
7747 }
7748
7749 static int
7750 api_reset_vrf (vat_main_t * vam)
7751 {
7752   unformat_input_t *i = vam->input;
7753   vl_api_reset_vrf_t *mp;
7754   u32 vrf_id = 0;
7755   u8 is_ipv6 = 0;
7756   u8 vrf_id_set = 0;
7757   int ret;
7758
7759   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7760     {
7761       if (unformat (i, "vrf %d", &vrf_id))
7762         vrf_id_set = 1;
7763       else if (unformat (i, "ipv6"))
7764         is_ipv6 = 1;
7765       else
7766         {
7767           clib_warning ("parse error '%U'", format_unformat_error, i);
7768           return -99;
7769         }
7770     }
7771
7772   if (vrf_id_set == 0)
7773     {
7774       errmsg ("missing vrf id");
7775       return -99;
7776     }
7777
7778   M (RESET_VRF, mp);
7779
7780   mp->vrf_id = ntohl (vrf_id);
7781   mp->is_ipv6 = is_ipv6;
7782
7783   S (mp);
7784   W (ret);
7785   return ret;
7786 }
7787
7788 static int
7789 api_create_vlan_subif (vat_main_t * vam)
7790 {
7791   unformat_input_t *i = vam->input;
7792   vl_api_create_vlan_subif_t *mp;
7793   u32 sw_if_index;
7794   u8 sw_if_index_set = 0;
7795   u32 vlan_id;
7796   u8 vlan_id_set = 0;
7797   int ret;
7798
7799   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7800     {
7801       if (unformat (i, "sw_if_index %d", &sw_if_index))
7802         sw_if_index_set = 1;
7803       else
7804         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7805         sw_if_index_set = 1;
7806       else if (unformat (i, "vlan %d", &vlan_id))
7807         vlan_id_set = 1;
7808       else
7809         {
7810           clib_warning ("parse error '%U'", format_unformat_error, i);
7811           return -99;
7812         }
7813     }
7814
7815   if (sw_if_index_set == 0)
7816     {
7817       errmsg ("missing interface name or sw_if_index");
7818       return -99;
7819     }
7820
7821   if (vlan_id_set == 0)
7822     {
7823       errmsg ("missing vlan_id");
7824       return -99;
7825     }
7826   M (CREATE_VLAN_SUBIF, mp);
7827
7828   mp->sw_if_index = ntohl (sw_if_index);
7829   mp->vlan_id = ntohl (vlan_id);
7830
7831   S (mp);
7832   W (ret);
7833   return ret;
7834 }
7835
7836 #define foreach_create_subif_bit                \
7837 _(no_tags)                                      \
7838 _(one_tag)                                      \
7839 _(two_tags)                                     \
7840 _(dot1ad)                                       \
7841 _(exact_match)                                  \
7842 _(default_sub)                                  \
7843 _(outer_vlan_id_any)                            \
7844 _(inner_vlan_id_any)
7845
7846 static int
7847 api_create_subif (vat_main_t * vam)
7848 {
7849   unformat_input_t *i = vam->input;
7850   vl_api_create_subif_t *mp;
7851   u32 sw_if_index;
7852   u8 sw_if_index_set = 0;
7853   u32 sub_id;
7854   u8 sub_id_set = 0;
7855   u32 no_tags = 0;
7856   u32 one_tag = 0;
7857   u32 two_tags = 0;
7858   u32 dot1ad = 0;
7859   u32 exact_match = 0;
7860   u32 default_sub = 0;
7861   u32 outer_vlan_id_any = 0;
7862   u32 inner_vlan_id_any = 0;
7863   u32 tmp;
7864   u16 outer_vlan_id = 0;
7865   u16 inner_vlan_id = 0;
7866   int ret;
7867
7868   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7869     {
7870       if (unformat (i, "sw_if_index %d", &sw_if_index))
7871         sw_if_index_set = 1;
7872       else
7873         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7874         sw_if_index_set = 1;
7875       else if (unformat (i, "sub_id %d", &sub_id))
7876         sub_id_set = 1;
7877       else if (unformat (i, "outer_vlan_id %d", &tmp))
7878         outer_vlan_id = tmp;
7879       else if (unformat (i, "inner_vlan_id %d", &tmp))
7880         inner_vlan_id = tmp;
7881
7882 #define _(a) else if (unformat (i, #a)) a = 1 ;
7883       foreach_create_subif_bit
7884 #undef _
7885         else
7886         {
7887           clib_warning ("parse error '%U'", format_unformat_error, i);
7888           return -99;
7889         }
7890     }
7891
7892   if (sw_if_index_set == 0)
7893     {
7894       errmsg ("missing interface name or sw_if_index");
7895       return -99;
7896     }
7897
7898   if (sub_id_set == 0)
7899     {
7900       errmsg ("missing sub_id");
7901       return -99;
7902     }
7903   M (CREATE_SUBIF, mp);
7904
7905   mp->sw_if_index = ntohl (sw_if_index);
7906   mp->sub_id = ntohl (sub_id);
7907
7908 #define _(a) mp->a = a;
7909   foreach_create_subif_bit;
7910 #undef _
7911
7912   mp->outer_vlan_id = ntohs (outer_vlan_id);
7913   mp->inner_vlan_id = ntohs (inner_vlan_id);
7914
7915   S (mp);
7916   W (ret);
7917   return ret;
7918 }
7919
7920 static int
7921 api_oam_add_del (vat_main_t * vam)
7922 {
7923   unformat_input_t *i = vam->input;
7924   vl_api_oam_add_del_t *mp;
7925   u32 vrf_id = 0;
7926   u8 is_add = 1;
7927   ip4_address_t src, dst;
7928   u8 src_set = 0;
7929   u8 dst_set = 0;
7930   int ret;
7931
7932   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7933     {
7934       if (unformat (i, "vrf %d", &vrf_id))
7935         ;
7936       else if (unformat (i, "src %U", unformat_ip4_address, &src))
7937         src_set = 1;
7938       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
7939         dst_set = 1;
7940       else if (unformat (i, "del"))
7941         is_add = 0;
7942       else
7943         {
7944           clib_warning ("parse error '%U'", format_unformat_error, i);
7945           return -99;
7946         }
7947     }
7948
7949   if (src_set == 0)
7950     {
7951       errmsg ("missing src addr");
7952       return -99;
7953     }
7954
7955   if (dst_set == 0)
7956     {
7957       errmsg ("missing dst addr");
7958       return -99;
7959     }
7960
7961   M (OAM_ADD_DEL, mp);
7962
7963   mp->vrf_id = ntohl (vrf_id);
7964   mp->is_add = is_add;
7965   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
7966   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
7967
7968   S (mp);
7969   W (ret);
7970   return ret;
7971 }
7972
7973 static int
7974 api_reset_fib (vat_main_t * vam)
7975 {
7976   unformat_input_t *i = vam->input;
7977   vl_api_reset_fib_t *mp;
7978   u32 vrf_id = 0;
7979   u8 is_ipv6 = 0;
7980   u8 vrf_id_set = 0;
7981
7982   int ret;
7983   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7984     {
7985       if (unformat (i, "vrf %d", &vrf_id))
7986         vrf_id_set = 1;
7987       else if (unformat (i, "ipv6"))
7988         is_ipv6 = 1;
7989       else
7990         {
7991           clib_warning ("parse error '%U'", format_unformat_error, i);
7992           return -99;
7993         }
7994     }
7995
7996   if (vrf_id_set == 0)
7997     {
7998       errmsg ("missing vrf id");
7999       return -99;
8000     }
8001
8002   M (RESET_FIB, mp);
8003
8004   mp->vrf_id = ntohl (vrf_id);
8005   mp->is_ipv6 = is_ipv6;
8006
8007   S (mp);
8008   W (ret);
8009   return ret;
8010 }
8011
8012 static int
8013 api_dhcp_proxy_config (vat_main_t * vam)
8014 {
8015   unformat_input_t *i = vam->input;
8016   vl_api_dhcp_proxy_config_t *mp;
8017   u32 rx_vrf_id = 0;
8018   u32 server_vrf_id = 0;
8019   u8 is_add = 1;
8020   u8 v4_address_set = 0;
8021   u8 v6_address_set = 0;
8022   ip4_address_t v4address;
8023   ip6_address_t v6address;
8024   u8 v4_src_address_set = 0;
8025   u8 v6_src_address_set = 0;
8026   ip4_address_t v4srcaddress;
8027   ip6_address_t v6srcaddress;
8028   int ret;
8029
8030   /* Parse args required to build the message */
8031   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8032     {
8033       if (unformat (i, "del"))
8034         is_add = 0;
8035       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
8036         ;
8037       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
8038         ;
8039       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
8040         v4_address_set = 1;
8041       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
8042         v6_address_set = 1;
8043       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
8044         v4_src_address_set = 1;
8045       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
8046         v6_src_address_set = 1;
8047       else
8048         break;
8049     }
8050
8051   if (v4_address_set && v6_address_set)
8052     {
8053       errmsg ("both v4 and v6 server addresses set");
8054       return -99;
8055     }
8056   if (!v4_address_set && !v6_address_set)
8057     {
8058       errmsg ("no server addresses set");
8059       return -99;
8060     }
8061
8062   if (v4_src_address_set && v6_src_address_set)
8063     {
8064       errmsg ("both v4 and v6  src addresses set");
8065       return -99;
8066     }
8067   if (!v4_src_address_set && !v6_src_address_set)
8068     {
8069       errmsg ("no src addresses set");
8070       return -99;
8071     }
8072
8073   if (!(v4_src_address_set && v4_address_set) &&
8074       !(v6_src_address_set && v6_address_set))
8075     {
8076       errmsg ("no matching server and src addresses set");
8077       return -99;
8078     }
8079
8080   /* Construct the API message */
8081   M (DHCP_PROXY_CONFIG, mp);
8082
8083   mp->is_add = is_add;
8084   mp->rx_vrf_id = ntohl (rx_vrf_id);
8085   mp->server_vrf_id = ntohl (server_vrf_id);
8086   if (v6_address_set)
8087     {
8088       mp->is_ipv6 = 1;
8089       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
8090       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
8091     }
8092   else
8093     {
8094       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
8095       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
8096     }
8097
8098   /* send it... */
8099   S (mp);
8100
8101   /* Wait for a reply, return good/bad news  */
8102   W (ret);
8103   return ret;
8104 }
8105
8106 #define vl_api_dhcp_proxy_details_t_endian vl_noop_handler
8107 #define vl_api_dhcp_proxy_details_t_print vl_noop_handler
8108
8109 static void
8110 vl_api_dhcp_proxy_details_t_handler (vl_api_dhcp_proxy_details_t * mp)
8111 {
8112   vat_main_t *vam = &vat_main;
8113   u32 i, count = mp->count;
8114   vl_api_dhcp_server_t *s;
8115
8116   if (mp->is_ipv6)
8117     print (vam->ofp,
8118            "RX Table-ID %d, Source Address %U, VSS FIB-ID %d, VSS OUI %d",
8119            ntohl (mp->rx_vrf_id),
8120            format_ip6_address, mp->dhcp_src_address,
8121            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
8122   else
8123     print (vam->ofp,
8124            "RX Table-ID %d, Source Address %U, VSS FIB-ID %d, VSS OUI %d",
8125            ntohl (mp->rx_vrf_id),
8126            format_ip4_address, mp->dhcp_src_address,
8127            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
8128
8129   for (i = 0; i < count; i++)
8130     {
8131       s = &mp->servers[i];
8132
8133       if (mp->is_ipv6)
8134         print (vam->ofp,
8135                " Server Table-ID %d, Server Address %U",
8136                ntohl (s->server_vrf_id), format_ip6_address, s->dhcp_server);
8137       else
8138         print (vam->ofp,
8139                " Server Table-ID %d, Server Address %U",
8140                ntohl (s->server_vrf_id), format_ip4_address, s->dhcp_server);
8141     }
8142 }
8143
8144 static void vl_api_dhcp_proxy_details_t_handler_json
8145   (vl_api_dhcp_proxy_details_t * mp)
8146 {
8147   vat_main_t *vam = &vat_main;
8148   vat_json_node_t *node = NULL;
8149   u32 i, count = mp->count;
8150   struct in_addr ip4;
8151   struct in6_addr ip6;
8152   vl_api_dhcp_server_t *s;
8153
8154   if (VAT_JSON_ARRAY != vam->json_tree.type)
8155     {
8156       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
8157       vat_json_init_array (&vam->json_tree);
8158     }
8159   node = vat_json_array_add (&vam->json_tree);
8160
8161   vat_json_init_object (node);
8162   vat_json_object_add_uint (node, "rx-table-id", ntohl (mp->rx_vrf_id));
8163   vat_json_object_add_uint (node, "vss-fib-id", ntohl (mp->vss_fib_id));
8164   vat_json_object_add_uint (node, "vss-oui", ntohl (mp->vss_oui));
8165
8166   if (mp->is_ipv6)
8167     {
8168       clib_memcpy (&ip6, &mp->dhcp_src_address, sizeof (ip6));
8169       vat_json_object_add_ip6 (node, "src_address", ip6);
8170     }
8171   else
8172     {
8173       clib_memcpy (&ip4, &mp->dhcp_src_address, sizeof (ip4));
8174       vat_json_object_add_ip4 (node, "src_address", ip4);
8175     }
8176
8177   for (i = 0; i < count; i++)
8178     {
8179       s = &mp->servers[i];
8180
8181       vat_json_object_add_uint (node, "server-table-id",
8182                                 ntohl (s->server_vrf_id));
8183
8184       if (mp->is_ipv6)
8185         {
8186           clib_memcpy (&ip4, &s->dhcp_server, sizeof (ip4));
8187           vat_json_object_add_ip4 (node, "src_address", ip4);
8188         }
8189       else
8190         {
8191           clib_memcpy (&ip6, &s->dhcp_server, sizeof (ip6));
8192           vat_json_object_add_ip6 (node, "server_address", ip6);
8193         }
8194     }
8195 }
8196
8197 static int
8198 api_dhcp_proxy_dump (vat_main_t * vam)
8199 {
8200   unformat_input_t *i = vam->input;
8201   vl_api_control_ping_t *mp_ping;
8202   vl_api_dhcp_proxy_dump_t *mp;
8203   u8 is_ipv6 = 0;
8204   int ret;
8205
8206   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8207     {
8208       if (unformat (i, "ipv6"))
8209         is_ipv6 = 1;
8210       else
8211         {
8212           clib_warning ("parse error '%U'", format_unformat_error, i);
8213           return -99;
8214         }
8215     }
8216
8217   M (DHCP_PROXY_DUMP, mp);
8218
8219   mp->is_ip6 = is_ipv6;
8220   S (mp);
8221
8222   /* Use a control ping for synchronization */
8223   M (CONTROL_PING, mp_ping);
8224   S (mp_ping);
8225
8226   W (ret);
8227   return ret;
8228 }
8229
8230 static int
8231 api_dhcp_proxy_set_vss (vat_main_t * vam)
8232 {
8233   unformat_input_t *i = vam->input;
8234   vl_api_dhcp_proxy_set_vss_t *mp;
8235   u8 is_ipv6 = 0;
8236   u8 is_add = 1;
8237   u32 tbl_id;
8238   u8 tbl_id_set = 0;
8239   u32 oui;
8240   u8 oui_set = 0;
8241   u32 fib_id;
8242   u8 fib_id_set = 0;
8243   int ret;
8244
8245   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8246     {
8247       if (unformat (i, "tbl_id %d", &tbl_id))
8248         tbl_id_set = 1;
8249       if (unformat (i, "fib_id %d", &fib_id))
8250         fib_id_set = 1;
8251       if (unformat (i, "oui %d", &oui))
8252         oui_set = 1;
8253       else if (unformat (i, "ipv6"))
8254         is_ipv6 = 1;
8255       else if (unformat (i, "del"))
8256         is_add = 0;
8257       else
8258         {
8259           clib_warning ("parse error '%U'", format_unformat_error, i);
8260           return -99;
8261         }
8262     }
8263
8264   if (tbl_id_set == 0)
8265     {
8266       errmsg ("missing tbl id");
8267       return -99;
8268     }
8269
8270   if (fib_id_set == 0)
8271     {
8272       errmsg ("missing fib id");
8273       return -99;
8274     }
8275   if (oui_set == 0)
8276     {
8277       errmsg ("missing oui");
8278       return -99;
8279     }
8280
8281   M (DHCP_PROXY_SET_VSS, mp);
8282   mp->tbl_id = ntohl (tbl_id);
8283   mp->fib_id = ntohl (fib_id);
8284   mp->oui = ntohl (oui);
8285   mp->is_ipv6 = is_ipv6;
8286   mp->is_add = is_add;
8287
8288   S (mp);
8289   W (ret);
8290   return ret;
8291 }
8292
8293 static int
8294 api_dhcp_client_config (vat_main_t * vam)
8295 {
8296   unformat_input_t *i = vam->input;
8297   vl_api_dhcp_client_config_t *mp;
8298   u32 sw_if_index;
8299   u8 sw_if_index_set = 0;
8300   u8 is_add = 1;
8301   u8 *hostname = 0;
8302   u8 disable_event = 0;
8303   int ret;
8304
8305   /* Parse args required to build the message */
8306   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8307     {
8308       if (unformat (i, "del"))
8309         is_add = 0;
8310       else
8311         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8312         sw_if_index_set = 1;
8313       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8314         sw_if_index_set = 1;
8315       else if (unformat (i, "hostname %s", &hostname))
8316         ;
8317       else if (unformat (i, "disable_event"))
8318         disable_event = 1;
8319       else
8320         break;
8321     }
8322
8323   if (sw_if_index_set == 0)
8324     {
8325       errmsg ("missing interface name or sw_if_index");
8326       return -99;
8327     }
8328
8329   if (vec_len (hostname) > 63)
8330     {
8331       errmsg ("hostname too long");
8332     }
8333   vec_add1 (hostname, 0);
8334
8335   /* Construct the API message */
8336   M (DHCP_CLIENT_CONFIG, mp);
8337
8338   mp->sw_if_index = htonl (sw_if_index);
8339   clib_memcpy (mp->hostname, hostname, vec_len (hostname));
8340   vec_free (hostname);
8341   mp->is_add = is_add;
8342   mp->want_dhcp_event = disable_event ? 0 : 1;
8343   mp->pid = htonl (getpid ());
8344
8345   /* send it... */
8346   S (mp);
8347
8348   /* Wait for a reply, return good/bad news  */
8349   W (ret);
8350   return ret;
8351 }
8352
8353 static int
8354 api_set_ip_flow_hash (vat_main_t * vam)
8355 {
8356   unformat_input_t *i = vam->input;
8357   vl_api_set_ip_flow_hash_t *mp;
8358   u32 vrf_id = 0;
8359   u8 is_ipv6 = 0;
8360   u8 vrf_id_set = 0;
8361   u8 src = 0;
8362   u8 dst = 0;
8363   u8 sport = 0;
8364   u8 dport = 0;
8365   u8 proto = 0;
8366   u8 reverse = 0;
8367   int ret;
8368
8369   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8370     {
8371       if (unformat (i, "vrf %d", &vrf_id))
8372         vrf_id_set = 1;
8373       else if (unformat (i, "ipv6"))
8374         is_ipv6 = 1;
8375       else if (unformat (i, "src"))
8376         src = 1;
8377       else if (unformat (i, "dst"))
8378         dst = 1;
8379       else if (unformat (i, "sport"))
8380         sport = 1;
8381       else if (unformat (i, "dport"))
8382         dport = 1;
8383       else if (unformat (i, "proto"))
8384         proto = 1;
8385       else if (unformat (i, "reverse"))
8386         reverse = 1;
8387
8388       else
8389         {
8390           clib_warning ("parse error '%U'", format_unformat_error, i);
8391           return -99;
8392         }
8393     }
8394
8395   if (vrf_id_set == 0)
8396     {
8397       errmsg ("missing vrf id");
8398       return -99;
8399     }
8400
8401   M (SET_IP_FLOW_HASH, mp);
8402   mp->src = src;
8403   mp->dst = dst;
8404   mp->sport = sport;
8405   mp->dport = dport;
8406   mp->proto = proto;
8407   mp->reverse = reverse;
8408   mp->vrf_id = ntohl (vrf_id);
8409   mp->is_ipv6 = is_ipv6;
8410
8411   S (mp);
8412   W (ret);
8413   return ret;
8414 }
8415
8416 static int
8417 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
8418 {
8419   unformat_input_t *i = vam->input;
8420   vl_api_sw_interface_ip6_enable_disable_t *mp;
8421   u32 sw_if_index;
8422   u8 sw_if_index_set = 0;
8423   u8 enable = 0;
8424   int ret;
8425
8426   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8427     {
8428       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8429         sw_if_index_set = 1;
8430       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8431         sw_if_index_set = 1;
8432       else if (unformat (i, "enable"))
8433         enable = 1;
8434       else if (unformat (i, "disable"))
8435         enable = 0;
8436       else
8437         {
8438           clib_warning ("parse error '%U'", format_unformat_error, i);
8439           return -99;
8440         }
8441     }
8442
8443   if (sw_if_index_set == 0)
8444     {
8445       errmsg ("missing interface name or sw_if_index");
8446       return -99;
8447     }
8448
8449   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
8450
8451   mp->sw_if_index = ntohl (sw_if_index);
8452   mp->enable = enable;
8453
8454   S (mp);
8455   W (ret);
8456   return ret;
8457 }
8458
8459 static int
8460 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
8461 {
8462   unformat_input_t *i = vam->input;
8463   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
8464   u32 sw_if_index;
8465   u8 sw_if_index_set = 0;
8466   u8 v6_address_set = 0;
8467   ip6_address_t v6address;
8468   int ret;
8469
8470   /* Parse args required to build the message */
8471   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8472     {
8473       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8474         sw_if_index_set = 1;
8475       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8476         sw_if_index_set = 1;
8477       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
8478         v6_address_set = 1;
8479       else
8480         break;
8481     }
8482
8483   if (sw_if_index_set == 0)
8484     {
8485       errmsg ("missing interface name or sw_if_index");
8486       return -99;
8487     }
8488   if (!v6_address_set)
8489     {
8490       errmsg ("no address set");
8491       return -99;
8492     }
8493
8494   /* Construct the API message */
8495   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS, mp);
8496
8497   mp->sw_if_index = ntohl (sw_if_index);
8498   clib_memcpy (mp->address, &v6address, sizeof (v6address));
8499
8500   /* send it... */
8501   S (mp);
8502
8503   /* Wait for a reply, return good/bad news  */
8504   W (ret);
8505   return ret;
8506 }
8507
8508 static int
8509 api_ip6nd_proxy_add_del (vat_main_t * vam)
8510 {
8511   unformat_input_t *i = vam->input;
8512   vl_api_ip6nd_proxy_add_del_t *mp;
8513   u32 sw_if_index = ~0;
8514   u8 v6_address_set = 0;
8515   ip6_address_t v6address;
8516   u8 is_del = 0;
8517   int ret;
8518
8519   /* Parse args required to build the message */
8520   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8521     {
8522       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8523         ;
8524       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8525         ;
8526       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
8527         v6_address_set = 1;
8528       if (unformat (i, "del"))
8529         is_del = 1;
8530       else
8531         {
8532           clib_warning ("parse error '%U'", format_unformat_error, i);
8533           return -99;
8534         }
8535     }
8536
8537   if (sw_if_index == ~0)
8538     {
8539       errmsg ("missing interface name or sw_if_index");
8540       return -99;
8541     }
8542   if (!v6_address_set)
8543     {
8544       errmsg ("no address set");
8545       return -99;
8546     }
8547
8548   /* Construct the API message */
8549   M (IP6ND_PROXY_ADD_DEL, mp);
8550
8551   mp->is_del = is_del;
8552   mp->sw_if_index = ntohl (sw_if_index);
8553   clib_memcpy (mp->address, &v6address, sizeof (v6address));
8554
8555   /* send it... */
8556   S (mp);
8557
8558   /* Wait for a reply, return good/bad news  */
8559   W (ret);
8560   return ret;
8561 }
8562
8563 static int
8564 api_ip6nd_proxy_dump (vat_main_t * vam)
8565 {
8566   vl_api_ip6nd_proxy_dump_t *mp;
8567   vl_api_control_ping_t *mp_ping;
8568   int ret;
8569
8570   M (IP6ND_PROXY_DUMP, mp);
8571
8572   S (mp);
8573
8574   /* Use a control ping for synchronization */
8575   M (CONTROL_PING, mp_ping);
8576   S (mp_ping);
8577
8578   W (ret);
8579   return ret;
8580 }
8581
8582 static void vl_api_ip6nd_proxy_details_t_handler
8583   (vl_api_ip6nd_proxy_details_t * mp)
8584 {
8585   vat_main_t *vam = &vat_main;
8586
8587   print (vam->ofp, "host %U sw_if_index %d",
8588          format_ip6_address, mp->address, ntohl (mp->sw_if_index));
8589 }
8590
8591 static void vl_api_ip6nd_proxy_details_t_handler_json
8592   (vl_api_ip6nd_proxy_details_t * mp)
8593 {
8594   vat_main_t *vam = &vat_main;
8595   struct in6_addr ip6;
8596   vat_json_node_t *node = NULL;
8597
8598   if (VAT_JSON_ARRAY != vam->json_tree.type)
8599     {
8600       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
8601       vat_json_init_array (&vam->json_tree);
8602     }
8603   node = vat_json_array_add (&vam->json_tree);
8604
8605   vat_json_init_object (node);
8606   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
8607
8608   clib_memcpy (&ip6, mp->address, sizeof (ip6));
8609   vat_json_object_add_ip6 (node, "host", ip6);
8610 }
8611
8612 static int
8613 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
8614 {
8615   unformat_input_t *i = vam->input;
8616   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
8617   u32 sw_if_index;
8618   u8 sw_if_index_set = 0;
8619   u32 address_length = 0;
8620   u8 v6_address_set = 0;
8621   ip6_address_t v6address;
8622   u8 use_default = 0;
8623   u8 no_advertise = 0;
8624   u8 off_link = 0;
8625   u8 no_autoconfig = 0;
8626   u8 no_onlink = 0;
8627   u8 is_no = 0;
8628   u32 val_lifetime = 0;
8629   u32 pref_lifetime = 0;
8630   int ret;
8631
8632   /* Parse args required to build the message */
8633   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8634     {
8635       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8636         sw_if_index_set = 1;
8637       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8638         sw_if_index_set = 1;
8639       else if (unformat (i, "%U/%d",
8640                          unformat_ip6_address, &v6address, &address_length))
8641         v6_address_set = 1;
8642       else if (unformat (i, "val_life %d", &val_lifetime))
8643         ;
8644       else if (unformat (i, "pref_life %d", &pref_lifetime))
8645         ;
8646       else if (unformat (i, "def"))
8647         use_default = 1;
8648       else if (unformat (i, "noadv"))
8649         no_advertise = 1;
8650       else if (unformat (i, "offl"))
8651         off_link = 1;
8652       else if (unformat (i, "noauto"))
8653         no_autoconfig = 1;
8654       else if (unformat (i, "nolink"))
8655         no_onlink = 1;
8656       else if (unformat (i, "isno"))
8657         is_no = 1;
8658       else
8659         {
8660           clib_warning ("parse error '%U'", format_unformat_error, i);
8661           return -99;
8662         }
8663     }
8664
8665   if (sw_if_index_set == 0)
8666     {
8667       errmsg ("missing interface name or sw_if_index");
8668       return -99;
8669     }
8670   if (!v6_address_set)
8671     {
8672       errmsg ("no address set");
8673       return -99;
8674     }
8675
8676   /* Construct the API message */
8677   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
8678
8679   mp->sw_if_index = ntohl (sw_if_index);
8680   clib_memcpy (mp->address, &v6address, sizeof (v6address));
8681   mp->address_length = address_length;
8682   mp->use_default = use_default;
8683   mp->no_advertise = no_advertise;
8684   mp->off_link = off_link;
8685   mp->no_autoconfig = no_autoconfig;
8686   mp->no_onlink = no_onlink;
8687   mp->is_no = is_no;
8688   mp->val_lifetime = ntohl (val_lifetime);
8689   mp->pref_lifetime = ntohl (pref_lifetime);
8690
8691   /* send it... */
8692   S (mp);
8693
8694   /* Wait for a reply, return good/bad news  */
8695   W (ret);
8696   return ret;
8697 }
8698
8699 static int
8700 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
8701 {
8702   unformat_input_t *i = vam->input;
8703   vl_api_sw_interface_ip6nd_ra_config_t *mp;
8704   u32 sw_if_index;
8705   u8 sw_if_index_set = 0;
8706   u8 suppress = 0;
8707   u8 managed = 0;
8708   u8 other = 0;
8709   u8 ll_option = 0;
8710   u8 send_unicast = 0;
8711   u8 cease = 0;
8712   u8 is_no = 0;
8713   u8 default_router = 0;
8714   u32 max_interval = 0;
8715   u32 min_interval = 0;
8716   u32 lifetime = 0;
8717   u32 initial_count = 0;
8718   u32 initial_interval = 0;
8719   int ret;
8720
8721
8722   /* Parse args required to build the message */
8723   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8724     {
8725       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8726         sw_if_index_set = 1;
8727       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8728         sw_if_index_set = 1;
8729       else if (unformat (i, "maxint %d", &max_interval))
8730         ;
8731       else if (unformat (i, "minint %d", &min_interval))
8732         ;
8733       else if (unformat (i, "life %d", &lifetime))
8734         ;
8735       else if (unformat (i, "count %d", &initial_count))
8736         ;
8737       else if (unformat (i, "interval %d", &initial_interval))
8738         ;
8739       else if (unformat (i, "suppress") || unformat (i, "surpress"))
8740         suppress = 1;
8741       else if (unformat (i, "managed"))
8742         managed = 1;
8743       else if (unformat (i, "other"))
8744         other = 1;
8745       else if (unformat (i, "ll"))
8746         ll_option = 1;
8747       else if (unformat (i, "send"))
8748         send_unicast = 1;
8749       else if (unformat (i, "cease"))
8750         cease = 1;
8751       else if (unformat (i, "isno"))
8752         is_no = 1;
8753       else if (unformat (i, "def"))
8754         default_router = 1;
8755       else
8756         {
8757           clib_warning ("parse error '%U'", format_unformat_error, i);
8758           return -99;
8759         }
8760     }
8761
8762   if (sw_if_index_set == 0)
8763     {
8764       errmsg ("missing interface name or sw_if_index");
8765       return -99;
8766     }
8767
8768   /* Construct the API message */
8769   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
8770
8771   mp->sw_if_index = ntohl (sw_if_index);
8772   mp->max_interval = ntohl (max_interval);
8773   mp->min_interval = ntohl (min_interval);
8774   mp->lifetime = ntohl (lifetime);
8775   mp->initial_count = ntohl (initial_count);
8776   mp->initial_interval = ntohl (initial_interval);
8777   mp->suppress = suppress;
8778   mp->managed = managed;
8779   mp->other = other;
8780   mp->ll_option = ll_option;
8781   mp->send_unicast = send_unicast;
8782   mp->cease = cease;
8783   mp->is_no = is_no;
8784   mp->default_router = default_router;
8785
8786   /* send it... */
8787   S (mp);
8788
8789   /* Wait for a reply, return good/bad news  */
8790   W (ret);
8791   return ret;
8792 }
8793
8794 static int
8795 api_set_arp_neighbor_limit (vat_main_t * vam)
8796 {
8797   unformat_input_t *i = vam->input;
8798   vl_api_set_arp_neighbor_limit_t *mp;
8799   u32 arp_nbr_limit;
8800   u8 limit_set = 0;
8801   u8 is_ipv6 = 0;
8802   int ret;
8803
8804   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8805     {
8806       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
8807         limit_set = 1;
8808       else if (unformat (i, "ipv6"))
8809         is_ipv6 = 1;
8810       else
8811         {
8812           clib_warning ("parse error '%U'", format_unformat_error, i);
8813           return -99;
8814         }
8815     }
8816
8817   if (limit_set == 0)
8818     {
8819       errmsg ("missing limit value");
8820       return -99;
8821     }
8822
8823   M (SET_ARP_NEIGHBOR_LIMIT, mp);
8824
8825   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
8826   mp->is_ipv6 = is_ipv6;
8827
8828   S (mp);
8829   W (ret);
8830   return ret;
8831 }
8832
8833 static int
8834 api_l2_patch_add_del (vat_main_t * vam)
8835 {
8836   unformat_input_t *i = vam->input;
8837   vl_api_l2_patch_add_del_t *mp;
8838   u32 rx_sw_if_index;
8839   u8 rx_sw_if_index_set = 0;
8840   u32 tx_sw_if_index;
8841   u8 tx_sw_if_index_set = 0;
8842   u8 is_add = 1;
8843   int ret;
8844
8845   /* Parse args required to build the message */
8846   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8847     {
8848       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
8849         rx_sw_if_index_set = 1;
8850       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
8851         tx_sw_if_index_set = 1;
8852       else if (unformat (i, "rx"))
8853         {
8854           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8855             {
8856               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
8857                             &rx_sw_if_index))
8858                 rx_sw_if_index_set = 1;
8859             }
8860           else
8861             break;
8862         }
8863       else if (unformat (i, "tx"))
8864         {
8865           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8866             {
8867               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
8868                             &tx_sw_if_index))
8869                 tx_sw_if_index_set = 1;
8870             }
8871           else
8872             break;
8873         }
8874       else if (unformat (i, "del"))
8875         is_add = 0;
8876       else
8877         break;
8878     }
8879
8880   if (rx_sw_if_index_set == 0)
8881     {
8882       errmsg ("missing rx interface name or rx_sw_if_index");
8883       return -99;
8884     }
8885
8886   if (tx_sw_if_index_set == 0)
8887     {
8888       errmsg ("missing tx interface name or tx_sw_if_index");
8889       return -99;
8890     }
8891
8892   M (L2_PATCH_ADD_DEL, mp);
8893
8894   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
8895   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
8896   mp->is_add = is_add;
8897
8898   S (mp);
8899   W (ret);
8900   return ret;
8901 }
8902
8903 u8 is_del;
8904 u8 localsid_addr[16];
8905 u8 end_psp;
8906 u8 behavior;
8907 u32 sw_if_index;
8908 u32 vlan_index;
8909 u32 fib_table;
8910 u8 nh_addr[16];
8911
8912 static int
8913 api_sr_localsid_add_del (vat_main_t * vam)
8914 {
8915   unformat_input_t *i = vam->input;
8916   vl_api_sr_localsid_add_del_t *mp;
8917
8918   u8 is_del;
8919   ip6_address_t localsid;
8920   u8 end_psp = 0;
8921   u8 behavior = ~0;
8922   u32 sw_if_index;
8923   u32 fib_table = ~(u32) 0;
8924   ip6_address_t next_hop;
8925
8926   bool nexthop_set = 0;
8927
8928   int ret;
8929
8930   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8931     {
8932       if (unformat (i, "del"))
8933         is_del = 1;
8934       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
8935       else if (unformat (i, "next-hop %U", unformat_ip6_address, &next_hop))
8936         nexthop_set = 1;
8937       else if (unformat (i, "behavior %u", &behavior));
8938       else if (unformat (i, "sw_if_index %u", &sw_if_index));
8939       else if (unformat (i, "fib-table %u", &fib_table));
8940       else if (unformat (i, "end.psp %u", &behavior));
8941       else
8942         break;
8943     }
8944
8945   M (SR_LOCALSID_ADD_DEL, mp);
8946
8947   clib_memcpy (mp->localsid_addr, &localsid, sizeof (mp->localsid_addr));
8948   if (nexthop_set)
8949     clib_memcpy (mp->nh_addr, &next_hop, sizeof (mp->nh_addr));
8950   mp->behavior = behavior;
8951   mp->sw_if_index = ntohl (sw_if_index);
8952   mp->fib_table = ntohl (fib_table);
8953   mp->end_psp = end_psp;
8954   mp->is_del = is_del;
8955
8956   S (mp);
8957   W (ret);
8958   return ret;
8959 }
8960
8961 static int
8962 api_ioam_enable (vat_main_t * vam)
8963 {
8964   unformat_input_t *input = vam->input;
8965   vl_api_ioam_enable_t *mp;
8966   u32 id = 0;
8967   int has_trace_option = 0;
8968   int has_pot_option = 0;
8969   int has_seqno_option = 0;
8970   int has_analyse_option = 0;
8971   int ret;
8972
8973   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8974     {
8975       if (unformat (input, "trace"))
8976         has_trace_option = 1;
8977       else if (unformat (input, "pot"))
8978         has_pot_option = 1;
8979       else if (unformat (input, "seqno"))
8980         has_seqno_option = 1;
8981       else if (unformat (input, "analyse"))
8982         has_analyse_option = 1;
8983       else
8984         break;
8985     }
8986   M (IOAM_ENABLE, mp);
8987   mp->id = htons (id);
8988   mp->seqno = has_seqno_option;
8989   mp->analyse = has_analyse_option;
8990   mp->pot_enable = has_pot_option;
8991   mp->trace_enable = has_trace_option;
8992
8993   S (mp);
8994   W (ret);
8995   return ret;
8996 }
8997
8998
8999 static int
9000 api_ioam_disable (vat_main_t * vam)
9001 {
9002   vl_api_ioam_disable_t *mp;
9003   int ret;
9004
9005   M (IOAM_DISABLE, mp);
9006   S (mp);
9007   W (ret);
9008   return ret;
9009 }
9010
9011 #define foreach_tcp_proto_field                 \
9012 _(src_port)                                     \
9013 _(dst_port)
9014
9015 #define foreach_udp_proto_field                 \
9016 _(src_port)                                     \
9017 _(dst_port)
9018
9019 #define foreach_ip4_proto_field                 \
9020 _(src_address)                                  \
9021 _(dst_address)                                  \
9022 _(tos)                                          \
9023 _(length)                                       \
9024 _(fragment_id)                                  \
9025 _(ttl)                                          \
9026 _(protocol)                                     \
9027 _(checksum)
9028
9029 typedef struct
9030 {
9031   u16 src_port, dst_port;
9032 } tcpudp_header_t;
9033
9034 #if VPP_API_TEST_BUILTIN == 0
9035 uword
9036 unformat_tcp_mask (unformat_input_t * input, va_list * args)
9037 {
9038   u8 **maskp = va_arg (*args, u8 **);
9039   u8 *mask = 0;
9040   u8 found_something = 0;
9041   tcp_header_t *tcp;
9042
9043 #define _(a) u8 a=0;
9044   foreach_tcp_proto_field;
9045 #undef _
9046
9047   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9048     {
9049       if (0);
9050 #define _(a) else if (unformat (input, #a)) a=1;
9051       foreach_tcp_proto_field
9052 #undef _
9053         else
9054         break;
9055     }
9056
9057 #define _(a) found_something += a;
9058   foreach_tcp_proto_field;
9059 #undef _
9060
9061   if (found_something == 0)
9062     return 0;
9063
9064   vec_validate (mask, sizeof (*tcp) - 1);
9065
9066   tcp = (tcp_header_t *) mask;
9067
9068 #define _(a) if (a) memset (&tcp->a, 0xff, sizeof (tcp->a));
9069   foreach_tcp_proto_field;
9070 #undef _
9071
9072   *maskp = mask;
9073   return 1;
9074 }
9075
9076 uword
9077 unformat_udp_mask (unformat_input_t * input, va_list * args)
9078 {
9079   u8 **maskp = va_arg (*args, u8 **);
9080   u8 *mask = 0;
9081   u8 found_something = 0;
9082   udp_header_t *udp;
9083
9084 #define _(a) u8 a=0;
9085   foreach_udp_proto_field;
9086 #undef _
9087
9088   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9089     {
9090       if (0);
9091 #define _(a) else if (unformat (input, #a)) a=1;
9092       foreach_udp_proto_field
9093 #undef _
9094         else
9095         break;
9096     }
9097
9098 #define _(a) found_something += a;
9099   foreach_udp_proto_field;
9100 #undef _
9101
9102   if (found_something == 0)
9103     return 0;
9104
9105   vec_validate (mask, sizeof (*udp) - 1);
9106
9107   udp = (udp_header_t *) mask;
9108
9109 #define _(a) if (a) memset (&udp->a, 0xff, sizeof (udp->a));
9110   foreach_udp_proto_field;
9111 #undef _
9112
9113   *maskp = mask;
9114   return 1;
9115 }
9116
9117 uword
9118 unformat_l4_mask (unformat_input_t * input, va_list * args)
9119 {
9120   u8 **maskp = va_arg (*args, u8 **);
9121   u16 src_port = 0, dst_port = 0;
9122   tcpudp_header_t *tcpudp;
9123
9124   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9125     {
9126       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
9127         return 1;
9128       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
9129         return 1;
9130       else if (unformat (input, "src_port"))
9131         src_port = 0xFFFF;
9132       else if (unformat (input, "dst_port"))
9133         dst_port = 0xFFFF;
9134       else
9135         return 0;
9136     }
9137
9138   if (!src_port && !dst_port)
9139     return 0;
9140
9141   u8 *mask = 0;
9142   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
9143
9144   tcpudp = (tcpudp_header_t *) mask;
9145   tcpudp->src_port = src_port;
9146   tcpudp->dst_port = dst_port;
9147
9148   *maskp = mask;
9149
9150   return 1;
9151 }
9152
9153 uword
9154 unformat_ip4_mask (unformat_input_t * input, va_list * args)
9155 {
9156   u8 **maskp = va_arg (*args, u8 **);
9157   u8 *mask = 0;
9158   u8 found_something = 0;
9159   ip4_header_t *ip;
9160
9161 #define _(a) u8 a=0;
9162   foreach_ip4_proto_field;
9163 #undef _
9164   u8 version = 0;
9165   u8 hdr_length = 0;
9166
9167
9168   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9169     {
9170       if (unformat (input, "version"))
9171         version = 1;
9172       else if (unformat (input, "hdr_length"))
9173         hdr_length = 1;
9174       else if (unformat (input, "src"))
9175         src_address = 1;
9176       else if (unformat (input, "dst"))
9177         dst_address = 1;
9178       else if (unformat (input, "proto"))
9179         protocol = 1;
9180
9181 #define _(a) else if (unformat (input, #a)) a=1;
9182       foreach_ip4_proto_field
9183 #undef _
9184         else
9185         break;
9186     }
9187
9188 #define _(a) found_something += a;
9189   foreach_ip4_proto_field;
9190 #undef _
9191
9192   if (found_something == 0)
9193     return 0;
9194
9195   vec_validate (mask, sizeof (*ip) - 1);
9196
9197   ip = (ip4_header_t *) mask;
9198
9199 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
9200   foreach_ip4_proto_field;
9201 #undef _
9202
9203   ip->ip_version_and_header_length = 0;
9204
9205   if (version)
9206     ip->ip_version_and_header_length |= 0xF0;
9207
9208   if (hdr_length)
9209     ip->ip_version_and_header_length |= 0x0F;
9210
9211   *maskp = mask;
9212   return 1;
9213 }
9214
9215 #define foreach_ip6_proto_field                 \
9216 _(src_address)                                  \
9217 _(dst_address)                                  \
9218 _(payload_length)                               \
9219 _(hop_limit)                                    \
9220 _(protocol)
9221
9222 uword
9223 unformat_ip6_mask (unformat_input_t * input, va_list * args)
9224 {
9225   u8 **maskp = va_arg (*args, u8 **);
9226   u8 *mask = 0;
9227   u8 found_something = 0;
9228   ip6_header_t *ip;
9229   u32 ip_version_traffic_class_and_flow_label;
9230
9231 #define _(a) u8 a=0;
9232   foreach_ip6_proto_field;
9233 #undef _
9234   u8 version = 0;
9235   u8 traffic_class = 0;
9236   u8 flow_label = 0;
9237
9238   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9239     {
9240       if (unformat (input, "version"))
9241         version = 1;
9242       else if (unformat (input, "traffic-class"))
9243         traffic_class = 1;
9244       else if (unformat (input, "flow-label"))
9245         flow_label = 1;
9246       else if (unformat (input, "src"))
9247         src_address = 1;
9248       else if (unformat (input, "dst"))
9249         dst_address = 1;
9250       else if (unformat (input, "proto"))
9251         protocol = 1;
9252
9253 #define _(a) else if (unformat (input, #a)) a=1;
9254       foreach_ip6_proto_field
9255 #undef _
9256         else
9257         break;
9258     }
9259
9260 #define _(a) found_something += a;
9261   foreach_ip6_proto_field;
9262 #undef _
9263
9264   if (found_something == 0)
9265     return 0;
9266
9267   vec_validate (mask, sizeof (*ip) - 1);
9268
9269   ip = (ip6_header_t *) mask;
9270
9271 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
9272   foreach_ip6_proto_field;
9273 #undef _
9274
9275   ip_version_traffic_class_and_flow_label = 0;
9276
9277   if (version)
9278     ip_version_traffic_class_and_flow_label |= 0xF0000000;
9279
9280   if (traffic_class)
9281     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
9282
9283   if (flow_label)
9284     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
9285
9286   ip->ip_version_traffic_class_and_flow_label =
9287     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
9288
9289   *maskp = mask;
9290   return 1;
9291 }
9292
9293 uword
9294 unformat_l3_mask (unformat_input_t * input, va_list * args)
9295 {
9296   u8 **maskp = va_arg (*args, u8 **);
9297
9298   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9299     {
9300       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
9301         return 1;
9302       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
9303         return 1;
9304       else
9305         break;
9306     }
9307   return 0;
9308 }
9309
9310 uword
9311 unformat_l2_mask (unformat_input_t * input, va_list * args)
9312 {
9313   u8 **maskp = va_arg (*args, u8 **);
9314   u8 *mask = 0;
9315   u8 src = 0;
9316   u8 dst = 0;
9317   u8 proto = 0;
9318   u8 tag1 = 0;
9319   u8 tag2 = 0;
9320   u8 ignore_tag1 = 0;
9321   u8 ignore_tag2 = 0;
9322   u8 cos1 = 0;
9323   u8 cos2 = 0;
9324   u8 dot1q = 0;
9325   u8 dot1ad = 0;
9326   int len = 14;
9327
9328   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9329     {
9330       if (unformat (input, "src"))
9331         src = 1;
9332       else if (unformat (input, "dst"))
9333         dst = 1;
9334       else if (unformat (input, "proto"))
9335         proto = 1;
9336       else if (unformat (input, "tag1"))
9337         tag1 = 1;
9338       else if (unformat (input, "tag2"))
9339         tag2 = 1;
9340       else if (unformat (input, "ignore-tag1"))
9341         ignore_tag1 = 1;
9342       else if (unformat (input, "ignore-tag2"))
9343         ignore_tag2 = 1;
9344       else if (unformat (input, "cos1"))
9345         cos1 = 1;
9346       else if (unformat (input, "cos2"))
9347         cos2 = 1;
9348       else if (unformat (input, "dot1q"))
9349         dot1q = 1;
9350       else if (unformat (input, "dot1ad"))
9351         dot1ad = 1;
9352       else
9353         break;
9354     }
9355   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
9356        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
9357     return 0;
9358
9359   if (tag1 || ignore_tag1 || cos1 || dot1q)
9360     len = 18;
9361   if (tag2 || ignore_tag2 || cos2 || dot1ad)
9362     len = 22;
9363
9364   vec_validate (mask, len - 1);
9365
9366   if (dst)
9367     memset (mask, 0xff, 6);
9368
9369   if (src)
9370     memset (mask + 6, 0xff, 6);
9371
9372   if (tag2 || dot1ad)
9373     {
9374       /* inner vlan tag */
9375       if (tag2)
9376         {
9377           mask[19] = 0xff;
9378           mask[18] = 0x0f;
9379         }
9380       if (cos2)
9381         mask[18] |= 0xe0;
9382       if (proto)
9383         mask[21] = mask[20] = 0xff;
9384       if (tag1)
9385         {
9386           mask[15] = 0xff;
9387           mask[14] = 0x0f;
9388         }
9389       if (cos1)
9390         mask[14] |= 0xe0;
9391       *maskp = mask;
9392       return 1;
9393     }
9394   if (tag1 | dot1q)
9395     {
9396       if (tag1)
9397         {
9398           mask[15] = 0xff;
9399           mask[14] = 0x0f;
9400         }
9401       if (cos1)
9402         mask[14] |= 0xe0;
9403       if (proto)
9404         mask[16] = mask[17] = 0xff;
9405
9406       *maskp = mask;
9407       return 1;
9408     }
9409   if (cos2)
9410     mask[18] |= 0xe0;
9411   if (cos1)
9412     mask[14] |= 0xe0;
9413   if (proto)
9414     mask[12] = mask[13] = 0xff;
9415
9416   *maskp = mask;
9417   return 1;
9418 }
9419
9420 uword
9421 unformat_classify_mask (unformat_input_t * input, va_list * args)
9422 {
9423   u8 **maskp = va_arg (*args, u8 **);
9424   u32 *skipp = va_arg (*args, u32 *);
9425   u32 *matchp = va_arg (*args, u32 *);
9426   u32 match;
9427   u8 *mask = 0;
9428   u8 *l2 = 0;
9429   u8 *l3 = 0;
9430   u8 *l4 = 0;
9431   int i;
9432
9433   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9434     {
9435       if (unformat (input, "hex %U", unformat_hex_string, &mask))
9436         ;
9437       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
9438         ;
9439       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
9440         ;
9441       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
9442         ;
9443       else
9444         break;
9445     }
9446
9447   if (l4 && !l3)
9448     {
9449       vec_free (mask);
9450       vec_free (l2);
9451       vec_free (l4);
9452       return 0;
9453     }
9454
9455   if (mask || l2 || l3 || l4)
9456     {
9457       if (l2 || l3 || l4)
9458         {
9459           /* "With a free Ethernet header in every package" */
9460           if (l2 == 0)
9461             vec_validate (l2, 13);
9462           mask = l2;
9463           if (vec_len (l3))
9464             {
9465               vec_append (mask, l3);
9466               vec_free (l3);
9467             }
9468           if (vec_len (l4))
9469             {
9470               vec_append (mask, l4);
9471               vec_free (l4);
9472             }
9473         }
9474
9475       /* Scan forward looking for the first significant mask octet */
9476       for (i = 0; i < vec_len (mask); i++)
9477         if (mask[i])
9478           break;
9479
9480       /* compute (skip, match) params */
9481       *skipp = i / sizeof (u32x4);
9482       vec_delete (mask, *skipp * sizeof (u32x4), 0);
9483
9484       /* Pad mask to an even multiple of the vector size */
9485       while (vec_len (mask) % sizeof (u32x4))
9486         vec_add1 (mask, 0);
9487
9488       match = vec_len (mask) / sizeof (u32x4);
9489
9490       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
9491         {
9492           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
9493           if (*tmp || *(tmp + 1))
9494             break;
9495           match--;
9496         }
9497       if (match == 0)
9498         clib_warning ("BUG: match 0");
9499
9500       _vec_len (mask) = match * sizeof (u32x4);
9501
9502       *matchp = match;
9503       *maskp = mask;
9504
9505       return 1;
9506     }
9507
9508   return 0;
9509 }
9510 #endif /* VPP_API_TEST_BUILTIN */
9511
9512 #define foreach_l2_next                         \
9513 _(drop, DROP)                                   \
9514 _(ethernet, ETHERNET_INPUT)                     \
9515 _(ip4, IP4_INPUT)                               \
9516 _(ip6, IP6_INPUT)
9517
9518 uword
9519 unformat_l2_next_index (unformat_input_t * input, va_list * args)
9520 {
9521   u32 *miss_next_indexp = va_arg (*args, u32 *);
9522   u32 next_index = 0;
9523   u32 tmp;
9524
9525 #define _(n,N) \
9526   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
9527   foreach_l2_next;
9528 #undef _
9529
9530   if (unformat (input, "%d", &tmp))
9531     {
9532       next_index = tmp;
9533       goto out;
9534     }
9535
9536   return 0;
9537
9538 out:
9539   *miss_next_indexp = next_index;
9540   return 1;
9541 }
9542
9543 #define foreach_ip_next                         \
9544 _(drop, DROP)                                   \
9545 _(local, LOCAL)                                 \
9546 _(rewrite, REWRITE)
9547
9548 uword
9549 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
9550 {
9551   u32 *miss_next_indexp = va_arg (*args, u32 *);
9552   u32 next_index = 0;
9553   u32 tmp;
9554
9555 #define _(n,N) \
9556   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
9557   foreach_ip_next;
9558 #undef _
9559
9560   if (unformat (input, "%d", &tmp))
9561     {
9562       next_index = tmp;
9563       goto out;
9564     }
9565
9566   return 0;
9567
9568 out:
9569   *miss_next_indexp = next_index;
9570   return 1;
9571 }
9572
9573 #define foreach_acl_next                        \
9574 _(deny, DENY)
9575
9576 uword
9577 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
9578 {
9579   u32 *miss_next_indexp = va_arg (*args, u32 *);
9580   u32 next_index = 0;
9581   u32 tmp;
9582
9583 #define _(n,N) \
9584   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
9585   foreach_acl_next;
9586 #undef _
9587
9588   if (unformat (input, "permit"))
9589     {
9590       next_index = ~0;
9591       goto out;
9592     }
9593   else if (unformat (input, "%d", &tmp))
9594     {
9595       next_index = tmp;
9596       goto out;
9597     }
9598
9599   return 0;
9600
9601 out:
9602   *miss_next_indexp = next_index;
9603   return 1;
9604 }
9605
9606 uword
9607 unformat_policer_precolor (unformat_input_t * input, va_list * args)
9608 {
9609   u32 *r = va_arg (*args, u32 *);
9610
9611   if (unformat (input, "conform-color"))
9612     *r = POLICE_CONFORM;
9613   else if (unformat (input, "exceed-color"))
9614     *r = POLICE_EXCEED;
9615   else
9616     return 0;
9617
9618   return 1;
9619 }
9620
9621 static int
9622 api_classify_add_del_table (vat_main_t * vam)
9623 {
9624   unformat_input_t *i = vam->input;
9625   vl_api_classify_add_del_table_t *mp;
9626
9627   u32 nbuckets = 2;
9628   u32 skip = ~0;
9629   u32 match = ~0;
9630   int is_add = 1;
9631   int del_chain = 0;
9632   u32 table_index = ~0;
9633   u32 next_table_index = ~0;
9634   u32 miss_next_index = ~0;
9635   u32 memory_size = 32 << 20;
9636   u8 *mask = 0;
9637   u32 current_data_flag = 0;
9638   int current_data_offset = 0;
9639   int ret;
9640
9641   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9642     {
9643       if (unformat (i, "del"))
9644         is_add = 0;
9645       else if (unformat (i, "del-chain"))
9646         {
9647           is_add = 0;
9648           del_chain = 1;
9649         }
9650       else if (unformat (i, "buckets %d", &nbuckets))
9651         ;
9652       else if (unformat (i, "memory_size %d", &memory_size))
9653         ;
9654       else if (unformat (i, "skip %d", &skip))
9655         ;
9656       else if (unformat (i, "match %d", &match))
9657         ;
9658       else if (unformat (i, "table %d", &table_index))
9659         ;
9660       else if (unformat (i, "mask %U", unformat_classify_mask,
9661                          &mask, &skip, &match))
9662         ;
9663       else if (unformat (i, "next-table %d", &next_table_index))
9664         ;
9665       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
9666                          &miss_next_index))
9667         ;
9668       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
9669                          &miss_next_index))
9670         ;
9671       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
9672                          &miss_next_index))
9673         ;
9674       else if (unformat (i, "current-data-flag %d", &current_data_flag))
9675         ;
9676       else if (unformat (i, "current-data-offset %d", &current_data_offset))
9677         ;
9678       else
9679         break;
9680     }
9681
9682   if (is_add && mask == 0)
9683     {
9684       errmsg ("Mask required");
9685       return -99;
9686     }
9687
9688   if (is_add && skip == ~0)
9689     {
9690       errmsg ("skip count required");
9691       return -99;
9692     }
9693
9694   if (is_add && match == ~0)
9695     {
9696       errmsg ("match count required");
9697       return -99;
9698     }
9699
9700   if (!is_add && table_index == ~0)
9701     {
9702       errmsg ("table index required for delete");
9703       return -99;
9704     }
9705
9706   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
9707
9708   mp->is_add = is_add;
9709   mp->del_chain = del_chain;
9710   mp->table_index = ntohl (table_index);
9711   mp->nbuckets = ntohl (nbuckets);
9712   mp->memory_size = ntohl (memory_size);
9713   mp->skip_n_vectors = ntohl (skip);
9714   mp->match_n_vectors = ntohl (match);
9715   mp->next_table_index = ntohl (next_table_index);
9716   mp->miss_next_index = ntohl (miss_next_index);
9717   mp->current_data_flag = ntohl (current_data_flag);
9718   mp->current_data_offset = ntohl (current_data_offset);
9719   clib_memcpy (mp->mask, mask, vec_len (mask));
9720
9721   vec_free (mask);
9722
9723   S (mp);
9724   W (ret);
9725   return ret;
9726 }
9727
9728 #if VPP_API_TEST_BUILTIN == 0
9729 uword
9730 unformat_l4_match (unformat_input_t * input, va_list * args)
9731 {
9732   u8 **matchp = va_arg (*args, u8 **);
9733
9734   u8 *proto_header = 0;
9735   int src_port = 0;
9736   int dst_port = 0;
9737
9738   tcpudp_header_t h;
9739
9740   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9741     {
9742       if (unformat (input, "src_port %d", &src_port))
9743         ;
9744       else if (unformat (input, "dst_port %d", &dst_port))
9745         ;
9746       else
9747         return 0;
9748     }
9749
9750   h.src_port = clib_host_to_net_u16 (src_port);
9751   h.dst_port = clib_host_to_net_u16 (dst_port);
9752   vec_validate (proto_header, sizeof (h) - 1);
9753   memcpy (proto_header, &h, sizeof (h));
9754
9755   *matchp = proto_header;
9756
9757   return 1;
9758 }
9759
9760 uword
9761 unformat_ip4_match (unformat_input_t * input, va_list * args)
9762 {
9763   u8 **matchp = va_arg (*args, u8 **);
9764   u8 *match = 0;
9765   ip4_header_t *ip;
9766   int version = 0;
9767   u32 version_val;
9768   int hdr_length = 0;
9769   u32 hdr_length_val;
9770   int src = 0, dst = 0;
9771   ip4_address_t src_val, dst_val;
9772   int proto = 0;
9773   u32 proto_val;
9774   int tos = 0;
9775   u32 tos_val;
9776   int length = 0;
9777   u32 length_val;
9778   int fragment_id = 0;
9779   u32 fragment_id_val;
9780   int ttl = 0;
9781   int ttl_val;
9782   int checksum = 0;
9783   u32 checksum_val;
9784
9785   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9786     {
9787       if (unformat (input, "version %d", &version_val))
9788         version = 1;
9789       else if (unformat (input, "hdr_length %d", &hdr_length_val))
9790         hdr_length = 1;
9791       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
9792         src = 1;
9793       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
9794         dst = 1;
9795       else if (unformat (input, "proto %d", &proto_val))
9796         proto = 1;
9797       else if (unformat (input, "tos %d", &tos_val))
9798         tos = 1;
9799       else if (unformat (input, "length %d", &length_val))
9800         length = 1;
9801       else if (unformat (input, "fragment_id %d", &fragment_id_val))
9802         fragment_id = 1;
9803       else if (unformat (input, "ttl %d", &ttl_val))
9804         ttl = 1;
9805       else if (unformat (input, "checksum %d", &checksum_val))
9806         checksum = 1;
9807       else
9808         break;
9809     }
9810
9811   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
9812       + ttl + checksum == 0)
9813     return 0;
9814
9815   /*
9816    * Aligned because we use the real comparison functions
9817    */
9818   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
9819
9820   ip = (ip4_header_t *) match;
9821
9822   /* These are realistically matched in practice */
9823   if (src)
9824     ip->src_address.as_u32 = src_val.as_u32;
9825
9826   if (dst)
9827     ip->dst_address.as_u32 = dst_val.as_u32;
9828
9829   if (proto)
9830     ip->protocol = proto_val;
9831
9832
9833   /* These are not, but they're included for completeness */
9834   if (version)
9835     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
9836
9837   if (hdr_length)
9838     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
9839
9840   if (tos)
9841     ip->tos = tos_val;
9842
9843   if (length)
9844     ip->length = clib_host_to_net_u16 (length_val);
9845
9846   if (ttl)
9847     ip->ttl = ttl_val;
9848
9849   if (checksum)
9850     ip->checksum = clib_host_to_net_u16 (checksum_val);
9851
9852   *matchp = match;
9853   return 1;
9854 }
9855
9856 uword
9857 unformat_ip6_match (unformat_input_t * input, va_list * args)
9858 {
9859   u8 **matchp = va_arg (*args, u8 **);
9860   u8 *match = 0;
9861   ip6_header_t *ip;
9862   int version = 0;
9863   u32 version_val;
9864   u8 traffic_class = 0;
9865   u32 traffic_class_val = 0;
9866   u8 flow_label = 0;
9867   u8 flow_label_val;
9868   int src = 0, dst = 0;
9869   ip6_address_t src_val, dst_val;
9870   int proto = 0;
9871   u32 proto_val;
9872   int payload_length = 0;
9873   u32 payload_length_val;
9874   int hop_limit = 0;
9875   int hop_limit_val;
9876   u32 ip_version_traffic_class_and_flow_label;
9877
9878   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9879     {
9880       if (unformat (input, "version %d", &version_val))
9881         version = 1;
9882       else if (unformat (input, "traffic_class %d", &traffic_class_val))
9883         traffic_class = 1;
9884       else if (unformat (input, "flow_label %d", &flow_label_val))
9885         flow_label = 1;
9886       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
9887         src = 1;
9888       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
9889         dst = 1;
9890       else if (unformat (input, "proto %d", &proto_val))
9891         proto = 1;
9892       else if (unformat (input, "payload_length %d", &payload_length_val))
9893         payload_length = 1;
9894       else if (unformat (input, "hop_limit %d", &hop_limit_val))
9895         hop_limit = 1;
9896       else
9897         break;
9898     }
9899
9900   if (version + traffic_class + flow_label + src + dst + proto +
9901       payload_length + hop_limit == 0)
9902     return 0;
9903
9904   /*
9905    * Aligned because we use the real comparison functions
9906    */
9907   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
9908
9909   ip = (ip6_header_t *) match;
9910
9911   if (src)
9912     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
9913
9914   if (dst)
9915     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
9916
9917   if (proto)
9918     ip->protocol = proto_val;
9919
9920   ip_version_traffic_class_and_flow_label = 0;
9921
9922   if (version)
9923     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
9924
9925   if (traffic_class)
9926     ip_version_traffic_class_and_flow_label |=
9927       (traffic_class_val & 0xFF) << 20;
9928
9929   if (flow_label)
9930     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
9931
9932   ip->ip_version_traffic_class_and_flow_label =
9933     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
9934
9935   if (payload_length)
9936     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
9937
9938   if (hop_limit)
9939     ip->hop_limit = hop_limit_val;
9940
9941   *matchp = match;
9942   return 1;
9943 }
9944
9945 uword
9946 unformat_l3_match (unformat_input_t * input, va_list * args)
9947 {
9948   u8 **matchp = va_arg (*args, u8 **);
9949
9950   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9951     {
9952       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
9953         return 1;
9954       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
9955         return 1;
9956       else
9957         break;
9958     }
9959   return 0;
9960 }
9961
9962 uword
9963 unformat_vlan_tag (unformat_input_t * input, va_list * args)
9964 {
9965   u8 *tagp = va_arg (*args, u8 *);
9966   u32 tag;
9967
9968   if (unformat (input, "%d", &tag))
9969     {
9970       tagp[0] = (tag >> 8) & 0x0F;
9971       tagp[1] = tag & 0xFF;
9972       return 1;
9973     }
9974
9975   return 0;
9976 }
9977
9978 uword
9979 unformat_l2_match (unformat_input_t * input, va_list * args)
9980 {
9981   u8 **matchp = va_arg (*args, u8 **);
9982   u8 *match = 0;
9983   u8 src = 0;
9984   u8 src_val[6];
9985   u8 dst = 0;
9986   u8 dst_val[6];
9987   u8 proto = 0;
9988   u16 proto_val;
9989   u8 tag1 = 0;
9990   u8 tag1_val[2];
9991   u8 tag2 = 0;
9992   u8 tag2_val[2];
9993   int len = 14;
9994   u8 ignore_tag1 = 0;
9995   u8 ignore_tag2 = 0;
9996   u8 cos1 = 0;
9997   u8 cos2 = 0;
9998   u32 cos1_val = 0;
9999   u32 cos2_val = 0;
10000
10001   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10002     {
10003       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
10004         src = 1;
10005       else
10006         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
10007         dst = 1;
10008       else if (unformat (input, "proto %U",
10009                          unformat_ethernet_type_host_byte_order, &proto_val))
10010         proto = 1;
10011       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
10012         tag1 = 1;
10013       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
10014         tag2 = 1;
10015       else if (unformat (input, "ignore-tag1"))
10016         ignore_tag1 = 1;
10017       else if (unformat (input, "ignore-tag2"))
10018         ignore_tag2 = 1;
10019       else if (unformat (input, "cos1 %d", &cos1_val))
10020         cos1 = 1;
10021       else if (unformat (input, "cos2 %d", &cos2_val))
10022         cos2 = 1;
10023       else
10024         break;
10025     }
10026   if ((src + dst + proto + tag1 + tag2 +
10027        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
10028     return 0;
10029
10030   if (tag1 || ignore_tag1 || cos1)
10031     len = 18;
10032   if (tag2 || ignore_tag2 || cos2)
10033     len = 22;
10034
10035   vec_validate_aligned (match, len - 1, sizeof (u32x4));
10036
10037   if (dst)
10038     clib_memcpy (match, dst_val, 6);
10039
10040   if (src)
10041     clib_memcpy (match + 6, src_val, 6);
10042
10043   if (tag2)
10044     {
10045       /* inner vlan tag */
10046       match[19] = tag2_val[1];
10047       match[18] = tag2_val[0];
10048       if (cos2)
10049         match[18] |= (cos2_val & 0x7) << 5;
10050       if (proto)
10051         {
10052           match[21] = proto_val & 0xff;
10053           match[20] = proto_val >> 8;
10054         }
10055       if (tag1)
10056         {
10057           match[15] = tag1_val[1];
10058           match[14] = tag1_val[0];
10059         }
10060       if (cos1)
10061         match[14] |= (cos1_val & 0x7) << 5;
10062       *matchp = match;
10063       return 1;
10064     }
10065   if (tag1)
10066     {
10067       match[15] = tag1_val[1];
10068       match[14] = tag1_val[0];
10069       if (proto)
10070         {
10071           match[17] = proto_val & 0xff;
10072           match[16] = proto_val >> 8;
10073         }
10074       if (cos1)
10075         match[14] |= (cos1_val & 0x7) << 5;
10076
10077       *matchp = match;
10078       return 1;
10079     }
10080   if (cos2)
10081     match[18] |= (cos2_val & 0x7) << 5;
10082   if (cos1)
10083     match[14] |= (cos1_val & 0x7) << 5;
10084   if (proto)
10085     {
10086       match[13] = proto_val & 0xff;
10087       match[12] = proto_val >> 8;
10088     }
10089
10090   *matchp = match;
10091   return 1;
10092 }
10093 #endif
10094
10095 uword
10096 api_unformat_classify_match (unformat_input_t * input, va_list * args)
10097 {
10098   u8 **matchp = va_arg (*args, u8 **);
10099   u32 skip_n_vectors = va_arg (*args, u32);
10100   u32 match_n_vectors = va_arg (*args, u32);
10101
10102   u8 *match = 0;
10103   u8 *l2 = 0;
10104   u8 *l3 = 0;
10105   u8 *l4 = 0;
10106
10107   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10108     {
10109       if (unformat (input, "hex %U", unformat_hex_string, &match))
10110         ;
10111       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
10112         ;
10113       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
10114         ;
10115       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
10116         ;
10117       else
10118         break;
10119     }
10120
10121   if (l4 && !l3)
10122     {
10123       vec_free (match);
10124       vec_free (l2);
10125       vec_free (l4);
10126       return 0;
10127     }
10128
10129   if (match || l2 || l3 || l4)
10130     {
10131       if (l2 || l3 || l4)
10132         {
10133           /* "Win a free Ethernet header in every packet" */
10134           if (l2 == 0)
10135             vec_validate_aligned (l2, 13, sizeof (u32x4));
10136           match = l2;
10137           if (vec_len (l3))
10138             {
10139               vec_append_aligned (match, l3, sizeof (u32x4));
10140               vec_free (l3);
10141             }
10142           if (vec_len (l4))
10143             {
10144               vec_append_aligned (match, l4, sizeof (u32x4));
10145               vec_free (l4);
10146             }
10147         }
10148
10149       /* Make sure the vector is big enough even if key is all 0's */
10150       vec_validate_aligned
10151         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
10152          sizeof (u32x4));
10153
10154       /* Set size, include skipped vectors */
10155       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
10156
10157       *matchp = match;
10158
10159       return 1;
10160     }
10161
10162   return 0;
10163 }
10164
10165 static int
10166 api_classify_add_del_session (vat_main_t * vam)
10167 {
10168   unformat_input_t *i = vam->input;
10169   vl_api_classify_add_del_session_t *mp;
10170   int is_add = 1;
10171   u32 table_index = ~0;
10172   u32 hit_next_index = ~0;
10173   u32 opaque_index = ~0;
10174   u8 *match = 0;
10175   i32 advance = 0;
10176   u32 skip_n_vectors = 0;
10177   u32 match_n_vectors = 0;
10178   u32 action = 0;
10179   u32 metadata = 0;
10180   int ret;
10181
10182   /*
10183    * Warning: you have to supply skip_n and match_n
10184    * because the API client cant simply look at the classify
10185    * table object.
10186    */
10187
10188   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10189     {
10190       if (unformat (i, "del"))
10191         is_add = 0;
10192       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
10193                          &hit_next_index))
10194         ;
10195       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
10196                          &hit_next_index))
10197         ;
10198       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
10199                          &hit_next_index))
10200         ;
10201       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
10202         ;
10203       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
10204         ;
10205       else if (unformat (i, "opaque-index %d", &opaque_index))
10206         ;
10207       else if (unformat (i, "skip_n %d", &skip_n_vectors))
10208         ;
10209       else if (unformat (i, "match_n %d", &match_n_vectors))
10210         ;
10211       else if (unformat (i, "match %U", api_unformat_classify_match,
10212                          &match, skip_n_vectors, match_n_vectors))
10213         ;
10214       else if (unformat (i, "advance %d", &advance))
10215         ;
10216       else if (unformat (i, "table-index %d", &table_index))
10217         ;
10218       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
10219         action = 1;
10220       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
10221         action = 2;
10222       else if (unformat (i, "action %d", &action))
10223         ;
10224       else if (unformat (i, "metadata %d", &metadata))
10225         ;
10226       else
10227         break;
10228     }
10229
10230   if (table_index == ~0)
10231     {
10232       errmsg ("Table index required");
10233       return -99;
10234     }
10235
10236   if (is_add && match == 0)
10237     {
10238       errmsg ("Match value required");
10239       return -99;
10240     }
10241
10242   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
10243
10244   mp->is_add = is_add;
10245   mp->table_index = ntohl (table_index);
10246   mp->hit_next_index = ntohl (hit_next_index);
10247   mp->opaque_index = ntohl (opaque_index);
10248   mp->advance = ntohl (advance);
10249   mp->action = action;
10250   mp->metadata = ntohl (metadata);
10251   clib_memcpy (mp->match, match, vec_len (match));
10252   vec_free (match);
10253
10254   S (mp);
10255   W (ret);
10256   return ret;
10257 }
10258
10259 static int
10260 api_classify_set_interface_ip_table (vat_main_t * vam)
10261 {
10262   unformat_input_t *i = vam->input;
10263   vl_api_classify_set_interface_ip_table_t *mp;
10264   u32 sw_if_index;
10265   int sw_if_index_set;
10266   u32 table_index = ~0;
10267   u8 is_ipv6 = 0;
10268   int ret;
10269
10270   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10271     {
10272       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10273         sw_if_index_set = 1;
10274       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10275         sw_if_index_set = 1;
10276       else if (unformat (i, "table %d", &table_index))
10277         ;
10278       else
10279         {
10280           clib_warning ("parse error '%U'", format_unformat_error, i);
10281           return -99;
10282         }
10283     }
10284
10285   if (sw_if_index_set == 0)
10286     {
10287       errmsg ("missing interface name or sw_if_index");
10288       return -99;
10289     }
10290
10291
10292   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
10293
10294   mp->sw_if_index = ntohl (sw_if_index);
10295   mp->table_index = ntohl (table_index);
10296   mp->is_ipv6 = is_ipv6;
10297
10298   S (mp);
10299   W (ret);
10300   return ret;
10301 }
10302
10303 static int
10304 api_classify_set_interface_l2_tables (vat_main_t * vam)
10305 {
10306   unformat_input_t *i = vam->input;
10307   vl_api_classify_set_interface_l2_tables_t *mp;
10308   u32 sw_if_index;
10309   int sw_if_index_set;
10310   u32 ip4_table_index = ~0;
10311   u32 ip6_table_index = ~0;
10312   u32 other_table_index = ~0;
10313   u32 is_input = 1;
10314   int ret;
10315
10316   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10317     {
10318       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10319         sw_if_index_set = 1;
10320       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10321         sw_if_index_set = 1;
10322       else if (unformat (i, "ip4-table %d", &ip4_table_index))
10323         ;
10324       else if (unformat (i, "ip6-table %d", &ip6_table_index))
10325         ;
10326       else if (unformat (i, "other-table %d", &other_table_index))
10327         ;
10328       else if (unformat (i, "is-input %d", &is_input))
10329         ;
10330       else
10331         {
10332           clib_warning ("parse error '%U'", format_unformat_error, i);
10333           return -99;
10334         }
10335     }
10336
10337   if (sw_if_index_set == 0)
10338     {
10339       errmsg ("missing interface name or sw_if_index");
10340       return -99;
10341     }
10342
10343
10344   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
10345
10346   mp->sw_if_index = ntohl (sw_if_index);
10347   mp->ip4_table_index = ntohl (ip4_table_index);
10348   mp->ip6_table_index = ntohl (ip6_table_index);
10349   mp->other_table_index = ntohl (other_table_index);
10350   mp->is_input = (u8) is_input;
10351
10352   S (mp);
10353   W (ret);
10354   return ret;
10355 }
10356
10357 static int
10358 api_set_ipfix_exporter (vat_main_t * vam)
10359 {
10360   unformat_input_t *i = vam->input;
10361   vl_api_set_ipfix_exporter_t *mp;
10362   ip4_address_t collector_address;
10363   u8 collector_address_set = 0;
10364   u32 collector_port = ~0;
10365   ip4_address_t src_address;
10366   u8 src_address_set = 0;
10367   u32 vrf_id = ~0;
10368   u32 path_mtu = ~0;
10369   u32 template_interval = ~0;
10370   u8 udp_checksum = 0;
10371   int ret;
10372
10373   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10374     {
10375       if (unformat (i, "collector_address %U", unformat_ip4_address,
10376                     &collector_address))
10377         collector_address_set = 1;
10378       else if (unformat (i, "collector_port %d", &collector_port))
10379         ;
10380       else if (unformat (i, "src_address %U", unformat_ip4_address,
10381                          &src_address))
10382         src_address_set = 1;
10383       else if (unformat (i, "vrf_id %d", &vrf_id))
10384         ;
10385       else if (unformat (i, "path_mtu %d", &path_mtu))
10386         ;
10387       else if (unformat (i, "template_interval %d", &template_interval))
10388         ;
10389       else if (unformat (i, "udp_checksum"))
10390         udp_checksum = 1;
10391       else
10392         break;
10393     }
10394
10395   if (collector_address_set == 0)
10396     {
10397       errmsg ("collector_address required");
10398       return -99;
10399     }
10400
10401   if (src_address_set == 0)
10402     {
10403       errmsg ("src_address required");
10404       return -99;
10405     }
10406
10407   M (SET_IPFIX_EXPORTER, mp);
10408
10409   memcpy (mp->collector_address, collector_address.data,
10410           sizeof (collector_address.data));
10411   mp->collector_port = htons ((u16) collector_port);
10412   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
10413   mp->vrf_id = htonl (vrf_id);
10414   mp->path_mtu = htonl (path_mtu);
10415   mp->template_interval = htonl (template_interval);
10416   mp->udp_checksum = udp_checksum;
10417
10418   S (mp);
10419   W (ret);
10420   return ret;
10421 }
10422
10423 static int
10424 api_set_ipfix_classify_stream (vat_main_t * vam)
10425 {
10426   unformat_input_t *i = vam->input;
10427   vl_api_set_ipfix_classify_stream_t *mp;
10428   u32 domain_id = 0;
10429   u32 src_port = UDP_DST_PORT_ipfix;
10430   int ret;
10431
10432   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10433     {
10434       if (unformat (i, "domain %d", &domain_id))
10435         ;
10436       else if (unformat (i, "src_port %d", &src_port))
10437         ;
10438       else
10439         {
10440           errmsg ("unknown input `%U'", format_unformat_error, i);
10441           return -99;
10442         }
10443     }
10444
10445   M (SET_IPFIX_CLASSIFY_STREAM, mp);
10446
10447   mp->domain_id = htonl (domain_id);
10448   mp->src_port = htons ((u16) src_port);
10449
10450   S (mp);
10451   W (ret);
10452   return ret;
10453 }
10454
10455 static int
10456 api_ipfix_classify_table_add_del (vat_main_t * vam)
10457 {
10458   unformat_input_t *i = vam->input;
10459   vl_api_ipfix_classify_table_add_del_t *mp;
10460   int is_add = -1;
10461   u32 classify_table_index = ~0;
10462   u8 ip_version = 0;
10463   u8 transport_protocol = 255;
10464   int ret;
10465
10466   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10467     {
10468       if (unformat (i, "add"))
10469         is_add = 1;
10470       else if (unformat (i, "del"))
10471         is_add = 0;
10472       else if (unformat (i, "table %d", &classify_table_index))
10473         ;
10474       else if (unformat (i, "ip4"))
10475         ip_version = 4;
10476       else if (unformat (i, "ip6"))
10477         ip_version = 6;
10478       else if (unformat (i, "tcp"))
10479         transport_protocol = 6;
10480       else if (unformat (i, "udp"))
10481         transport_protocol = 17;
10482       else
10483         {
10484           errmsg ("unknown input `%U'", format_unformat_error, i);
10485           return -99;
10486         }
10487     }
10488
10489   if (is_add == -1)
10490     {
10491       errmsg ("expecting: add|del");
10492       return -99;
10493     }
10494   if (classify_table_index == ~0)
10495     {
10496       errmsg ("classifier table not specified");
10497       return -99;
10498     }
10499   if (ip_version == 0)
10500     {
10501       errmsg ("IP version not specified");
10502       return -99;
10503     }
10504
10505   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
10506
10507   mp->is_add = is_add;
10508   mp->table_id = htonl (classify_table_index);
10509   mp->ip_version = ip_version;
10510   mp->transport_protocol = transport_protocol;
10511
10512   S (mp);
10513   W (ret);
10514   return ret;
10515 }
10516
10517 static int
10518 api_get_node_index (vat_main_t * vam)
10519 {
10520   unformat_input_t *i = vam->input;
10521   vl_api_get_node_index_t *mp;
10522   u8 *name = 0;
10523   int ret;
10524
10525   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10526     {
10527       if (unformat (i, "node %s", &name))
10528         ;
10529       else
10530         break;
10531     }
10532   if (name == 0)
10533     {
10534       errmsg ("node name required");
10535       return -99;
10536     }
10537   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
10538     {
10539       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10540       return -99;
10541     }
10542
10543   M (GET_NODE_INDEX, mp);
10544   clib_memcpy (mp->node_name, name, vec_len (name));
10545   vec_free (name);
10546
10547   S (mp);
10548   W (ret);
10549   return ret;
10550 }
10551
10552 static int
10553 api_get_next_index (vat_main_t * vam)
10554 {
10555   unformat_input_t *i = vam->input;
10556   vl_api_get_next_index_t *mp;
10557   u8 *node_name = 0, *next_node_name = 0;
10558   int ret;
10559
10560   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10561     {
10562       if (unformat (i, "node-name %s", &node_name))
10563         ;
10564       else if (unformat (i, "next-node-name %s", &next_node_name))
10565         break;
10566     }
10567
10568   if (node_name == 0)
10569     {
10570       errmsg ("node name required");
10571       return -99;
10572     }
10573   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
10574     {
10575       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10576       return -99;
10577     }
10578
10579   if (next_node_name == 0)
10580     {
10581       errmsg ("next node name required");
10582       return -99;
10583     }
10584   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
10585     {
10586       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
10587       return -99;
10588     }
10589
10590   M (GET_NEXT_INDEX, mp);
10591   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
10592   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
10593   vec_free (node_name);
10594   vec_free (next_node_name);
10595
10596   S (mp);
10597   W (ret);
10598   return ret;
10599 }
10600
10601 static int
10602 api_add_node_next (vat_main_t * vam)
10603 {
10604   unformat_input_t *i = vam->input;
10605   vl_api_add_node_next_t *mp;
10606   u8 *name = 0;
10607   u8 *next = 0;
10608   int ret;
10609
10610   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10611     {
10612       if (unformat (i, "node %s", &name))
10613         ;
10614       else if (unformat (i, "next %s", &next))
10615         ;
10616       else
10617         break;
10618     }
10619   if (name == 0)
10620     {
10621       errmsg ("node name required");
10622       return -99;
10623     }
10624   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
10625     {
10626       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10627       return -99;
10628     }
10629   if (next == 0)
10630     {
10631       errmsg ("next node required");
10632       return -99;
10633     }
10634   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
10635     {
10636       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
10637       return -99;
10638     }
10639
10640   M (ADD_NODE_NEXT, mp);
10641   clib_memcpy (mp->node_name, name, vec_len (name));
10642   clib_memcpy (mp->next_name, next, vec_len (next));
10643   vec_free (name);
10644   vec_free (next);
10645
10646   S (mp);
10647   W (ret);
10648   return ret;
10649 }
10650
10651 static int
10652 api_l2tpv3_create_tunnel (vat_main_t * vam)
10653 {
10654   unformat_input_t *i = vam->input;
10655   ip6_address_t client_address, our_address;
10656   int client_address_set = 0;
10657   int our_address_set = 0;
10658   u32 local_session_id = 0;
10659   u32 remote_session_id = 0;
10660   u64 local_cookie = 0;
10661   u64 remote_cookie = 0;
10662   u8 l2_sublayer_present = 0;
10663   vl_api_l2tpv3_create_tunnel_t *mp;
10664   int ret;
10665
10666   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10667     {
10668       if (unformat (i, "client_address %U", unformat_ip6_address,
10669                     &client_address))
10670         client_address_set = 1;
10671       else if (unformat (i, "our_address %U", unformat_ip6_address,
10672                          &our_address))
10673         our_address_set = 1;
10674       else if (unformat (i, "local_session_id %d", &local_session_id))
10675         ;
10676       else if (unformat (i, "remote_session_id %d", &remote_session_id))
10677         ;
10678       else if (unformat (i, "local_cookie %lld", &local_cookie))
10679         ;
10680       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
10681         ;
10682       else if (unformat (i, "l2-sublayer-present"))
10683         l2_sublayer_present = 1;
10684       else
10685         break;
10686     }
10687
10688   if (client_address_set == 0)
10689     {
10690       errmsg ("client_address required");
10691       return -99;
10692     }
10693
10694   if (our_address_set == 0)
10695     {
10696       errmsg ("our_address required");
10697       return -99;
10698     }
10699
10700   M (L2TPV3_CREATE_TUNNEL, mp);
10701
10702   clib_memcpy (mp->client_address, client_address.as_u8,
10703                sizeof (mp->client_address));
10704
10705   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
10706
10707   mp->local_session_id = ntohl (local_session_id);
10708   mp->remote_session_id = ntohl (remote_session_id);
10709   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
10710   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
10711   mp->l2_sublayer_present = l2_sublayer_present;
10712   mp->is_ipv6 = 1;
10713
10714   S (mp);
10715   W (ret);
10716   return ret;
10717 }
10718
10719 static int
10720 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
10721 {
10722   unformat_input_t *i = vam->input;
10723   u32 sw_if_index;
10724   u8 sw_if_index_set = 0;
10725   u64 new_local_cookie = 0;
10726   u64 new_remote_cookie = 0;
10727   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
10728   int ret;
10729
10730   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10731     {
10732       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10733         sw_if_index_set = 1;
10734       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10735         sw_if_index_set = 1;
10736       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
10737         ;
10738       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
10739         ;
10740       else
10741         break;
10742     }
10743
10744   if (sw_if_index_set == 0)
10745     {
10746       errmsg ("missing interface name or sw_if_index");
10747       return -99;
10748     }
10749
10750   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
10751
10752   mp->sw_if_index = ntohl (sw_if_index);
10753   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
10754   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
10755
10756   S (mp);
10757   W (ret);
10758   return ret;
10759 }
10760
10761 static int
10762 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
10763 {
10764   unformat_input_t *i = vam->input;
10765   vl_api_l2tpv3_interface_enable_disable_t *mp;
10766   u32 sw_if_index;
10767   u8 sw_if_index_set = 0;
10768   u8 enable_disable = 1;
10769   int ret;
10770
10771   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10772     {
10773       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10774         sw_if_index_set = 1;
10775       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10776         sw_if_index_set = 1;
10777       else if (unformat (i, "enable"))
10778         enable_disable = 1;
10779       else if (unformat (i, "disable"))
10780         enable_disable = 0;
10781       else
10782         break;
10783     }
10784
10785   if (sw_if_index_set == 0)
10786     {
10787       errmsg ("missing interface name or sw_if_index");
10788       return -99;
10789     }
10790
10791   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
10792
10793   mp->sw_if_index = ntohl (sw_if_index);
10794   mp->enable_disable = enable_disable;
10795
10796   S (mp);
10797   W (ret);
10798   return ret;
10799 }
10800
10801 static int
10802 api_l2tpv3_set_lookup_key (vat_main_t * vam)
10803 {
10804   unformat_input_t *i = vam->input;
10805   vl_api_l2tpv3_set_lookup_key_t *mp;
10806   u8 key = ~0;
10807   int ret;
10808
10809   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10810     {
10811       if (unformat (i, "lookup_v6_src"))
10812         key = L2T_LOOKUP_SRC_ADDRESS;
10813       else if (unformat (i, "lookup_v6_dst"))
10814         key = L2T_LOOKUP_DST_ADDRESS;
10815       else if (unformat (i, "lookup_session_id"))
10816         key = L2T_LOOKUP_SESSION_ID;
10817       else
10818         break;
10819     }
10820
10821   if (key == (u8) ~ 0)
10822     {
10823       errmsg ("l2tp session lookup key unset");
10824       return -99;
10825     }
10826
10827   M (L2TPV3_SET_LOOKUP_KEY, mp);
10828
10829   mp->key = key;
10830
10831   S (mp);
10832   W (ret);
10833   return ret;
10834 }
10835
10836 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
10837   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
10838 {
10839   vat_main_t *vam = &vat_main;
10840
10841   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
10842          format_ip6_address, mp->our_address,
10843          format_ip6_address, mp->client_address,
10844          clib_net_to_host_u32 (mp->sw_if_index));
10845
10846   print (vam->ofp,
10847          "   local cookies %016llx %016llx remote cookie %016llx",
10848          clib_net_to_host_u64 (mp->local_cookie[0]),
10849          clib_net_to_host_u64 (mp->local_cookie[1]),
10850          clib_net_to_host_u64 (mp->remote_cookie));
10851
10852   print (vam->ofp, "   local session-id %d remote session-id %d",
10853          clib_net_to_host_u32 (mp->local_session_id),
10854          clib_net_to_host_u32 (mp->remote_session_id));
10855
10856   print (vam->ofp, "   l2 specific sublayer %s\n",
10857          mp->l2_sublayer_present ? "preset" : "absent");
10858
10859 }
10860
10861 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
10862   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
10863 {
10864   vat_main_t *vam = &vat_main;
10865   vat_json_node_t *node = NULL;
10866   struct in6_addr addr;
10867
10868   if (VAT_JSON_ARRAY != vam->json_tree.type)
10869     {
10870       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10871       vat_json_init_array (&vam->json_tree);
10872     }
10873   node = vat_json_array_add (&vam->json_tree);
10874
10875   vat_json_init_object (node);
10876
10877   clib_memcpy (&addr, mp->our_address, sizeof (addr));
10878   vat_json_object_add_ip6 (node, "our_address", addr);
10879   clib_memcpy (&addr, mp->client_address, sizeof (addr));
10880   vat_json_object_add_ip6 (node, "client_address", addr);
10881
10882   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
10883   vat_json_init_array (lc);
10884   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
10885   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
10886   vat_json_object_add_uint (node, "remote_cookie",
10887                             clib_net_to_host_u64 (mp->remote_cookie));
10888
10889   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
10890   vat_json_object_add_uint (node, "local_session_id",
10891                             clib_net_to_host_u32 (mp->local_session_id));
10892   vat_json_object_add_uint (node, "remote_session_id",
10893                             clib_net_to_host_u32 (mp->remote_session_id));
10894   vat_json_object_add_string_copy (node, "l2_sublayer",
10895                                    mp->l2_sublayer_present ? (u8 *) "present"
10896                                    : (u8 *) "absent");
10897 }
10898
10899 static int
10900 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
10901 {
10902   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
10903   vl_api_control_ping_t *mp_ping;
10904   int ret;
10905
10906   /* Get list of l2tpv3-tunnel interfaces */
10907   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
10908   S (mp);
10909
10910   /* Use a control ping for synchronization */
10911   M (CONTROL_PING, mp_ping);
10912   S (mp_ping);
10913
10914   W (ret);
10915   return ret;
10916 }
10917
10918
10919 static void vl_api_sw_interface_tap_details_t_handler
10920   (vl_api_sw_interface_tap_details_t * mp)
10921 {
10922   vat_main_t *vam = &vat_main;
10923
10924   print (vam->ofp, "%-16s %d",
10925          mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
10926 }
10927
10928 static void vl_api_sw_interface_tap_details_t_handler_json
10929   (vl_api_sw_interface_tap_details_t * mp)
10930 {
10931   vat_main_t *vam = &vat_main;
10932   vat_json_node_t *node = NULL;
10933
10934   if (VAT_JSON_ARRAY != vam->json_tree.type)
10935     {
10936       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10937       vat_json_init_array (&vam->json_tree);
10938     }
10939   node = vat_json_array_add (&vam->json_tree);
10940
10941   vat_json_init_object (node);
10942   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10943   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
10944 }
10945
10946 static int
10947 api_sw_interface_tap_dump (vat_main_t * vam)
10948 {
10949   vl_api_sw_interface_tap_dump_t *mp;
10950   vl_api_control_ping_t *mp_ping;
10951   int ret;
10952
10953   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
10954   /* Get list of tap interfaces */
10955   M (SW_INTERFACE_TAP_DUMP, mp);
10956   S (mp);
10957
10958   /* Use a control ping for synchronization */
10959   M (CONTROL_PING, mp_ping);
10960   S (mp_ping);
10961
10962   W (ret);
10963   return ret;
10964 }
10965
10966 static uword unformat_vxlan_decap_next
10967   (unformat_input_t * input, va_list * args)
10968 {
10969   u32 *result = va_arg (*args, u32 *);
10970   u32 tmp;
10971
10972   if (unformat (input, "l2"))
10973     *result = VXLAN_INPUT_NEXT_L2_INPUT;
10974   else if (unformat (input, "%d", &tmp))
10975     *result = tmp;
10976   else
10977     return 0;
10978   return 1;
10979 }
10980
10981 static int
10982 api_vxlan_add_del_tunnel (vat_main_t * vam)
10983 {
10984   unformat_input_t *line_input = vam->input;
10985   vl_api_vxlan_add_del_tunnel_t *mp;
10986   ip46_address_t src, dst;
10987   u8 is_add = 1;
10988   u8 ipv4_set = 0, ipv6_set = 0;
10989   u8 src_set = 0;
10990   u8 dst_set = 0;
10991   u8 grp_set = 0;
10992   u32 mcast_sw_if_index = ~0;
10993   u32 encap_vrf_id = 0;
10994   u32 decap_next_index = ~0;
10995   u32 vni = 0;
10996   int ret;
10997
10998   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
10999   memset (&src, 0, sizeof src);
11000   memset (&dst, 0, sizeof dst);
11001
11002   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11003     {
11004       if (unformat (line_input, "del"))
11005         is_add = 0;
11006       else
11007         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
11008         {
11009           ipv4_set = 1;
11010           src_set = 1;
11011         }
11012       else
11013         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
11014         {
11015           ipv4_set = 1;
11016           dst_set = 1;
11017         }
11018       else
11019         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
11020         {
11021           ipv6_set = 1;
11022           src_set = 1;
11023         }
11024       else
11025         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
11026         {
11027           ipv6_set = 1;
11028           dst_set = 1;
11029         }
11030       else if (unformat (line_input, "group %U %U",
11031                          unformat_ip4_address, &dst.ip4,
11032                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11033         {
11034           grp_set = dst_set = 1;
11035           ipv4_set = 1;
11036         }
11037       else if (unformat (line_input, "group %U",
11038                          unformat_ip4_address, &dst.ip4))
11039         {
11040           grp_set = dst_set = 1;
11041           ipv4_set = 1;
11042         }
11043       else if (unformat (line_input, "group %U %U",
11044                          unformat_ip6_address, &dst.ip6,
11045                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11046         {
11047           grp_set = dst_set = 1;
11048           ipv6_set = 1;
11049         }
11050       else if (unformat (line_input, "group %U",
11051                          unformat_ip6_address, &dst.ip6))
11052         {
11053           grp_set = dst_set = 1;
11054           ipv6_set = 1;
11055         }
11056       else
11057         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
11058         ;
11059       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
11060         ;
11061       else if (unformat (line_input, "decap-next %U",
11062                          unformat_vxlan_decap_next, &decap_next_index))
11063         ;
11064       else if (unformat (line_input, "vni %d", &vni))
11065         ;
11066       else
11067         {
11068           errmsg ("parse error '%U'", format_unformat_error, line_input);
11069           return -99;
11070         }
11071     }
11072
11073   if (src_set == 0)
11074     {
11075       errmsg ("tunnel src address not specified");
11076       return -99;
11077     }
11078   if (dst_set == 0)
11079     {
11080       errmsg ("tunnel dst address not specified");
11081       return -99;
11082     }
11083
11084   if (grp_set && !ip46_address_is_multicast (&dst))
11085     {
11086       errmsg ("tunnel group address not multicast");
11087       return -99;
11088     }
11089   if (grp_set && mcast_sw_if_index == ~0)
11090     {
11091       errmsg ("tunnel nonexistent multicast device");
11092       return -99;
11093     }
11094   if (grp_set == 0 && ip46_address_is_multicast (&dst))
11095     {
11096       errmsg ("tunnel dst address must be unicast");
11097       return -99;
11098     }
11099
11100
11101   if (ipv4_set && ipv6_set)
11102     {
11103       errmsg ("both IPv4 and IPv6 addresses specified");
11104       return -99;
11105     }
11106
11107   if ((vni == 0) || (vni >> 24))
11108     {
11109       errmsg ("vni not specified or out of range");
11110       return -99;
11111     }
11112
11113   M (VXLAN_ADD_DEL_TUNNEL, mp);
11114
11115   if (ipv6_set)
11116     {
11117       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
11118       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
11119     }
11120   else
11121     {
11122       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
11123       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
11124     }
11125   mp->encap_vrf_id = ntohl (encap_vrf_id);
11126   mp->decap_next_index = ntohl (decap_next_index);
11127   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
11128   mp->vni = ntohl (vni);
11129   mp->is_add = is_add;
11130   mp->is_ipv6 = ipv6_set;
11131
11132   S (mp);
11133   W (ret);
11134   return ret;
11135 }
11136
11137 static void vl_api_vxlan_tunnel_details_t_handler
11138   (vl_api_vxlan_tunnel_details_t * mp)
11139 {
11140   vat_main_t *vam = &vat_main;
11141   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
11142   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
11143
11144   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
11145          ntohl (mp->sw_if_index),
11146          format_ip46_address, &src, IP46_TYPE_ANY,
11147          format_ip46_address, &dst, IP46_TYPE_ANY,
11148          ntohl (mp->encap_vrf_id),
11149          ntohl (mp->decap_next_index), ntohl (mp->vni),
11150          ntohl (mp->mcast_sw_if_index));
11151 }
11152
11153 static void vl_api_vxlan_tunnel_details_t_handler_json
11154   (vl_api_vxlan_tunnel_details_t * mp)
11155 {
11156   vat_main_t *vam = &vat_main;
11157   vat_json_node_t *node = NULL;
11158
11159   if (VAT_JSON_ARRAY != vam->json_tree.type)
11160     {
11161       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11162       vat_json_init_array (&vam->json_tree);
11163     }
11164   node = vat_json_array_add (&vam->json_tree);
11165
11166   vat_json_init_object (node);
11167   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11168   if (mp->is_ipv6)
11169     {
11170       struct in6_addr ip6;
11171
11172       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
11173       vat_json_object_add_ip6 (node, "src_address", ip6);
11174       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
11175       vat_json_object_add_ip6 (node, "dst_address", ip6);
11176     }
11177   else
11178     {
11179       struct in_addr ip4;
11180
11181       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
11182       vat_json_object_add_ip4 (node, "src_address", ip4);
11183       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
11184       vat_json_object_add_ip4 (node, "dst_address", ip4);
11185     }
11186   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
11187   vat_json_object_add_uint (node, "decap_next_index",
11188                             ntohl (mp->decap_next_index));
11189   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
11190   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
11191   vat_json_object_add_uint (node, "mcast_sw_if_index",
11192                             ntohl (mp->mcast_sw_if_index));
11193 }
11194
11195 static int
11196 api_vxlan_tunnel_dump (vat_main_t * vam)
11197 {
11198   unformat_input_t *i = vam->input;
11199   vl_api_vxlan_tunnel_dump_t *mp;
11200   vl_api_control_ping_t *mp_ping;
11201   u32 sw_if_index;
11202   u8 sw_if_index_set = 0;
11203   int ret;
11204
11205   /* Parse args required to build the message */
11206   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11207     {
11208       if (unformat (i, "sw_if_index %d", &sw_if_index))
11209         sw_if_index_set = 1;
11210       else
11211         break;
11212     }
11213
11214   if (sw_if_index_set == 0)
11215     {
11216       sw_if_index = ~0;
11217     }
11218
11219   if (!vam->json_output)
11220     {
11221       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
11222              "sw_if_index", "src_address", "dst_address",
11223              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
11224     }
11225
11226   /* Get list of vxlan-tunnel interfaces */
11227   M (VXLAN_TUNNEL_DUMP, mp);
11228
11229   mp->sw_if_index = htonl (sw_if_index);
11230
11231   S (mp);
11232
11233   /* Use a control ping for synchronization */
11234   M (CONTROL_PING, mp_ping);
11235   S (mp_ping);
11236
11237   W (ret);
11238   return ret;
11239 }
11240
11241 static int
11242 api_gre_add_del_tunnel (vat_main_t * vam)
11243 {
11244   unformat_input_t *line_input = vam->input;
11245   vl_api_gre_add_del_tunnel_t *mp;
11246   ip4_address_t src4, dst4;
11247   ip6_address_t src6, dst6;
11248   u8 is_add = 1;
11249   u8 ipv4_set = 0;
11250   u8 ipv6_set = 0;
11251   u8 teb = 0;
11252   u8 src_set = 0;
11253   u8 dst_set = 0;
11254   u32 outer_fib_id = 0;
11255   int ret;
11256
11257   memset (&src4, 0, sizeof src4);
11258   memset (&dst4, 0, sizeof dst4);
11259   memset (&src6, 0, sizeof src6);
11260   memset (&dst6, 0, sizeof dst6);
11261
11262   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11263     {
11264       if (unformat (line_input, "del"))
11265         is_add = 0;
11266       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
11267         {
11268           src_set = 1;
11269           ipv4_set = 1;
11270         }
11271       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
11272         {
11273           dst_set = 1;
11274           ipv4_set = 1;
11275         }
11276       else if (unformat (line_input, "src %U", unformat_ip6_address, &src6))
11277         {
11278           src_set = 1;
11279           ipv6_set = 1;
11280         }
11281       else if (unformat (line_input, "dst %U", unformat_ip6_address, &dst6))
11282         {
11283           dst_set = 1;
11284           ipv6_set = 1;
11285         }
11286       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
11287         ;
11288       else if (unformat (line_input, "teb"))
11289         teb = 1;
11290       else
11291         {
11292           errmsg ("parse error '%U'", format_unformat_error, line_input);
11293           return -99;
11294         }
11295     }
11296
11297   if (src_set == 0)
11298     {
11299       errmsg ("tunnel src address not specified");
11300       return -99;
11301     }
11302   if (dst_set == 0)
11303     {
11304       errmsg ("tunnel dst address not specified");
11305       return -99;
11306     }
11307   if (ipv4_set && ipv6_set)
11308     {
11309       errmsg ("both IPv4 and IPv6 addresses specified");
11310       return -99;
11311     }
11312
11313
11314   M (GRE_ADD_DEL_TUNNEL, mp);
11315
11316   if (ipv4_set)
11317     {
11318       clib_memcpy (&mp->src_address, &src4, 4);
11319       clib_memcpy (&mp->dst_address, &dst4, 4);
11320     }
11321   else
11322     {
11323       clib_memcpy (&mp->src_address, &src6, 16);
11324       clib_memcpy (&mp->dst_address, &dst6, 16);
11325     }
11326   mp->outer_fib_id = ntohl (outer_fib_id);
11327   mp->is_add = is_add;
11328   mp->teb = teb;
11329   mp->is_ipv6 = ipv6_set;
11330
11331   S (mp);
11332   W (ret);
11333   return ret;
11334 }
11335
11336 static void vl_api_gre_tunnel_details_t_handler
11337   (vl_api_gre_tunnel_details_t * mp)
11338 {
11339   vat_main_t *vam = &vat_main;
11340   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->src_address);
11341   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->dst_address);
11342
11343   print (vam->ofp, "%11d%24U%24U%6d%14d",
11344          ntohl (mp->sw_if_index),
11345          format_ip46_address, &src, IP46_TYPE_ANY,
11346          format_ip46_address, &dst, IP46_TYPE_ANY,
11347          mp->teb, ntohl (mp->outer_fib_id));
11348 }
11349
11350 static void vl_api_gre_tunnel_details_t_handler_json
11351   (vl_api_gre_tunnel_details_t * mp)
11352 {
11353   vat_main_t *vam = &vat_main;
11354   vat_json_node_t *node = NULL;
11355   struct in_addr ip4;
11356   struct in6_addr ip6;
11357
11358   if (VAT_JSON_ARRAY != vam->json_tree.type)
11359     {
11360       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11361       vat_json_init_array (&vam->json_tree);
11362     }
11363   node = vat_json_array_add (&vam->json_tree);
11364
11365   vat_json_init_object (node);
11366   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11367   if (!mp->is_ipv6)
11368     {
11369       clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
11370       vat_json_object_add_ip4 (node, "src_address", ip4);
11371       clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
11372       vat_json_object_add_ip4 (node, "dst_address", ip4);
11373     }
11374   else
11375     {
11376       clib_memcpy (&ip6, &mp->src_address, sizeof (ip6));
11377       vat_json_object_add_ip6 (node, "src_address", ip6);
11378       clib_memcpy (&ip6, &mp->dst_address, sizeof (ip6));
11379       vat_json_object_add_ip6 (node, "dst_address", ip6);
11380     }
11381   vat_json_object_add_uint (node, "teb", mp->teb);
11382   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
11383   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6);
11384 }
11385
11386 static int
11387 api_gre_tunnel_dump (vat_main_t * vam)
11388 {
11389   unformat_input_t *i = vam->input;
11390   vl_api_gre_tunnel_dump_t *mp;
11391   vl_api_control_ping_t *mp_ping;
11392   u32 sw_if_index;
11393   u8 sw_if_index_set = 0;
11394   int ret;
11395
11396   /* Parse args required to build the message */
11397   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11398     {
11399       if (unformat (i, "sw_if_index %d", &sw_if_index))
11400         sw_if_index_set = 1;
11401       else
11402         break;
11403     }
11404
11405   if (sw_if_index_set == 0)
11406     {
11407       sw_if_index = ~0;
11408     }
11409
11410   if (!vam->json_output)
11411     {
11412       print (vam->ofp, "%11s%24s%24s%6s%14s",
11413              "sw_if_index", "src_address", "dst_address", "teb",
11414              "outer_fib_id");
11415     }
11416
11417   /* Get list of gre-tunnel interfaces */
11418   M (GRE_TUNNEL_DUMP, mp);
11419
11420   mp->sw_if_index = htonl (sw_if_index);
11421
11422   S (mp);
11423
11424   /* Use a control ping for synchronization */
11425   M (CONTROL_PING, mp_ping);
11426   S (mp_ping);
11427
11428   W (ret);
11429   return ret;
11430 }
11431
11432 static int
11433 api_l2_fib_clear_table (vat_main_t * vam)
11434 {
11435 //  unformat_input_t * i = vam->input;
11436   vl_api_l2_fib_clear_table_t *mp;
11437   int ret;
11438
11439   M (L2_FIB_CLEAR_TABLE, mp);
11440
11441   S (mp);
11442   W (ret);
11443   return ret;
11444 }
11445
11446 static int
11447 api_l2_interface_efp_filter (vat_main_t * vam)
11448 {
11449   unformat_input_t *i = vam->input;
11450   vl_api_l2_interface_efp_filter_t *mp;
11451   u32 sw_if_index;
11452   u8 enable = 1;
11453   u8 sw_if_index_set = 0;
11454   int ret;
11455
11456   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11457     {
11458       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11459         sw_if_index_set = 1;
11460       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11461         sw_if_index_set = 1;
11462       else if (unformat (i, "enable"))
11463         enable = 1;
11464       else if (unformat (i, "disable"))
11465         enable = 0;
11466       else
11467         {
11468           clib_warning ("parse error '%U'", format_unformat_error, i);
11469           return -99;
11470         }
11471     }
11472
11473   if (sw_if_index_set == 0)
11474     {
11475       errmsg ("missing sw_if_index");
11476       return -99;
11477     }
11478
11479   M (L2_INTERFACE_EFP_FILTER, mp);
11480
11481   mp->sw_if_index = ntohl (sw_if_index);
11482   mp->enable_disable = enable;
11483
11484   S (mp);
11485   W (ret);
11486   return ret;
11487 }
11488
11489 #define foreach_vtr_op                          \
11490 _("disable",  L2_VTR_DISABLED)                  \
11491 _("push-1",  L2_VTR_PUSH_1)                     \
11492 _("push-2",  L2_VTR_PUSH_2)                     \
11493 _("pop-1",  L2_VTR_POP_1)                       \
11494 _("pop-2",  L2_VTR_POP_2)                       \
11495 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
11496 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
11497 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
11498 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
11499
11500 static int
11501 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
11502 {
11503   unformat_input_t *i = vam->input;
11504   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
11505   u32 sw_if_index;
11506   u8 sw_if_index_set = 0;
11507   u8 vtr_op_set = 0;
11508   u32 vtr_op = 0;
11509   u32 push_dot1q = 1;
11510   u32 tag1 = ~0;
11511   u32 tag2 = ~0;
11512   int ret;
11513
11514   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11515     {
11516       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11517         sw_if_index_set = 1;
11518       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11519         sw_if_index_set = 1;
11520       else if (unformat (i, "vtr_op %d", &vtr_op))
11521         vtr_op_set = 1;
11522 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
11523       foreach_vtr_op
11524 #undef _
11525         else if (unformat (i, "push_dot1q %d", &push_dot1q))
11526         ;
11527       else if (unformat (i, "tag1 %d", &tag1))
11528         ;
11529       else if (unformat (i, "tag2 %d", &tag2))
11530         ;
11531       else
11532         {
11533           clib_warning ("parse error '%U'", format_unformat_error, i);
11534           return -99;
11535         }
11536     }
11537
11538   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
11539     {
11540       errmsg ("missing vtr operation or sw_if_index");
11541       return -99;
11542     }
11543
11544   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
11545   mp->sw_if_index = ntohl (sw_if_index);
11546   mp->vtr_op = ntohl (vtr_op);
11547   mp->push_dot1q = ntohl (push_dot1q);
11548   mp->tag1 = ntohl (tag1);
11549   mp->tag2 = ntohl (tag2);
11550
11551   S (mp);
11552   W (ret);
11553   return ret;
11554 }
11555
11556 static int
11557 api_create_vhost_user_if (vat_main_t * vam)
11558 {
11559   unformat_input_t *i = vam->input;
11560   vl_api_create_vhost_user_if_t *mp;
11561   u8 *file_name;
11562   u8 is_server = 0;
11563   u8 file_name_set = 0;
11564   u32 custom_dev_instance = ~0;
11565   u8 hwaddr[6];
11566   u8 use_custom_mac = 0;
11567   u8 *tag = 0;
11568   int ret;
11569
11570   /* Shut up coverity */
11571   memset (hwaddr, 0, sizeof (hwaddr));
11572
11573   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11574     {
11575       if (unformat (i, "socket %s", &file_name))
11576         {
11577           file_name_set = 1;
11578         }
11579       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
11580         ;
11581       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
11582         use_custom_mac = 1;
11583       else if (unformat (i, "server"))
11584         is_server = 1;
11585       else if (unformat (i, "tag %s", &tag))
11586         ;
11587       else
11588         break;
11589     }
11590
11591   if (file_name_set == 0)
11592     {
11593       errmsg ("missing socket file name");
11594       return -99;
11595     }
11596
11597   if (vec_len (file_name) > 255)
11598     {
11599       errmsg ("socket file name too long");
11600       return -99;
11601     }
11602   vec_add1 (file_name, 0);
11603
11604   M (CREATE_VHOST_USER_IF, mp);
11605
11606   mp->is_server = is_server;
11607   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
11608   vec_free (file_name);
11609   if (custom_dev_instance != ~0)
11610     {
11611       mp->renumber = 1;
11612       mp->custom_dev_instance = ntohl (custom_dev_instance);
11613     }
11614   mp->use_custom_mac = use_custom_mac;
11615   clib_memcpy (mp->mac_address, hwaddr, 6);
11616   if (tag)
11617     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
11618   vec_free (tag);
11619
11620   S (mp);
11621   W (ret);
11622   return ret;
11623 }
11624
11625 static int
11626 api_modify_vhost_user_if (vat_main_t * vam)
11627 {
11628   unformat_input_t *i = vam->input;
11629   vl_api_modify_vhost_user_if_t *mp;
11630   u8 *file_name;
11631   u8 is_server = 0;
11632   u8 file_name_set = 0;
11633   u32 custom_dev_instance = ~0;
11634   u8 sw_if_index_set = 0;
11635   u32 sw_if_index = (u32) ~ 0;
11636   int ret;
11637
11638   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11639     {
11640       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11641         sw_if_index_set = 1;
11642       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11643         sw_if_index_set = 1;
11644       else if (unformat (i, "socket %s", &file_name))
11645         {
11646           file_name_set = 1;
11647         }
11648       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
11649         ;
11650       else if (unformat (i, "server"))
11651         is_server = 1;
11652       else
11653         break;
11654     }
11655
11656   if (sw_if_index_set == 0)
11657     {
11658       errmsg ("missing sw_if_index or interface name");
11659       return -99;
11660     }
11661
11662   if (file_name_set == 0)
11663     {
11664       errmsg ("missing socket file name");
11665       return -99;
11666     }
11667
11668   if (vec_len (file_name) > 255)
11669     {
11670       errmsg ("socket file name too long");
11671       return -99;
11672     }
11673   vec_add1 (file_name, 0);
11674
11675   M (MODIFY_VHOST_USER_IF, mp);
11676
11677   mp->sw_if_index = ntohl (sw_if_index);
11678   mp->is_server = is_server;
11679   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
11680   vec_free (file_name);
11681   if (custom_dev_instance != ~0)
11682     {
11683       mp->renumber = 1;
11684       mp->custom_dev_instance = ntohl (custom_dev_instance);
11685     }
11686
11687   S (mp);
11688   W (ret);
11689   return ret;
11690 }
11691
11692 static int
11693 api_delete_vhost_user_if (vat_main_t * vam)
11694 {
11695   unformat_input_t *i = vam->input;
11696   vl_api_delete_vhost_user_if_t *mp;
11697   u32 sw_if_index = ~0;
11698   u8 sw_if_index_set = 0;
11699   int ret;
11700
11701   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11702     {
11703       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11704         sw_if_index_set = 1;
11705       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11706         sw_if_index_set = 1;
11707       else
11708         break;
11709     }
11710
11711   if (sw_if_index_set == 0)
11712     {
11713       errmsg ("missing sw_if_index or interface name");
11714       return -99;
11715     }
11716
11717
11718   M (DELETE_VHOST_USER_IF, mp);
11719
11720   mp->sw_if_index = ntohl (sw_if_index);
11721
11722   S (mp);
11723   W (ret);
11724   return ret;
11725 }
11726
11727 static void vl_api_sw_interface_vhost_user_details_t_handler
11728   (vl_api_sw_interface_vhost_user_details_t * mp)
11729 {
11730   vat_main_t *vam = &vat_main;
11731
11732   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
11733          (char *) mp->interface_name,
11734          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
11735          clib_net_to_host_u64 (mp->features), mp->is_server,
11736          ntohl (mp->num_regions), (char *) mp->sock_filename);
11737   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
11738 }
11739
11740 static void vl_api_sw_interface_vhost_user_details_t_handler_json
11741   (vl_api_sw_interface_vhost_user_details_t * mp)
11742 {
11743   vat_main_t *vam = &vat_main;
11744   vat_json_node_t *node = NULL;
11745
11746   if (VAT_JSON_ARRAY != vam->json_tree.type)
11747     {
11748       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11749       vat_json_init_array (&vam->json_tree);
11750     }
11751   node = vat_json_array_add (&vam->json_tree);
11752
11753   vat_json_init_object (node);
11754   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11755   vat_json_object_add_string_copy (node, "interface_name",
11756                                    mp->interface_name);
11757   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
11758                             ntohl (mp->virtio_net_hdr_sz));
11759   vat_json_object_add_uint (node, "features",
11760                             clib_net_to_host_u64 (mp->features));
11761   vat_json_object_add_uint (node, "is_server", mp->is_server);
11762   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
11763   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
11764   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
11765 }
11766
11767 static int
11768 api_sw_interface_vhost_user_dump (vat_main_t * vam)
11769 {
11770   vl_api_sw_interface_vhost_user_dump_t *mp;
11771   vl_api_control_ping_t *mp_ping;
11772   int ret;
11773   print (vam->ofp,
11774          "Interface name            idx hdr_sz features server regions filename");
11775
11776   /* Get list of vhost-user interfaces */
11777   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
11778   S (mp);
11779
11780   /* Use a control ping for synchronization */
11781   M (CONTROL_PING, mp_ping);
11782   S (mp_ping);
11783
11784   W (ret);
11785   return ret;
11786 }
11787
11788 static int
11789 api_show_version (vat_main_t * vam)
11790 {
11791   vl_api_show_version_t *mp;
11792   int ret;
11793
11794   M (SHOW_VERSION, mp);
11795
11796   S (mp);
11797   W (ret);
11798   return ret;
11799 }
11800
11801
11802 static int
11803 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
11804 {
11805   unformat_input_t *line_input = vam->input;
11806   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
11807   ip4_address_t local4, remote4;
11808   ip6_address_t local6, remote6;
11809   u8 is_add = 1;
11810   u8 ipv4_set = 0, ipv6_set = 0;
11811   u8 local_set = 0;
11812   u8 remote_set = 0;
11813   u32 encap_vrf_id = 0;
11814   u32 decap_vrf_id = 0;
11815   u8 protocol = ~0;
11816   u32 vni;
11817   u8 vni_set = 0;
11818   int ret;
11819
11820   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11821     {
11822       if (unformat (line_input, "del"))
11823         is_add = 0;
11824       else if (unformat (line_input, "local %U",
11825                          unformat_ip4_address, &local4))
11826         {
11827           local_set = 1;
11828           ipv4_set = 1;
11829         }
11830       else if (unformat (line_input, "remote %U",
11831                          unformat_ip4_address, &remote4))
11832         {
11833           remote_set = 1;
11834           ipv4_set = 1;
11835         }
11836       else if (unformat (line_input, "local %U",
11837                          unformat_ip6_address, &local6))
11838         {
11839           local_set = 1;
11840           ipv6_set = 1;
11841         }
11842       else if (unformat (line_input, "remote %U",
11843                          unformat_ip6_address, &remote6))
11844         {
11845           remote_set = 1;
11846           ipv6_set = 1;
11847         }
11848       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
11849         ;
11850       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
11851         ;
11852       else if (unformat (line_input, "vni %d", &vni))
11853         vni_set = 1;
11854       else if (unformat (line_input, "next-ip4"))
11855         protocol = 1;
11856       else if (unformat (line_input, "next-ip6"))
11857         protocol = 2;
11858       else if (unformat (line_input, "next-ethernet"))
11859         protocol = 3;
11860       else if (unformat (line_input, "next-nsh"))
11861         protocol = 4;
11862       else
11863         {
11864           errmsg ("parse error '%U'", format_unformat_error, line_input);
11865           return -99;
11866         }
11867     }
11868
11869   if (local_set == 0)
11870     {
11871       errmsg ("tunnel local address not specified");
11872       return -99;
11873     }
11874   if (remote_set == 0)
11875     {
11876       errmsg ("tunnel remote address not specified");
11877       return -99;
11878     }
11879   if (ipv4_set && ipv6_set)
11880     {
11881       errmsg ("both IPv4 and IPv6 addresses specified");
11882       return -99;
11883     }
11884
11885   if (vni_set == 0)
11886     {
11887       errmsg ("vni not specified");
11888       return -99;
11889     }
11890
11891   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
11892
11893
11894   if (ipv6_set)
11895     {
11896       clib_memcpy (&mp->local, &local6, sizeof (local6));
11897       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
11898     }
11899   else
11900     {
11901       clib_memcpy (&mp->local, &local4, sizeof (local4));
11902       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
11903     }
11904
11905   mp->encap_vrf_id = ntohl (encap_vrf_id);
11906   mp->decap_vrf_id = ntohl (decap_vrf_id);
11907   mp->protocol = protocol;
11908   mp->vni = ntohl (vni);
11909   mp->is_add = is_add;
11910   mp->is_ipv6 = ipv6_set;
11911
11912   S (mp);
11913   W (ret);
11914   return ret;
11915 }
11916
11917 static void vl_api_vxlan_gpe_tunnel_details_t_handler
11918   (vl_api_vxlan_gpe_tunnel_details_t * mp)
11919 {
11920   vat_main_t *vam = &vat_main;
11921
11922   print (vam->ofp, "%11d%24U%24U%13d%12d%14d%14d",
11923          ntohl (mp->sw_if_index),
11924          format_ip46_address, &(mp->local[0]),
11925          format_ip46_address, &(mp->remote[0]),
11926          ntohl (mp->vni),
11927          ntohl (mp->protocol),
11928          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
11929 }
11930
11931 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
11932   (vl_api_vxlan_gpe_tunnel_details_t * mp)
11933 {
11934   vat_main_t *vam = &vat_main;
11935   vat_json_node_t *node = NULL;
11936   struct in_addr ip4;
11937   struct in6_addr ip6;
11938
11939   if (VAT_JSON_ARRAY != vam->json_tree.type)
11940     {
11941       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11942       vat_json_init_array (&vam->json_tree);
11943     }
11944   node = vat_json_array_add (&vam->json_tree);
11945
11946   vat_json_init_object (node);
11947   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11948   if (mp->is_ipv6)
11949     {
11950       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
11951       vat_json_object_add_ip6 (node, "local", ip6);
11952       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
11953       vat_json_object_add_ip6 (node, "remote", ip6);
11954     }
11955   else
11956     {
11957       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
11958       vat_json_object_add_ip4 (node, "local", ip4);
11959       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
11960       vat_json_object_add_ip4 (node, "remote", ip4);
11961     }
11962   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
11963   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
11964   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
11965   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
11966   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
11967 }
11968
11969 static int
11970 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
11971 {
11972   unformat_input_t *i = vam->input;
11973   vl_api_vxlan_gpe_tunnel_dump_t *mp;
11974   vl_api_control_ping_t *mp_ping;
11975   u32 sw_if_index;
11976   u8 sw_if_index_set = 0;
11977   int ret;
11978
11979   /* Parse args required to build the message */
11980   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11981     {
11982       if (unformat (i, "sw_if_index %d", &sw_if_index))
11983         sw_if_index_set = 1;
11984       else
11985         break;
11986     }
11987
11988   if (sw_if_index_set == 0)
11989     {
11990       sw_if_index = ~0;
11991     }
11992
11993   if (!vam->json_output)
11994     {
11995       print (vam->ofp, "%11s%24s%24s%13s%15s%14s%14s",
11996              "sw_if_index", "local", "remote", "vni",
11997              "protocol", "encap_vrf_id", "decap_vrf_id");
11998     }
11999
12000   /* Get list of vxlan-tunnel interfaces */
12001   M (VXLAN_GPE_TUNNEL_DUMP, mp);
12002
12003   mp->sw_if_index = htonl (sw_if_index);
12004
12005   S (mp);
12006
12007   /* Use a control ping for synchronization */
12008   M (CONTROL_PING, mp_ping);
12009   S (mp_ping);
12010
12011   W (ret);
12012   return ret;
12013 }
12014
12015 u8 *
12016 format_l2_fib_mac_address (u8 * s, va_list * args)
12017 {
12018   u8 *a = va_arg (*args, u8 *);
12019
12020   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
12021                  a[2], a[3], a[4], a[5], a[6], a[7]);
12022 }
12023
12024 static void vl_api_l2_fib_table_details_t_handler
12025   (vl_api_l2_fib_table_details_t * mp)
12026 {
12027   vat_main_t *vam = &vat_main;
12028
12029   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
12030          "       %d       %d     %d",
12031          ntohl (mp->bd_id), format_l2_fib_mac_address, &mp->mac,
12032          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
12033          mp->bvi_mac);
12034 }
12035
12036 static void vl_api_l2_fib_table_details_t_handler_json
12037   (vl_api_l2_fib_table_details_t * mp)
12038 {
12039   vat_main_t *vam = &vat_main;
12040   vat_json_node_t *node = NULL;
12041
12042   if (VAT_JSON_ARRAY != vam->json_tree.type)
12043     {
12044       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12045       vat_json_init_array (&vam->json_tree);
12046     }
12047   node = vat_json_array_add (&vam->json_tree);
12048
12049   vat_json_init_object (node);
12050   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
12051   vat_json_object_add_uint (node, "mac", clib_net_to_host_u64 (mp->mac));
12052   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12053   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
12054   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
12055   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
12056 }
12057
12058 static int
12059 api_l2_fib_table_dump (vat_main_t * vam)
12060 {
12061   unformat_input_t *i = vam->input;
12062   vl_api_l2_fib_table_dump_t *mp;
12063   vl_api_control_ping_t *mp_ping;
12064   u32 bd_id;
12065   u8 bd_id_set = 0;
12066   int ret;
12067
12068   /* Parse args required to build the message */
12069   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12070     {
12071       if (unformat (i, "bd_id %d", &bd_id))
12072         bd_id_set = 1;
12073       else
12074         break;
12075     }
12076
12077   if (bd_id_set == 0)
12078     {
12079       errmsg ("missing bridge domain");
12080       return -99;
12081     }
12082
12083   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
12084
12085   /* Get list of l2 fib entries */
12086   M (L2_FIB_TABLE_DUMP, mp);
12087
12088   mp->bd_id = ntohl (bd_id);
12089   S (mp);
12090
12091   /* Use a control ping for synchronization */
12092   M (CONTROL_PING, mp_ping);
12093   S (mp_ping);
12094
12095   W (ret);
12096   return ret;
12097 }
12098
12099
12100 static int
12101 api_interface_name_renumber (vat_main_t * vam)
12102 {
12103   unformat_input_t *line_input = vam->input;
12104   vl_api_interface_name_renumber_t *mp;
12105   u32 sw_if_index = ~0;
12106   u32 new_show_dev_instance = ~0;
12107   int ret;
12108
12109   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12110     {
12111       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
12112                     &sw_if_index))
12113         ;
12114       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
12115         ;
12116       else if (unformat (line_input, "new_show_dev_instance %d",
12117                          &new_show_dev_instance))
12118         ;
12119       else
12120         break;
12121     }
12122
12123   if (sw_if_index == ~0)
12124     {
12125       errmsg ("missing interface name or sw_if_index");
12126       return -99;
12127     }
12128
12129   if (new_show_dev_instance == ~0)
12130     {
12131       errmsg ("missing new_show_dev_instance");
12132       return -99;
12133     }
12134
12135   M (INTERFACE_NAME_RENUMBER, mp);
12136
12137   mp->sw_if_index = ntohl (sw_if_index);
12138   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
12139
12140   S (mp);
12141   W (ret);
12142   return ret;
12143 }
12144
12145 static int
12146 api_want_ip4_arp_events (vat_main_t * vam)
12147 {
12148   unformat_input_t *line_input = vam->input;
12149   vl_api_want_ip4_arp_events_t *mp;
12150   ip4_address_t address;
12151   int address_set = 0;
12152   u32 enable_disable = 1;
12153   int ret;
12154
12155   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12156     {
12157       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
12158         address_set = 1;
12159       else if (unformat (line_input, "del"))
12160         enable_disable = 0;
12161       else
12162         break;
12163     }
12164
12165   if (address_set == 0)
12166     {
12167       errmsg ("missing addresses");
12168       return -99;
12169     }
12170
12171   M (WANT_IP4_ARP_EVENTS, mp);
12172   mp->enable_disable = enable_disable;
12173   mp->pid = htonl (getpid ());
12174   mp->address = address.as_u32;
12175
12176   S (mp);
12177   W (ret);
12178   return ret;
12179 }
12180
12181 static int
12182 api_want_ip6_nd_events (vat_main_t * vam)
12183 {
12184   unformat_input_t *line_input = vam->input;
12185   vl_api_want_ip6_nd_events_t *mp;
12186   ip6_address_t address;
12187   int address_set = 0;
12188   u32 enable_disable = 1;
12189   int ret;
12190
12191   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12192     {
12193       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
12194         address_set = 1;
12195       else if (unformat (line_input, "del"))
12196         enable_disable = 0;
12197       else
12198         break;
12199     }
12200
12201   if (address_set == 0)
12202     {
12203       errmsg ("missing addresses");
12204       return -99;
12205     }
12206
12207   M (WANT_IP6_ND_EVENTS, mp);
12208   mp->enable_disable = enable_disable;
12209   mp->pid = htonl (getpid ());
12210   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
12211
12212   S (mp);
12213   W (ret);
12214   return ret;
12215 }
12216
12217 static int
12218 api_input_acl_set_interface (vat_main_t * vam)
12219 {
12220   unformat_input_t *i = vam->input;
12221   vl_api_input_acl_set_interface_t *mp;
12222   u32 sw_if_index;
12223   int sw_if_index_set;
12224   u32 ip4_table_index = ~0;
12225   u32 ip6_table_index = ~0;
12226   u32 l2_table_index = ~0;
12227   u8 is_add = 1;
12228   int ret;
12229
12230   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12231     {
12232       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12233         sw_if_index_set = 1;
12234       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12235         sw_if_index_set = 1;
12236       else if (unformat (i, "del"))
12237         is_add = 0;
12238       else if (unformat (i, "ip4-table %d", &ip4_table_index))
12239         ;
12240       else if (unformat (i, "ip6-table %d", &ip6_table_index))
12241         ;
12242       else if (unformat (i, "l2-table %d", &l2_table_index))
12243         ;
12244       else
12245         {
12246           clib_warning ("parse error '%U'", format_unformat_error, i);
12247           return -99;
12248         }
12249     }
12250
12251   if (sw_if_index_set == 0)
12252     {
12253       errmsg ("missing interface name or sw_if_index");
12254       return -99;
12255     }
12256
12257   M (INPUT_ACL_SET_INTERFACE, mp);
12258
12259   mp->sw_if_index = ntohl (sw_if_index);
12260   mp->ip4_table_index = ntohl (ip4_table_index);
12261   mp->ip6_table_index = ntohl (ip6_table_index);
12262   mp->l2_table_index = ntohl (l2_table_index);
12263   mp->is_add = is_add;
12264
12265   S (mp);
12266   W (ret);
12267   return ret;
12268 }
12269
12270 static int
12271 api_ip_address_dump (vat_main_t * vam)
12272 {
12273   unformat_input_t *i = vam->input;
12274   vl_api_ip_address_dump_t *mp;
12275   vl_api_control_ping_t *mp_ping;
12276   u32 sw_if_index = ~0;
12277   u8 sw_if_index_set = 0;
12278   u8 ipv4_set = 0;
12279   u8 ipv6_set = 0;
12280   int ret;
12281
12282   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12283     {
12284       if (unformat (i, "sw_if_index %d", &sw_if_index))
12285         sw_if_index_set = 1;
12286       else
12287         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12288         sw_if_index_set = 1;
12289       else if (unformat (i, "ipv4"))
12290         ipv4_set = 1;
12291       else if (unformat (i, "ipv6"))
12292         ipv6_set = 1;
12293       else
12294         break;
12295     }
12296
12297   if (ipv4_set && ipv6_set)
12298     {
12299       errmsg ("ipv4 and ipv6 flags cannot be both set");
12300       return -99;
12301     }
12302
12303   if ((!ipv4_set) && (!ipv6_set))
12304     {
12305       errmsg ("no ipv4 nor ipv6 flag set");
12306       return -99;
12307     }
12308
12309   if (sw_if_index_set == 0)
12310     {
12311       errmsg ("missing interface name or sw_if_index");
12312       return -99;
12313     }
12314
12315   vam->current_sw_if_index = sw_if_index;
12316   vam->is_ipv6 = ipv6_set;
12317
12318   M (IP_ADDRESS_DUMP, mp);
12319   mp->sw_if_index = ntohl (sw_if_index);
12320   mp->is_ipv6 = ipv6_set;
12321   S (mp);
12322
12323   /* Use a control ping for synchronization */
12324   M (CONTROL_PING, mp_ping);
12325   S (mp_ping);
12326
12327   W (ret);
12328   return ret;
12329 }
12330
12331 static int
12332 api_ip_dump (vat_main_t * vam)
12333 {
12334   vl_api_ip_dump_t *mp;
12335   vl_api_control_ping_t *mp_ping;
12336   unformat_input_t *in = vam->input;
12337   int ipv4_set = 0;
12338   int ipv6_set = 0;
12339   int is_ipv6;
12340   int i;
12341   int ret;
12342
12343   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
12344     {
12345       if (unformat (in, "ipv4"))
12346         ipv4_set = 1;
12347       else if (unformat (in, "ipv6"))
12348         ipv6_set = 1;
12349       else
12350         break;
12351     }
12352
12353   if (ipv4_set && ipv6_set)
12354     {
12355       errmsg ("ipv4 and ipv6 flags cannot be both set");
12356       return -99;
12357     }
12358
12359   if ((!ipv4_set) && (!ipv6_set))
12360     {
12361       errmsg ("no ipv4 nor ipv6 flag set");
12362       return -99;
12363     }
12364
12365   is_ipv6 = ipv6_set;
12366   vam->is_ipv6 = is_ipv6;
12367
12368   /* free old data */
12369   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
12370     {
12371       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
12372     }
12373   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
12374
12375   M (IP_DUMP, mp);
12376   mp->is_ipv6 = ipv6_set;
12377   S (mp);
12378
12379   /* Use a control ping for synchronization */
12380   M (CONTROL_PING, mp_ping);
12381   S (mp_ping);
12382
12383   W (ret);
12384   return ret;
12385 }
12386
12387 static int
12388 api_ipsec_spd_add_del (vat_main_t * vam)
12389 {
12390   unformat_input_t *i = vam->input;
12391   vl_api_ipsec_spd_add_del_t *mp;
12392   u32 spd_id = ~0;
12393   u8 is_add = 1;
12394   int ret;
12395
12396   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12397     {
12398       if (unformat (i, "spd_id %d", &spd_id))
12399         ;
12400       else if (unformat (i, "del"))
12401         is_add = 0;
12402       else
12403         {
12404           clib_warning ("parse error '%U'", format_unformat_error, i);
12405           return -99;
12406         }
12407     }
12408   if (spd_id == ~0)
12409     {
12410       errmsg ("spd_id must be set");
12411       return -99;
12412     }
12413
12414   M (IPSEC_SPD_ADD_DEL, mp);
12415
12416   mp->spd_id = ntohl (spd_id);
12417   mp->is_add = is_add;
12418
12419   S (mp);
12420   W (ret);
12421   return ret;
12422 }
12423
12424 static int
12425 api_ipsec_interface_add_del_spd (vat_main_t * vam)
12426 {
12427   unformat_input_t *i = vam->input;
12428   vl_api_ipsec_interface_add_del_spd_t *mp;
12429   u32 sw_if_index;
12430   u8 sw_if_index_set = 0;
12431   u32 spd_id = (u32) ~ 0;
12432   u8 is_add = 1;
12433   int ret;
12434
12435   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12436     {
12437       if (unformat (i, "del"))
12438         is_add = 0;
12439       else if (unformat (i, "spd_id %d", &spd_id))
12440         ;
12441       else
12442         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12443         sw_if_index_set = 1;
12444       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12445         sw_if_index_set = 1;
12446       else
12447         {
12448           clib_warning ("parse error '%U'", format_unformat_error, i);
12449           return -99;
12450         }
12451
12452     }
12453
12454   if (spd_id == (u32) ~ 0)
12455     {
12456       errmsg ("spd_id must be set");
12457       return -99;
12458     }
12459
12460   if (sw_if_index_set == 0)
12461     {
12462       errmsg ("missing interface name or sw_if_index");
12463       return -99;
12464     }
12465
12466   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
12467
12468   mp->spd_id = ntohl (spd_id);
12469   mp->sw_if_index = ntohl (sw_if_index);
12470   mp->is_add = is_add;
12471
12472   S (mp);
12473   W (ret);
12474   return ret;
12475 }
12476
12477 static int
12478 api_ipsec_spd_add_del_entry (vat_main_t * vam)
12479 {
12480   unformat_input_t *i = vam->input;
12481   vl_api_ipsec_spd_add_del_entry_t *mp;
12482   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
12483   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
12484   i32 priority = 0;
12485   u32 rport_start = 0, rport_stop = (u32) ~ 0;
12486   u32 lport_start = 0, lport_stop = (u32) ~ 0;
12487   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
12488   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
12489   int ret;
12490
12491   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
12492   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
12493   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
12494   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
12495   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
12496   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
12497
12498   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12499     {
12500       if (unformat (i, "del"))
12501         is_add = 0;
12502       if (unformat (i, "outbound"))
12503         is_outbound = 1;
12504       if (unformat (i, "inbound"))
12505         is_outbound = 0;
12506       else if (unformat (i, "spd_id %d", &spd_id))
12507         ;
12508       else if (unformat (i, "sa_id %d", &sa_id))
12509         ;
12510       else if (unformat (i, "priority %d", &priority))
12511         ;
12512       else if (unformat (i, "protocol %d", &protocol))
12513         ;
12514       else if (unformat (i, "lport_start %d", &lport_start))
12515         ;
12516       else if (unformat (i, "lport_stop %d", &lport_stop))
12517         ;
12518       else if (unformat (i, "rport_start %d", &rport_start))
12519         ;
12520       else if (unformat (i, "rport_stop %d", &rport_stop))
12521         ;
12522       else
12523         if (unformat
12524             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
12525         {
12526           is_ipv6 = 0;
12527           is_ip_any = 0;
12528         }
12529       else
12530         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
12531         {
12532           is_ipv6 = 0;
12533           is_ip_any = 0;
12534         }
12535       else
12536         if (unformat
12537             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
12538         {
12539           is_ipv6 = 0;
12540           is_ip_any = 0;
12541         }
12542       else
12543         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
12544         {
12545           is_ipv6 = 0;
12546           is_ip_any = 0;
12547         }
12548       else
12549         if (unformat
12550             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
12551         {
12552           is_ipv6 = 1;
12553           is_ip_any = 0;
12554         }
12555       else
12556         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
12557         {
12558           is_ipv6 = 1;
12559           is_ip_any = 0;
12560         }
12561       else
12562         if (unformat
12563             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
12564         {
12565           is_ipv6 = 1;
12566           is_ip_any = 0;
12567         }
12568       else
12569         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
12570         {
12571           is_ipv6 = 1;
12572           is_ip_any = 0;
12573         }
12574       else
12575         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
12576         {
12577           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
12578             {
12579               clib_warning ("unsupported action: 'resolve'");
12580               return -99;
12581             }
12582         }
12583       else
12584         {
12585           clib_warning ("parse error '%U'", format_unformat_error, i);
12586           return -99;
12587         }
12588
12589     }
12590
12591   M (IPSEC_SPD_ADD_DEL_ENTRY, mp);
12592
12593   mp->spd_id = ntohl (spd_id);
12594   mp->priority = ntohl (priority);
12595   mp->is_outbound = is_outbound;
12596
12597   mp->is_ipv6 = is_ipv6;
12598   if (is_ipv6 || is_ip_any)
12599     {
12600       clib_memcpy (mp->remote_address_start, &raddr6_start,
12601                    sizeof (ip6_address_t));
12602       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
12603                    sizeof (ip6_address_t));
12604       clib_memcpy (mp->local_address_start, &laddr6_start,
12605                    sizeof (ip6_address_t));
12606       clib_memcpy (mp->local_address_stop, &laddr6_stop,
12607                    sizeof (ip6_address_t));
12608     }
12609   else
12610     {
12611       clib_memcpy (mp->remote_address_start, &raddr4_start,
12612                    sizeof (ip4_address_t));
12613       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
12614                    sizeof (ip4_address_t));
12615       clib_memcpy (mp->local_address_start, &laddr4_start,
12616                    sizeof (ip4_address_t));
12617       clib_memcpy (mp->local_address_stop, &laddr4_stop,
12618                    sizeof (ip4_address_t));
12619     }
12620   mp->protocol = (u8) protocol;
12621   mp->local_port_start = ntohs ((u16) lport_start);
12622   mp->local_port_stop = ntohs ((u16) lport_stop);
12623   mp->remote_port_start = ntohs ((u16) rport_start);
12624   mp->remote_port_stop = ntohs ((u16) rport_stop);
12625   mp->policy = (u8) policy;
12626   mp->sa_id = ntohl (sa_id);
12627   mp->is_add = is_add;
12628   mp->is_ip_any = is_ip_any;
12629   S (mp);
12630   W (ret);
12631   return ret;
12632 }
12633
12634 static int
12635 api_ipsec_sad_add_del_entry (vat_main_t * vam)
12636 {
12637   unformat_input_t *i = vam->input;
12638   vl_api_ipsec_sad_add_del_entry_t *mp;
12639   u32 sad_id = 0, spi = 0;
12640   u8 *ck = 0, *ik = 0;
12641   u8 is_add = 1;
12642
12643   u8 protocol = IPSEC_PROTOCOL_AH;
12644   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
12645   u32 crypto_alg = 0, integ_alg = 0;
12646   ip4_address_t tun_src4;
12647   ip4_address_t tun_dst4;
12648   ip6_address_t tun_src6;
12649   ip6_address_t tun_dst6;
12650   int ret;
12651
12652   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12653     {
12654       if (unformat (i, "del"))
12655         is_add = 0;
12656       else if (unformat (i, "sad_id %d", &sad_id))
12657         ;
12658       else if (unformat (i, "spi %d", &spi))
12659         ;
12660       else if (unformat (i, "esp"))
12661         protocol = IPSEC_PROTOCOL_ESP;
12662       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
12663         {
12664           is_tunnel = 1;
12665           is_tunnel_ipv6 = 0;
12666         }
12667       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
12668         {
12669           is_tunnel = 1;
12670           is_tunnel_ipv6 = 0;
12671         }
12672       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
12673         {
12674           is_tunnel = 1;
12675           is_tunnel_ipv6 = 1;
12676         }
12677       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
12678         {
12679           is_tunnel = 1;
12680           is_tunnel_ipv6 = 1;
12681         }
12682       else
12683         if (unformat
12684             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
12685         {
12686           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
12687               crypto_alg >= IPSEC_CRYPTO_N_ALG)
12688             {
12689               clib_warning ("unsupported crypto-alg: '%U'",
12690                             format_ipsec_crypto_alg, crypto_alg);
12691               return -99;
12692             }
12693         }
12694       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
12695         ;
12696       else
12697         if (unformat
12698             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
12699         {
12700           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
12701               integ_alg >= IPSEC_INTEG_N_ALG)
12702             {
12703               clib_warning ("unsupported integ-alg: '%U'",
12704                             format_ipsec_integ_alg, integ_alg);
12705               return -99;
12706             }
12707         }
12708       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
12709         ;
12710       else
12711         {
12712           clib_warning ("parse error '%U'", format_unformat_error, i);
12713           return -99;
12714         }
12715
12716     }
12717
12718   M (IPSEC_SAD_ADD_DEL_ENTRY, mp);
12719
12720   mp->sad_id = ntohl (sad_id);
12721   mp->is_add = is_add;
12722   mp->protocol = protocol;
12723   mp->spi = ntohl (spi);
12724   mp->is_tunnel = is_tunnel;
12725   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
12726   mp->crypto_algorithm = crypto_alg;
12727   mp->integrity_algorithm = integ_alg;
12728   mp->crypto_key_length = vec_len (ck);
12729   mp->integrity_key_length = vec_len (ik);
12730
12731   if (mp->crypto_key_length > sizeof (mp->crypto_key))
12732     mp->crypto_key_length = sizeof (mp->crypto_key);
12733
12734   if (mp->integrity_key_length > sizeof (mp->integrity_key))
12735     mp->integrity_key_length = sizeof (mp->integrity_key);
12736
12737   if (ck)
12738     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
12739   if (ik)
12740     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
12741
12742   if (is_tunnel)
12743     {
12744       if (is_tunnel_ipv6)
12745         {
12746           clib_memcpy (mp->tunnel_src_address, &tun_src6,
12747                        sizeof (ip6_address_t));
12748           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
12749                        sizeof (ip6_address_t));
12750         }
12751       else
12752         {
12753           clib_memcpy (mp->tunnel_src_address, &tun_src4,
12754                        sizeof (ip4_address_t));
12755           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
12756                        sizeof (ip4_address_t));
12757         }
12758     }
12759
12760   S (mp);
12761   W (ret);
12762   return ret;
12763 }
12764
12765 static int
12766 api_ipsec_sa_set_key (vat_main_t * vam)
12767 {
12768   unformat_input_t *i = vam->input;
12769   vl_api_ipsec_sa_set_key_t *mp;
12770   u32 sa_id;
12771   u8 *ck = 0, *ik = 0;
12772   int ret;
12773
12774   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12775     {
12776       if (unformat (i, "sa_id %d", &sa_id))
12777         ;
12778       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
12779         ;
12780       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
12781         ;
12782       else
12783         {
12784           clib_warning ("parse error '%U'", format_unformat_error, i);
12785           return -99;
12786         }
12787     }
12788
12789   M (IPSEC_SA_SET_KEY, mp);
12790
12791   mp->sa_id = ntohl (sa_id);
12792   mp->crypto_key_length = vec_len (ck);
12793   mp->integrity_key_length = vec_len (ik);
12794
12795   if (mp->crypto_key_length > sizeof (mp->crypto_key))
12796     mp->crypto_key_length = sizeof (mp->crypto_key);
12797
12798   if (mp->integrity_key_length > sizeof (mp->integrity_key))
12799     mp->integrity_key_length = sizeof (mp->integrity_key);
12800
12801   if (ck)
12802     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
12803   if (ik)
12804     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
12805
12806   S (mp);
12807   W (ret);
12808   return ret;
12809 }
12810
12811 static int
12812 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
12813 {
12814   unformat_input_t *i = vam->input;
12815   vl_api_ipsec_tunnel_if_add_del_t *mp;
12816   u32 local_spi = 0, remote_spi = 0;
12817   u32 crypto_alg = 0, integ_alg = 0;
12818   u8 *lck = NULL, *rck = NULL;
12819   u8 *lik = NULL, *rik = NULL;
12820   ip4_address_t local_ip = { {0} };
12821   ip4_address_t remote_ip = { {0} };
12822   u8 is_add = 1;
12823   u8 esn = 0;
12824   u8 anti_replay = 0;
12825   int ret;
12826
12827   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12828     {
12829       if (unformat (i, "del"))
12830         is_add = 0;
12831       else if (unformat (i, "esn"))
12832         esn = 1;
12833       else if (unformat (i, "anti_replay"))
12834         anti_replay = 1;
12835       else if (unformat (i, "local_spi %d", &local_spi))
12836         ;
12837       else if (unformat (i, "remote_spi %d", &remote_spi))
12838         ;
12839       else if (unformat (i, "local_ip %U", unformat_ip4_address, &local_ip))
12840         ;
12841       else if (unformat (i, "remote_ip %U", unformat_ip4_address, &remote_ip))
12842         ;
12843       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
12844         ;
12845       else
12846         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
12847         ;
12848       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
12849         ;
12850       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
12851         ;
12852       else
12853         if (unformat
12854             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
12855         {
12856           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
12857               crypto_alg >= IPSEC_CRYPTO_N_ALG)
12858             {
12859               errmsg ("unsupported crypto-alg: '%U'\n",
12860                       format_ipsec_crypto_alg, crypto_alg);
12861               return -99;
12862             }
12863         }
12864       else
12865         if (unformat
12866             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
12867         {
12868           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
12869               integ_alg >= IPSEC_INTEG_N_ALG)
12870             {
12871               errmsg ("unsupported integ-alg: '%U'\n",
12872                       format_ipsec_integ_alg, integ_alg);
12873               return -99;
12874             }
12875         }
12876       else
12877         {
12878           errmsg ("parse error '%U'\n", format_unformat_error, i);
12879           return -99;
12880         }
12881     }
12882
12883   M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
12884
12885   mp->is_add = is_add;
12886   mp->esn = esn;
12887   mp->anti_replay = anti_replay;
12888
12889   clib_memcpy (mp->local_ip, &local_ip, sizeof (ip4_address_t));
12890   clib_memcpy (mp->remote_ip, &remote_ip, sizeof (ip4_address_t));
12891
12892   mp->local_spi = htonl (local_spi);
12893   mp->remote_spi = htonl (remote_spi);
12894   mp->crypto_alg = (u8) crypto_alg;
12895
12896   mp->local_crypto_key_len = 0;
12897   if (lck)
12898     {
12899       mp->local_crypto_key_len = vec_len (lck);
12900       if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
12901         mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
12902       clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
12903     }
12904
12905   mp->remote_crypto_key_len = 0;
12906   if (rck)
12907     {
12908       mp->remote_crypto_key_len = vec_len (rck);
12909       if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
12910         mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
12911       clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
12912     }
12913
12914   mp->integ_alg = (u8) integ_alg;
12915
12916   mp->local_integ_key_len = 0;
12917   if (lik)
12918     {
12919       mp->local_integ_key_len = vec_len (lik);
12920       if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
12921         mp->local_integ_key_len = sizeof (mp->local_integ_key);
12922       clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
12923     }
12924
12925   mp->remote_integ_key_len = 0;
12926   if (rik)
12927     {
12928       mp->remote_integ_key_len = vec_len (rik);
12929       if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
12930         mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
12931       clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
12932     }
12933
12934   S (mp);
12935   W (ret);
12936   return ret;
12937 }
12938
12939 static int
12940 api_ikev2_profile_add_del (vat_main_t * vam)
12941 {
12942   unformat_input_t *i = vam->input;
12943   vl_api_ikev2_profile_add_del_t *mp;
12944   u8 is_add = 1;
12945   u8 *name = 0;
12946   int ret;
12947
12948   const char *valid_chars = "a-zA-Z0-9_";
12949
12950   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12951     {
12952       if (unformat (i, "del"))
12953         is_add = 0;
12954       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12955         vec_add1 (name, 0);
12956       else
12957         {
12958           errmsg ("parse error '%U'", format_unformat_error, i);
12959           return -99;
12960         }
12961     }
12962
12963   if (!vec_len (name))
12964     {
12965       errmsg ("profile name must be specified");
12966       return -99;
12967     }
12968
12969   if (vec_len (name) > 64)
12970     {
12971       errmsg ("profile name too long");
12972       return -99;
12973     }
12974
12975   M (IKEV2_PROFILE_ADD_DEL, mp);
12976
12977   clib_memcpy (mp->name, name, vec_len (name));
12978   mp->is_add = is_add;
12979   vec_free (name);
12980
12981   S (mp);
12982   W (ret);
12983   return ret;
12984 }
12985
12986 static int
12987 api_ikev2_profile_set_auth (vat_main_t * vam)
12988 {
12989   unformat_input_t *i = vam->input;
12990   vl_api_ikev2_profile_set_auth_t *mp;
12991   u8 *name = 0;
12992   u8 *data = 0;
12993   u32 auth_method = 0;
12994   u8 is_hex = 0;
12995   int ret;
12996
12997   const char *valid_chars = "a-zA-Z0-9_";
12998
12999   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13000     {
13001       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
13002         vec_add1 (name, 0);
13003       else if (unformat (i, "auth_method %U",
13004                          unformat_ikev2_auth_method, &auth_method))
13005         ;
13006       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
13007         is_hex = 1;
13008       else if (unformat (i, "auth_data %v", &data))
13009         ;
13010       else
13011         {
13012           errmsg ("parse error '%U'", format_unformat_error, i);
13013           return -99;
13014         }
13015     }
13016
13017   if (!vec_len (name))
13018     {
13019       errmsg ("profile name must be specified");
13020       return -99;
13021     }
13022
13023   if (vec_len (name) > 64)
13024     {
13025       errmsg ("profile name too long");
13026       return -99;
13027     }
13028
13029   if (!vec_len (data))
13030     {
13031       errmsg ("auth_data must be specified");
13032       return -99;
13033     }
13034
13035   if (!auth_method)
13036     {
13037       errmsg ("auth_method must be specified");
13038       return -99;
13039     }
13040
13041   M (IKEV2_PROFILE_SET_AUTH, mp);
13042
13043   mp->is_hex = is_hex;
13044   mp->auth_method = (u8) auth_method;
13045   mp->data_len = vec_len (data);
13046   clib_memcpy (mp->name, name, vec_len (name));
13047   clib_memcpy (mp->data, data, vec_len (data));
13048   vec_free (name);
13049   vec_free (data);
13050
13051   S (mp);
13052   W (ret);
13053   return ret;
13054 }
13055
13056 static int
13057 api_ikev2_profile_set_id (vat_main_t * vam)
13058 {
13059   unformat_input_t *i = vam->input;
13060   vl_api_ikev2_profile_set_id_t *mp;
13061   u8 *name = 0;
13062   u8 *data = 0;
13063   u8 is_local = 0;
13064   u32 id_type = 0;
13065   ip4_address_t ip4;
13066   int ret;
13067
13068   const char *valid_chars = "a-zA-Z0-9_";
13069
13070   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13071     {
13072       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
13073         vec_add1 (name, 0);
13074       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
13075         ;
13076       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
13077         {
13078           data = vec_new (u8, 4);
13079           clib_memcpy (data, ip4.as_u8, 4);
13080         }
13081       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
13082         ;
13083       else if (unformat (i, "id_data %v", &data))
13084         ;
13085       else if (unformat (i, "local"))
13086         is_local = 1;
13087       else if (unformat (i, "remote"))
13088         is_local = 0;
13089       else
13090         {
13091           errmsg ("parse error '%U'", format_unformat_error, i);
13092           return -99;
13093         }
13094     }
13095
13096   if (!vec_len (name))
13097     {
13098       errmsg ("profile name must be specified");
13099       return -99;
13100     }
13101
13102   if (vec_len (name) > 64)
13103     {
13104       errmsg ("profile name too long");
13105       return -99;
13106     }
13107
13108   if (!vec_len (data))
13109     {
13110       errmsg ("id_data must be specified");
13111       return -99;
13112     }
13113
13114   if (!id_type)
13115     {
13116       errmsg ("id_type must be specified");
13117       return -99;
13118     }
13119
13120   M (IKEV2_PROFILE_SET_ID, mp);
13121
13122   mp->is_local = is_local;
13123   mp->id_type = (u8) id_type;
13124   mp->data_len = vec_len (data);
13125   clib_memcpy (mp->name, name, vec_len (name));
13126   clib_memcpy (mp->data, data, vec_len (data));
13127   vec_free (name);
13128   vec_free (data);
13129
13130   S (mp);
13131   W (ret);
13132   return ret;
13133 }
13134
13135 static int
13136 api_ikev2_profile_set_ts (vat_main_t * vam)
13137 {
13138   unformat_input_t *i = vam->input;
13139   vl_api_ikev2_profile_set_ts_t *mp;
13140   u8 *name = 0;
13141   u8 is_local = 0;
13142   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
13143   ip4_address_t start_addr, end_addr;
13144
13145   const char *valid_chars = "a-zA-Z0-9_";
13146   int ret;
13147
13148   start_addr.as_u32 = 0;
13149   end_addr.as_u32 = (u32) ~ 0;
13150
13151   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13152     {
13153       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
13154         vec_add1 (name, 0);
13155       else if (unformat (i, "protocol %d", &proto))
13156         ;
13157       else if (unformat (i, "start_port %d", &start_port))
13158         ;
13159       else if (unformat (i, "end_port %d", &end_port))
13160         ;
13161       else
13162         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
13163         ;
13164       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
13165         ;
13166       else if (unformat (i, "local"))
13167         is_local = 1;
13168       else if (unformat (i, "remote"))
13169         is_local = 0;
13170       else
13171         {
13172           errmsg ("parse error '%U'", format_unformat_error, i);
13173           return -99;
13174         }
13175     }
13176
13177   if (!vec_len (name))
13178     {
13179       errmsg ("profile name must be specified");
13180       return -99;
13181     }
13182
13183   if (vec_len (name) > 64)
13184     {
13185       errmsg ("profile name too long");
13186       return -99;
13187     }
13188
13189   M (IKEV2_PROFILE_SET_TS, mp);
13190
13191   mp->is_local = is_local;
13192   mp->proto = (u8) proto;
13193   mp->start_port = (u16) start_port;
13194   mp->end_port = (u16) end_port;
13195   mp->start_addr = start_addr.as_u32;
13196   mp->end_addr = end_addr.as_u32;
13197   clib_memcpy (mp->name, name, vec_len (name));
13198   vec_free (name);
13199
13200   S (mp);
13201   W (ret);
13202   return ret;
13203 }
13204
13205 static int
13206 api_ikev2_set_local_key (vat_main_t * vam)
13207 {
13208   unformat_input_t *i = vam->input;
13209   vl_api_ikev2_set_local_key_t *mp;
13210   u8 *file = 0;
13211   int ret;
13212
13213   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13214     {
13215       if (unformat (i, "file %v", &file))
13216         vec_add1 (file, 0);
13217       else
13218         {
13219           errmsg ("parse error '%U'", format_unformat_error, i);
13220           return -99;
13221         }
13222     }
13223
13224   if (!vec_len (file))
13225     {
13226       errmsg ("RSA key file must be specified");
13227       return -99;
13228     }
13229
13230   if (vec_len (file) > 256)
13231     {
13232       errmsg ("file name too long");
13233       return -99;
13234     }
13235
13236   M (IKEV2_SET_LOCAL_KEY, mp);
13237
13238   clib_memcpy (mp->key_file, file, vec_len (file));
13239   vec_free (file);
13240
13241   S (mp);
13242   W (ret);
13243   return ret;
13244 }
13245
13246 static int
13247 api_ikev2_set_responder (vat_main_t * vam)
13248 {
13249   unformat_input_t *i = vam->input;
13250   vl_api_ikev2_set_responder_t *mp;
13251   int ret;
13252   u8 *name = 0;
13253   u32 sw_if_index = ~0;
13254   ip4_address_t address;
13255
13256   const char *valid_chars = "a-zA-Z0-9_";
13257
13258   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13259     {
13260       if (unformat
13261           (i, "%U interface %d address %U", unformat_token, valid_chars,
13262            &name, &sw_if_index, unformat_ip4_address, &address))
13263         vec_add1 (name, 0);
13264       else
13265         {
13266           errmsg ("parse error '%U'", format_unformat_error, i);
13267           return -99;
13268         }
13269     }
13270
13271   if (!vec_len (name))
13272     {
13273       errmsg ("profile name must be specified");
13274       return -99;
13275     }
13276
13277   if (vec_len (name) > 64)
13278     {
13279       errmsg ("profile name too long");
13280       return -99;
13281     }
13282
13283   M (IKEV2_SET_RESPONDER, mp);
13284
13285   clib_memcpy (mp->name, name, vec_len (name));
13286   vec_free (name);
13287
13288   mp->sw_if_index = sw_if_index;
13289   clib_memcpy (mp->address, &address, sizeof (address));
13290
13291   S (mp);
13292   W (ret);
13293   return ret;
13294 }
13295
13296 static int
13297 api_ikev2_set_ike_transforms (vat_main_t * vam)
13298 {
13299   unformat_input_t *i = vam->input;
13300   vl_api_ikev2_set_ike_transforms_t *mp;
13301   int ret;
13302   u8 *name = 0;
13303   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
13304
13305   const char *valid_chars = "a-zA-Z0-9_";
13306
13307   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13308     {
13309       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
13310                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
13311         vec_add1 (name, 0);
13312       else
13313         {
13314           errmsg ("parse error '%U'", format_unformat_error, i);
13315           return -99;
13316         }
13317     }
13318
13319   if (!vec_len (name))
13320     {
13321       errmsg ("profile name must be specified");
13322       return -99;
13323     }
13324
13325   if (vec_len (name) > 64)
13326     {
13327       errmsg ("profile name too long");
13328       return -99;
13329     }
13330
13331   M (IKEV2_SET_IKE_TRANSFORMS, mp);
13332
13333   clib_memcpy (mp->name, name, vec_len (name));
13334   vec_free (name);
13335   mp->crypto_alg = crypto_alg;
13336   mp->crypto_key_size = crypto_key_size;
13337   mp->integ_alg = integ_alg;
13338   mp->dh_group = dh_group;
13339
13340   S (mp);
13341   W (ret);
13342   return ret;
13343 }
13344
13345
13346 static int
13347 api_ikev2_set_esp_transforms (vat_main_t * vam)
13348 {
13349   unformat_input_t *i = vam->input;
13350   vl_api_ikev2_set_esp_transforms_t *mp;
13351   int ret;
13352   u8 *name = 0;
13353   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
13354
13355   const char *valid_chars = "a-zA-Z0-9_";
13356
13357   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13358     {
13359       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
13360                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
13361         vec_add1 (name, 0);
13362       else
13363         {
13364           errmsg ("parse error '%U'", format_unformat_error, i);
13365           return -99;
13366         }
13367     }
13368
13369   if (!vec_len (name))
13370     {
13371       errmsg ("profile name must be specified");
13372       return -99;
13373     }
13374
13375   if (vec_len (name) > 64)
13376     {
13377       errmsg ("profile name too long");
13378       return -99;
13379     }
13380
13381   M (IKEV2_SET_ESP_TRANSFORMS, mp);
13382
13383   clib_memcpy (mp->name, name, vec_len (name));
13384   vec_free (name);
13385   mp->crypto_alg = crypto_alg;
13386   mp->crypto_key_size = crypto_key_size;
13387   mp->integ_alg = integ_alg;
13388   mp->dh_group = dh_group;
13389
13390   S (mp);
13391   W (ret);
13392   return ret;
13393 }
13394
13395 static int
13396 api_ikev2_set_sa_lifetime (vat_main_t * vam)
13397 {
13398   unformat_input_t *i = vam->input;
13399   vl_api_ikev2_set_sa_lifetime_t *mp;
13400   int ret;
13401   u8 *name = 0;
13402   u64 lifetime, lifetime_maxdata;
13403   u32 lifetime_jitter, handover;
13404
13405   const char *valid_chars = "a-zA-Z0-9_";
13406
13407   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13408     {
13409       if (unformat (i, "%U %lu %u %u %lu", unformat_token, valid_chars, &name,
13410                     &lifetime, &lifetime_jitter, &handover,
13411                     &lifetime_maxdata))
13412         vec_add1 (name, 0);
13413       else
13414         {
13415           errmsg ("parse error '%U'", format_unformat_error, i);
13416           return -99;
13417         }
13418     }
13419
13420   if (!vec_len (name))
13421     {
13422       errmsg ("profile name must be specified");
13423       return -99;
13424     }
13425
13426   if (vec_len (name) > 64)
13427     {
13428       errmsg ("profile name too long");
13429       return -99;
13430     }
13431
13432   M (IKEV2_SET_SA_LIFETIME, mp);
13433
13434   clib_memcpy (mp->name, name, vec_len (name));
13435   vec_free (name);
13436   mp->lifetime = lifetime;
13437   mp->lifetime_jitter = lifetime_jitter;
13438   mp->handover = handover;
13439   mp->lifetime_maxdata = lifetime_maxdata;
13440
13441   S (mp);
13442   W (ret);
13443   return ret;
13444 }
13445
13446 static int
13447 api_ikev2_initiate_sa_init (vat_main_t * vam)
13448 {
13449   unformat_input_t *i = vam->input;
13450   vl_api_ikev2_initiate_sa_init_t *mp;
13451   int ret;
13452   u8 *name = 0;
13453
13454   const char *valid_chars = "a-zA-Z0-9_";
13455
13456   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13457     {
13458       if (unformat (i, "%U", unformat_token, valid_chars, &name))
13459         vec_add1 (name, 0);
13460       else
13461         {
13462           errmsg ("parse error '%U'", format_unformat_error, i);
13463           return -99;
13464         }
13465     }
13466
13467   if (!vec_len (name))
13468     {
13469       errmsg ("profile name must be specified");
13470       return -99;
13471     }
13472
13473   if (vec_len (name) > 64)
13474     {
13475       errmsg ("profile name too long");
13476       return -99;
13477     }
13478
13479   M (IKEV2_INITIATE_SA_INIT, mp);
13480
13481   clib_memcpy (mp->name, name, vec_len (name));
13482   vec_free (name);
13483
13484   S (mp);
13485   W (ret);
13486   return ret;
13487 }
13488
13489 static int
13490 api_ikev2_initiate_del_ike_sa (vat_main_t * vam)
13491 {
13492   unformat_input_t *i = vam->input;
13493   vl_api_ikev2_initiate_del_ike_sa_t *mp;
13494   int ret;
13495   u64 ispi;
13496
13497
13498   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13499     {
13500       if (unformat (i, "%lx", &ispi))
13501         ;
13502       else
13503         {
13504           errmsg ("parse error '%U'", format_unformat_error, i);
13505           return -99;
13506         }
13507     }
13508
13509   M (IKEV2_INITIATE_DEL_IKE_SA, mp);
13510
13511   mp->ispi = ispi;
13512
13513   S (mp);
13514   W (ret);
13515   return ret;
13516 }
13517
13518 static int
13519 api_ikev2_initiate_del_child_sa (vat_main_t * vam)
13520 {
13521   unformat_input_t *i = vam->input;
13522   vl_api_ikev2_initiate_del_child_sa_t *mp;
13523   int ret;
13524   u32 ispi;
13525
13526
13527   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13528     {
13529       if (unformat (i, "%x", &ispi))
13530         ;
13531       else
13532         {
13533           errmsg ("parse error '%U'", format_unformat_error, i);
13534           return -99;
13535         }
13536     }
13537
13538   M (IKEV2_INITIATE_DEL_CHILD_SA, mp);
13539
13540   mp->ispi = ispi;
13541
13542   S (mp);
13543   W (ret);
13544   return ret;
13545 }
13546
13547 static int
13548 api_ikev2_initiate_rekey_child_sa (vat_main_t * vam)
13549 {
13550   unformat_input_t *i = vam->input;
13551   vl_api_ikev2_initiate_rekey_child_sa_t *mp;
13552   int ret;
13553   u32 ispi;
13554
13555
13556   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13557     {
13558       if (unformat (i, "%x", &ispi))
13559         ;
13560       else
13561         {
13562           errmsg ("parse error '%U'", format_unformat_error, i);
13563           return -99;
13564         }
13565     }
13566
13567   M (IKEV2_INITIATE_REKEY_CHILD_SA, mp);
13568
13569   mp->ispi = ispi;
13570
13571   S (mp);
13572   W (ret);
13573   return ret;
13574 }
13575
13576 /*
13577  * MAP
13578  */
13579 static int
13580 api_map_add_domain (vat_main_t * vam)
13581 {
13582   unformat_input_t *i = vam->input;
13583   vl_api_map_add_domain_t *mp;
13584
13585   ip4_address_t ip4_prefix;
13586   ip6_address_t ip6_prefix;
13587   ip6_address_t ip6_src;
13588   u32 num_m_args = 0;
13589   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
13590     0, psid_length = 0;
13591   u8 is_translation = 0;
13592   u32 mtu = 0;
13593   u32 ip6_src_len = 128;
13594   int ret;
13595
13596   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13597     {
13598       if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
13599                     &ip4_prefix, &ip4_prefix_len))
13600         num_m_args++;
13601       else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
13602                          &ip6_prefix, &ip6_prefix_len))
13603         num_m_args++;
13604       else
13605         if (unformat
13606             (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
13607              &ip6_src_len))
13608         num_m_args++;
13609       else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
13610         num_m_args++;
13611       else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
13612         num_m_args++;
13613       else if (unformat (i, "psid-offset %d", &psid_offset))
13614         num_m_args++;
13615       else if (unformat (i, "psid-len %d", &psid_length))
13616         num_m_args++;
13617       else if (unformat (i, "mtu %d", &mtu))
13618         num_m_args++;
13619       else if (unformat (i, "map-t"))
13620         is_translation = 1;
13621       else
13622         {
13623           clib_warning ("parse error '%U'", format_unformat_error, i);
13624           return -99;
13625         }
13626     }
13627
13628   if (num_m_args < 3)
13629     {
13630       errmsg ("mandatory argument(s) missing");
13631       return -99;
13632     }
13633
13634   /* Construct the API message */
13635   M (MAP_ADD_DOMAIN, mp);
13636
13637   clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
13638   mp->ip4_prefix_len = ip4_prefix_len;
13639
13640   clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
13641   mp->ip6_prefix_len = ip6_prefix_len;
13642
13643   clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
13644   mp->ip6_src_prefix_len = ip6_src_len;
13645
13646   mp->ea_bits_len = ea_bits_len;
13647   mp->psid_offset = psid_offset;
13648   mp->psid_length = psid_length;
13649   mp->is_translation = is_translation;
13650   mp->mtu = htons (mtu);
13651
13652   /* send it... */
13653   S (mp);
13654
13655   /* Wait for a reply, return good/bad news  */
13656   W (ret);
13657   return ret;
13658 }
13659
13660 static int
13661 api_map_del_domain (vat_main_t * vam)
13662 {
13663   unformat_input_t *i = vam->input;
13664   vl_api_map_del_domain_t *mp;
13665
13666   u32 num_m_args = 0;
13667   u32 index;
13668   int ret;
13669
13670   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13671     {
13672       if (unformat (i, "index %d", &index))
13673         num_m_args++;
13674       else
13675         {
13676           clib_warning ("parse error '%U'", format_unformat_error, i);
13677           return -99;
13678         }
13679     }
13680
13681   if (num_m_args != 1)
13682     {
13683       errmsg ("mandatory argument(s) missing");
13684       return -99;
13685     }
13686
13687   /* Construct the API message */
13688   M (MAP_DEL_DOMAIN, mp);
13689
13690   mp->index = ntohl (index);
13691
13692   /* send it... */
13693   S (mp);
13694
13695   /* Wait for a reply, return good/bad news  */
13696   W (ret);
13697   return ret;
13698 }
13699
13700 static int
13701 api_map_add_del_rule (vat_main_t * vam)
13702 {
13703   unformat_input_t *i = vam->input;
13704   vl_api_map_add_del_rule_t *mp;
13705   u8 is_add = 1;
13706   ip6_address_t ip6_dst;
13707   u32 num_m_args = 0, index, psid = 0;
13708   int ret;
13709
13710   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13711     {
13712       if (unformat (i, "index %d", &index))
13713         num_m_args++;
13714       else if (unformat (i, "psid %d", &psid))
13715         num_m_args++;
13716       else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
13717         num_m_args++;
13718       else if (unformat (i, "del"))
13719         {
13720           is_add = 0;
13721         }
13722       else
13723         {
13724           clib_warning ("parse error '%U'", format_unformat_error, i);
13725           return -99;
13726         }
13727     }
13728
13729   /* Construct the API message */
13730   M (MAP_ADD_DEL_RULE, mp);
13731
13732   mp->index = ntohl (index);
13733   mp->is_add = is_add;
13734   clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
13735   mp->psid = ntohs (psid);
13736
13737   /* send it... */
13738   S (mp);
13739
13740   /* Wait for a reply, return good/bad news  */
13741   W (ret);
13742   return ret;
13743 }
13744
13745 static int
13746 api_map_domain_dump (vat_main_t * vam)
13747 {
13748   vl_api_map_domain_dump_t *mp;
13749   vl_api_control_ping_t *mp_ping;
13750   int ret;
13751
13752   /* Construct the API message */
13753   M (MAP_DOMAIN_DUMP, mp);
13754
13755   /* send it... */
13756   S (mp);
13757
13758   /* Use a control ping for synchronization */
13759   M (CONTROL_PING, mp_ping);
13760   S (mp_ping);
13761
13762   W (ret);
13763   return ret;
13764 }
13765
13766 static int
13767 api_map_rule_dump (vat_main_t * vam)
13768 {
13769   unformat_input_t *i = vam->input;
13770   vl_api_map_rule_dump_t *mp;
13771   vl_api_control_ping_t *mp_ping;
13772   u32 domain_index = ~0;
13773   int ret;
13774
13775   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13776     {
13777       if (unformat (i, "index %u", &domain_index))
13778         ;
13779       else
13780         break;
13781     }
13782
13783   if (domain_index == ~0)
13784     {
13785       clib_warning ("parse error: domain index expected");
13786       return -99;
13787     }
13788
13789   /* Construct the API message */
13790   M (MAP_RULE_DUMP, mp);
13791
13792   mp->domain_index = htonl (domain_index);
13793
13794   /* send it... */
13795   S (mp);
13796
13797   /* Use a control ping for synchronization */
13798   M (CONTROL_PING, mp_ping);
13799   S (mp_ping);
13800
13801   W (ret);
13802   return ret;
13803 }
13804
13805 static void vl_api_map_add_domain_reply_t_handler
13806   (vl_api_map_add_domain_reply_t * mp)
13807 {
13808   vat_main_t *vam = &vat_main;
13809   i32 retval = ntohl (mp->retval);
13810
13811   if (vam->async_mode)
13812     {
13813       vam->async_errors += (retval < 0);
13814     }
13815   else
13816     {
13817       vam->retval = retval;
13818       vam->result_ready = 1;
13819     }
13820 }
13821
13822 static void vl_api_map_add_domain_reply_t_handler_json
13823   (vl_api_map_add_domain_reply_t * mp)
13824 {
13825   vat_main_t *vam = &vat_main;
13826   vat_json_node_t node;
13827
13828   vat_json_init_object (&node);
13829   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
13830   vat_json_object_add_uint (&node, "index", ntohl (mp->index));
13831
13832   vat_json_print (vam->ofp, &node);
13833   vat_json_free (&node);
13834
13835   vam->retval = ntohl (mp->retval);
13836   vam->result_ready = 1;
13837 }
13838
13839 static int
13840 api_get_first_msg_id (vat_main_t * vam)
13841 {
13842   vl_api_get_first_msg_id_t *mp;
13843   unformat_input_t *i = vam->input;
13844   u8 *name;
13845   u8 name_set = 0;
13846   int ret;
13847
13848   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13849     {
13850       if (unformat (i, "client %s", &name))
13851         name_set = 1;
13852       else
13853         break;
13854     }
13855
13856   if (name_set == 0)
13857     {
13858       errmsg ("missing client name");
13859       return -99;
13860     }
13861   vec_add1 (name, 0);
13862
13863   if (vec_len (name) > 63)
13864     {
13865       errmsg ("client name too long");
13866       return -99;
13867     }
13868
13869   M (GET_FIRST_MSG_ID, mp);
13870   clib_memcpy (mp->name, name, vec_len (name));
13871   S (mp);
13872   W (ret);
13873   return ret;
13874 }
13875
13876 static int
13877 api_cop_interface_enable_disable (vat_main_t * vam)
13878 {
13879   unformat_input_t *line_input = vam->input;
13880   vl_api_cop_interface_enable_disable_t *mp;
13881   u32 sw_if_index = ~0;
13882   u8 enable_disable = 1;
13883   int ret;
13884
13885   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13886     {
13887       if (unformat (line_input, "disable"))
13888         enable_disable = 0;
13889       if (unformat (line_input, "enable"))
13890         enable_disable = 1;
13891       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
13892                          vam, &sw_if_index))
13893         ;
13894       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13895         ;
13896       else
13897         break;
13898     }
13899
13900   if (sw_if_index == ~0)
13901     {
13902       errmsg ("missing interface name or sw_if_index");
13903       return -99;
13904     }
13905
13906   /* Construct the API message */
13907   M (COP_INTERFACE_ENABLE_DISABLE, mp);
13908   mp->sw_if_index = ntohl (sw_if_index);
13909   mp->enable_disable = enable_disable;
13910
13911   /* send it... */
13912   S (mp);
13913   /* Wait for the reply */
13914   W (ret);
13915   return ret;
13916 }
13917
13918 static int
13919 api_cop_whitelist_enable_disable (vat_main_t * vam)
13920 {
13921   unformat_input_t *line_input = vam->input;
13922   vl_api_cop_whitelist_enable_disable_t *mp;
13923   u32 sw_if_index = ~0;
13924   u8 ip4 = 0, ip6 = 0, default_cop = 0;
13925   u32 fib_id = 0;
13926   int ret;
13927
13928   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13929     {
13930       if (unformat (line_input, "ip4"))
13931         ip4 = 1;
13932       else if (unformat (line_input, "ip6"))
13933         ip6 = 1;
13934       else if (unformat (line_input, "default"))
13935         default_cop = 1;
13936       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
13937                          vam, &sw_if_index))
13938         ;
13939       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13940         ;
13941       else if (unformat (line_input, "fib-id %d", &fib_id))
13942         ;
13943       else
13944         break;
13945     }
13946
13947   if (sw_if_index == ~0)
13948     {
13949       errmsg ("missing interface name or sw_if_index");
13950       return -99;
13951     }
13952
13953   /* Construct the API message */
13954   M (COP_WHITELIST_ENABLE_DISABLE, mp);
13955   mp->sw_if_index = ntohl (sw_if_index);
13956   mp->fib_id = ntohl (fib_id);
13957   mp->ip4 = ip4;
13958   mp->ip6 = ip6;
13959   mp->default_cop = default_cop;
13960
13961   /* send it... */
13962   S (mp);
13963   /* Wait for the reply */
13964   W (ret);
13965   return ret;
13966 }
13967
13968 static int
13969 api_get_node_graph (vat_main_t * vam)
13970 {
13971   vl_api_get_node_graph_t *mp;
13972   int ret;
13973
13974   M (GET_NODE_GRAPH, mp);
13975
13976   /* send it... */
13977   S (mp);
13978   /* Wait for the reply */
13979   W (ret);
13980   return ret;
13981 }
13982
13983 /* *INDENT-OFF* */
13984 /** Used for parsing LISP eids */
13985 typedef CLIB_PACKED(struct{
13986   u8 addr[16];   /**< eid address */
13987   u32 len;       /**< prefix length if IP */
13988   u8 type;      /**< type of eid */
13989 }) lisp_eid_vat_t;
13990 /* *INDENT-ON* */
13991
13992 static uword
13993 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
13994 {
13995   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
13996
13997   memset (a, 0, sizeof (a[0]));
13998
13999   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
14000     {
14001       a->type = 0;              /* ipv4 type */
14002     }
14003   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
14004     {
14005       a->type = 1;              /* ipv6 type */
14006     }
14007   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
14008     {
14009       a->type = 2;              /* mac type */
14010     }
14011   else
14012     {
14013       return 0;
14014     }
14015
14016   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
14017     {
14018       return 0;
14019     }
14020
14021   return 1;
14022 }
14023
14024 static int
14025 lisp_eid_size_vat (u8 type)
14026 {
14027   switch (type)
14028     {
14029     case 0:
14030       return 4;
14031     case 1:
14032       return 16;
14033     case 2:
14034       return 6;
14035     }
14036   return 0;
14037 }
14038
14039 static void
14040 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
14041 {
14042   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
14043 }
14044
14045 static int
14046 api_one_add_del_locator_set (vat_main_t * vam)
14047 {
14048   unformat_input_t *input = vam->input;
14049   vl_api_one_add_del_locator_set_t *mp;
14050   u8 is_add = 1;
14051   u8 *locator_set_name = NULL;
14052   u8 locator_set_name_set = 0;
14053   vl_api_local_locator_t locator, *locators = 0;
14054   u32 sw_if_index, priority, weight;
14055   u32 data_len = 0;
14056
14057   int ret;
14058   /* Parse args required to build the message */
14059   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14060     {
14061       if (unformat (input, "del"))
14062         {
14063           is_add = 0;
14064         }
14065       else if (unformat (input, "locator-set %s", &locator_set_name))
14066         {
14067           locator_set_name_set = 1;
14068         }
14069       else if (unformat (input, "sw_if_index %u p %u w %u",
14070                          &sw_if_index, &priority, &weight))
14071         {
14072           locator.sw_if_index = htonl (sw_if_index);
14073           locator.priority = priority;
14074           locator.weight = weight;
14075           vec_add1 (locators, locator);
14076         }
14077       else
14078         if (unformat
14079             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
14080              &sw_if_index, &priority, &weight))
14081         {
14082           locator.sw_if_index = htonl (sw_if_index);
14083           locator.priority = priority;
14084           locator.weight = weight;
14085           vec_add1 (locators, locator);
14086         }
14087       else
14088         break;
14089     }
14090
14091   if (locator_set_name_set == 0)
14092     {
14093       errmsg ("missing locator-set name");
14094       vec_free (locators);
14095       return -99;
14096     }
14097
14098   if (vec_len (locator_set_name) > 64)
14099     {
14100       errmsg ("locator-set name too long");
14101       vec_free (locator_set_name);
14102       vec_free (locators);
14103       return -99;
14104     }
14105   vec_add1 (locator_set_name, 0);
14106
14107   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
14108
14109   /* Construct the API message */
14110   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
14111
14112   mp->is_add = is_add;
14113   clib_memcpy (mp->locator_set_name, locator_set_name,
14114                vec_len (locator_set_name));
14115   vec_free (locator_set_name);
14116
14117   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
14118   if (locators)
14119     clib_memcpy (mp->locators, locators, data_len);
14120   vec_free (locators);
14121
14122   /* send it... */
14123   S (mp);
14124
14125   /* Wait for a reply... */
14126   W (ret);
14127   return ret;
14128 }
14129
14130 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
14131
14132 static int
14133 api_one_add_del_locator (vat_main_t * vam)
14134 {
14135   unformat_input_t *input = vam->input;
14136   vl_api_one_add_del_locator_t *mp;
14137   u32 tmp_if_index = ~0;
14138   u32 sw_if_index = ~0;
14139   u8 sw_if_index_set = 0;
14140   u8 sw_if_index_if_name_set = 0;
14141   u32 priority = ~0;
14142   u8 priority_set = 0;
14143   u32 weight = ~0;
14144   u8 weight_set = 0;
14145   u8 is_add = 1;
14146   u8 *locator_set_name = NULL;
14147   u8 locator_set_name_set = 0;
14148   int ret;
14149
14150   /* Parse args required to build the message */
14151   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14152     {
14153       if (unformat (input, "del"))
14154         {
14155           is_add = 0;
14156         }
14157       else if (unformat (input, "locator-set %s", &locator_set_name))
14158         {
14159           locator_set_name_set = 1;
14160         }
14161       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
14162                          &tmp_if_index))
14163         {
14164           sw_if_index_if_name_set = 1;
14165           sw_if_index = tmp_if_index;
14166         }
14167       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
14168         {
14169           sw_if_index_set = 1;
14170           sw_if_index = tmp_if_index;
14171         }
14172       else if (unformat (input, "p %d", &priority))
14173         {
14174           priority_set = 1;
14175         }
14176       else if (unformat (input, "w %d", &weight))
14177         {
14178           weight_set = 1;
14179         }
14180       else
14181         break;
14182     }
14183
14184   if (locator_set_name_set == 0)
14185     {
14186       errmsg ("missing locator-set name");
14187       return -99;
14188     }
14189
14190   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
14191     {
14192       errmsg ("missing sw_if_index");
14193       vec_free (locator_set_name);
14194       return -99;
14195     }
14196
14197   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
14198     {
14199       errmsg ("cannot use both params interface name and sw_if_index");
14200       vec_free (locator_set_name);
14201       return -99;
14202     }
14203
14204   if (priority_set == 0)
14205     {
14206       errmsg ("missing locator-set priority");
14207       vec_free (locator_set_name);
14208       return -99;
14209     }
14210
14211   if (weight_set == 0)
14212     {
14213       errmsg ("missing locator-set weight");
14214       vec_free (locator_set_name);
14215       return -99;
14216     }
14217
14218   if (vec_len (locator_set_name) > 64)
14219     {
14220       errmsg ("locator-set name too long");
14221       vec_free (locator_set_name);
14222       return -99;
14223     }
14224   vec_add1 (locator_set_name, 0);
14225
14226   /* Construct the API message */
14227   M (ONE_ADD_DEL_LOCATOR, mp);
14228
14229   mp->is_add = is_add;
14230   mp->sw_if_index = ntohl (sw_if_index);
14231   mp->priority = priority;
14232   mp->weight = weight;
14233   clib_memcpy (mp->locator_set_name, locator_set_name,
14234                vec_len (locator_set_name));
14235   vec_free (locator_set_name);
14236
14237   /* send it... */
14238   S (mp);
14239
14240   /* Wait for a reply... */
14241   W (ret);
14242   return ret;
14243 }
14244
14245 #define api_lisp_add_del_locator api_one_add_del_locator
14246
14247 uword
14248 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
14249 {
14250   u32 *key_id = va_arg (*args, u32 *);
14251   u8 *s = 0;
14252
14253   if (unformat (input, "%s", &s))
14254     {
14255       if (!strcmp ((char *) s, "sha1"))
14256         key_id[0] = HMAC_SHA_1_96;
14257       else if (!strcmp ((char *) s, "sha256"))
14258         key_id[0] = HMAC_SHA_256_128;
14259       else
14260         {
14261           clib_warning ("invalid key_id: '%s'", s);
14262           key_id[0] = HMAC_NO_KEY;
14263         }
14264     }
14265   else
14266     return 0;
14267
14268   vec_free (s);
14269   return 1;
14270 }
14271
14272 static int
14273 api_one_add_del_local_eid (vat_main_t * vam)
14274 {
14275   unformat_input_t *input = vam->input;
14276   vl_api_one_add_del_local_eid_t *mp;
14277   u8 is_add = 1;
14278   u8 eid_set = 0;
14279   lisp_eid_vat_t _eid, *eid = &_eid;
14280   u8 *locator_set_name = 0;
14281   u8 locator_set_name_set = 0;
14282   u32 vni = 0;
14283   u16 key_id = 0;
14284   u8 *key = 0;
14285   int ret;
14286
14287   /* Parse args required to build the message */
14288   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14289     {
14290       if (unformat (input, "del"))
14291         {
14292           is_add = 0;
14293         }
14294       else if (unformat (input, "vni %d", &vni))
14295         {
14296           ;
14297         }
14298       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
14299         {
14300           eid_set = 1;
14301         }
14302       else if (unformat (input, "locator-set %s", &locator_set_name))
14303         {
14304           locator_set_name_set = 1;
14305         }
14306       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
14307         ;
14308       else if (unformat (input, "secret-key %_%v%_", &key))
14309         ;
14310       else
14311         break;
14312     }
14313
14314   if (locator_set_name_set == 0)
14315     {
14316       errmsg ("missing locator-set name");
14317       return -99;
14318     }
14319
14320   if (0 == eid_set)
14321     {
14322       errmsg ("EID address not set!");
14323       vec_free (locator_set_name);
14324       return -99;
14325     }
14326
14327   if (key && (0 == key_id))
14328     {
14329       errmsg ("invalid key_id!");
14330       return -99;
14331     }
14332
14333   if (vec_len (key) > 64)
14334     {
14335       errmsg ("key too long");
14336       vec_free (key);
14337       return -99;
14338     }
14339
14340   if (vec_len (locator_set_name) > 64)
14341     {
14342       errmsg ("locator-set name too long");
14343       vec_free (locator_set_name);
14344       return -99;
14345     }
14346   vec_add1 (locator_set_name, 0);
14347
14348   /* Construct the API message */
14349   M (ONE_ADD_DEL_LOCAL_EID, mp);
14350
14351   mp->is_add = is_add;
14352   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
14353   mp->eid_type = eid->type;
14354   mp->prefix_len = eid->len;
14355   mp->vni = clib_host_to_net_u32 (vni);
14356   mp->key_id = clib_host_to_net_u16 (key_id);
14357   clib_memcpy (mp->locator_set_name, locator_set_name,
14358                vec_len (locator_set_name));
14359   clib_memcpy (mp->key, key, vec_len (key));
14360
14361   vec_free (locator_set_name);
14362   vec_free (key);
14363
14364   /* send it... */
14365   S (mp);
14366
14367   /* Wait for a reply... */
14368   W (ret);
14369   return ret;
14370 }
14371
14372 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
14373
14374 static int
14375 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
14376 {
14377   u32 dp_table = 0, vni = 0;;
14378   unformat_input_t *input = vam->input;
14379   vl_api_gpe_add_del_fwd_entry_t *mp;
14380   u8 is_add = 1;
14381   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
14382   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
14383   u8 rmt_eid_set = 0, lcl_eid_set = 0;
14384   u32 action = ~0, w;
14385   ip4_address_t rmt_rloc4, lcl_rloc4;
14386   ip6_address_t rmt_rloc6, lcl_rloc6;
14387   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
14388   int ret;
14389
14390   memset (&rloc, 0, sizeof (rloc));
14391
14392   /* Parse args required to build the message */
14393   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14394     {
14395       if (unformat (input, "del"))
14396         is_add = 0;
14397       else if (unformat (input, "add"))
14398         is_add = 1;
14399       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
14400         {
14401           rmt_eid_set = 1;
14402         }
14403       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
14404         {
14405           lcl_eid_set = 1;
14406         }
14407       else if (unformat (input, "vrf %d", &dp_table))
14408         ;
14409       else if (unformat (input, "bd %d", &dp_table))
14410         ;
14411       else if (unformat (input, "vni %d", &vni))
14412         ;
14413       else if (unformat (input, "w %d", &w))
14414         {
14415           if (!curr_rloc)
14416             {
14417               errmsg ("No RLOC configured for setting priority/weight!");
14418               return -99;
14419             }
14420           curr_rloc->weight = w;
14421         }
14422       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
14423                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
14424         {
14425           rloc.is_ip4 = 1;
14426
14427           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
14428           rloc.weight = 0;
14429           vec_add1 (lcl_locs, rloc);
14430
14431           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
14432           vec_add1 (rmt_locs, rloc);
14433           /* weight saved in rmt loc */
14434           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
14435         }
14436       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
14437                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
14438         {
14439           rloc.is_ip4 = 0;
14440           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
14441           rloc.weight = 0;
14442           vec_add1 (lcl_locs, rloc);
14443
14444           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
14445           vec_add1 (rmt_locs, rloc);
14446           /* weight saved in rmt loc */
14447           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
14448         }
14449       else if (unformat (input, "action %d", &action))
14450         {
14451           ;
14452         }
14453       else
14454         {
14455           clib_warning ("parse error '%U'", format_unformat_error, input);
14456           return -99;
14457         }
14458     }
14459
14460   if (!rmt_eid_set)
14461     {
14462       errmsg ("remote eid addresses not set");
14463       return -99;
14464     }
14465
14466   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
14467     {
14468       errmsg ("eid types don't match");
14469       return -99;
14470     }
14471
14472   if (0 == rmt_locs && (u32) ~ 0 == action)
14473     {
14474       errmsg ("action not set for negative mapping");
14475       return -99;
14476     }
14477
14478   /* Construct the API message */
14479   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
14480       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
14481
14482   mp->is_add = is_add;
14483   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
14484   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
14485   mp->eid_type = rmt_eid->type;
14486   mp->dp_table = clib_host_to_net_u32 (dp_table);
14487   mp->vni = clib_host_to_net_u32 (vni);
14488   mp->rmt_len = rmt_eid->len;
14489   mp->lcl_len = lcl_eid->len;
14490   mp->action = action;
14491
14492   if (0 != rmt_locs && 0 != lcl_locs)
14493     {
14494       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
14495       clib_memcpy (mp->locs, lcl_locs,
14496                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
14497
14498       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
14499       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
14500                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
14501     }
14502   vec_free (lcl_locs);
14503   vec_free (rmt_locs);
14504
14505   /* send it... */
14506   S (mp);
14507
14508   /* Wait for a reply... */
14509   W (ret);
14510   return ret;
14511 }
14512
14513 static int
14514 api_one_add_del_map_server (vat_main_t * vam)
14515 {
14516   unformat_input_t *input = vam->input;
14517   vl_api_one_add_del_map_server_t *mp;
14518   u8 is_add = 1;
14519   u8 ipv4_set = 0;
14520   u8 ipv6_set = 0;
14521   ip4_address_t ipv4;
14522   ip6_address_t ipv6;
14523   int ret;
14524
14525   /* Parse args required to build the message */
14526   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14527     {
14528       if (unformat (input, "del"))
14529         {
14530           is_add = 0;
14531         }
14532       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
14533         {
14534           ipv4_set = 1;
14535         }
14536       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
14537         {
14538           ipv6_set = 1;
14539         }
14540       else
14541         break;
14542     }
14543
14544   if (ipv4_set && ipv6_set)
14545     {
14546       errmsg ("both eid v4 and v6 addresses set");
14547       return -99;
14548     }
14549
14550   if (!ipv4_set && !ipv6_set)
14551     {
14552       errmsg ("eid addresses not set");
14553       return -99;
14554     }
14555
14556   /* Construct the API message */
14557   M (ONE_ADD_DEL_MAP_SERVER, mp);
14558
14559   mp->is_add = is_add;
14560   if (ipv6_set)
14561     {
14562       mp->is_ipv6 = 1;
14563       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
14564     }
14565   else
14566     {
14567       mp->is_ipv6 = 0;
14568       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
14569     }
14570
14571   /* send it... */
14572   S (mp);
14573
14574   /* Wait for a reply... */
14575   W (ret);
14576   return ret;
14577 }
14578
14579 #define api_lisp_add_del_map_server api_one_add_del_map_server
14580
14581 static int
14582 api_one_add_del_map_resolver (vat_main_t * vam)
14583 {
14584   unformat_input_t *input = vam->input;
14585   vl_api_one_add_del_map_resolver_t *mp;
14586   u8 is_add = 1;
14587   u8 ipv4_set = 0;
14588   u8 ipv6_set = 0;
14589   ip4_address_t ipv4;
14590   ip6_address_t ipv6;
14591   int ret;
14592
14593   /* Parse args required to build the message */
14594   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14595     {
14596       if (unformat (input, "del"))
14597         {
14598           is_add = 0;
14599         }
14600       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
14601         {
14602           ipv4_set = 1;
14603         }
14604       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
14605         {
14606           ipv6_set = 1;
14607         }
14608       else
14609         break;
14610     }
14611
14612   if (ipv4_set && ipv6_set)
14613     {
14614       errmsg ("both eid v4 and v6 addresses set");
14615       return -99;
14616     }
14617
14618   if (!ipv4_set && !ipv6_set)
14619     {
14620       errmsg ("eid addresses not set");
14621       return -99;
14622     }
14623
14624   /* Construct the API message */
14625   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
14626
14627   mp->is_add = is_add;
14628   if (ipv6_set)
14629     {
14630       mp->is_ipv6 = 1;
14631       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
14632     }
14633   else
14634     {
14635       mp->is_ipv6 = 0;
14636       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
14637     }
14638
14639   /* send it... */
14640   S (mp);
14641
14642   /* Wait for a reply... */
14643   W (ret);
14644   return ret;
14645 }
14646
14647 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
14648
14649 static int
14650 api_lisp_gpe_enable_disable (vat_main_t * vam)
14651 {
14652   unformat_input_t *input = vam->input;
14653   vl_api_gpe_enable_disable_t *mp;
14654   u8 is_set = 0;
14655   u8 is_en = 1;
14656   int ret;
14657
14658   /* Parse args required to build the message */
14659   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14660     {
14661       if (unformat (input, "enable"))
14662         {
14663           is_set = 1;
14664           is_en = 1;
14665         }
14666       else if (unformat (input, "disable"))
14667         {
14668           is_set = 1;
14669           is_en = 0;
14670         }
14671       else
14672         break;
14673     }
14674
14675   if (is_set == 0)
14676     {
14677       errmsg ("Value not set");
14678       return -99;
14679     }
14680
14681   /* Construct the API message */
14682   M (GPE_ENABLE_DISABLE, mp);
14683
14684   mp->is_en = is_en;
14685
14686   /* send it... */
14687   S (mp);
14688
14689   /* Wait for a reply... */
14690   W (ret);
14691   return ret;
14692 }
14693
14694 static int
14695 api_one_rloc_probe_enable_disable (vat_main_t * vam)
14696 {
14697   unformat_input_t *input = vam->input;
14698   vl_api_one_rloc_probe_enable_disable_t *mp;
14699   u8 is_set = 0;
14700   u8 is_en = 0;
14701   int ret;
14702
14703   /* Parse args required to build the message */
14704   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14705     {
14706       if (unformat (input, "enable"))
14707         {
14708           is_set = 1;
14709           is_en = 1;
14710         }
14711       else if (unformat (input, "disable"))
14712         is_set = 1;
14713       else
14714         break;
14715     }
14716
14717   if (!is_set)
14718     {
14719       errmsg ("Value not set");
14720       return -99;
14721     }
14722
14723   /* Construct the API message */
14724   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
14725
14726   mp->is_enabled = is_en;
14727
14728   /* send it... */
14729   S (mp);
14730
14731   /* Wait for a reply... */
14732   W (ret);
14733   return ret;
14734 }
14735
14736 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
14737
14738 static int
14739 api_one_map_register_enable_disable (vat_main_t * vam)
14740 {
14741   unformat_input_t *input = vam->input;
14742   vl_api_one_map_register_enable_disable_t *mp;
14743   u8 is_set = 0;
14744   u8 is_en = 0;
14745   int ret;
14746
14747   /* Parse args required to build the message */
14748   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14749     {
14750       if (unformat (input, "enable"))
14751         {
14752           is_set = 1;
14753           is_en = 1;
14754         }
14755       else if (unformat (input, "disable"))
14756         is_set = 1;
14757       else
14758         break;
14759     }
14760
14761   if (!is_set)
14762     {
14763       errmsg ("Value not set");
14764       return -99;
14765     }
14766
14767   /* Construct the API message */
14768   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
14769
14770   mp->is_enabled = is_en;
14771
14772   /* send it... */
14773   S (mp);
14774
14775   /* Wait for a reply... */
14776   W (ret);
14777   return ret;
14778 }
14779
14780 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
14781
14782 static int
14783 api_one_enable_disable (vat_main_t * vam)
14784 {
14785   unformat_input_t *input = vam->input;
14786   vl_api_one_enable_disable_t *mp;
14787   u8 is_set = 0;
14788   u8 is_en = 0;
14789   int ret;
14790
14791   /* Parse args required to build the message */
14792   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14793     {
14794       if (unformat (input, "enable"))
14795         {
14796           is_set = 1;
14797           is_en = 1;
14798         }
14799       else if (unformat (input, "disable"))
14800         {
14801           is_set = 1;
14802         }
14803       else
14804         break;
14805     }
14806
14807   if (!is_set)
14808     {
14809       errmsg ("Value not set");
14810       return -99;
14811     }
14812
14813   /* Construct the API message */
14814   M (ONE_ENABLE_DISABLE, mp);
14815
14816   mp->is_en = is_en;
14817
14818   /* send it... */
14819   S (mp);
14820
14821   /* Wait for a reply... */
14822   W (ret);
14823   return ret;
14824 }
14825
14826 #define api_lisp_enable_disable api_one_enable_disable
14827
14828 static int
14829 api_show_one_map_register_state (vat_main_t * vam)
14830 {
14831   vl_api_show_one_map_register_state_t *mp;
14832   int ret;
14833
14834   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
14835
14836   /* send */
14837   S (mp);
14838
14839   /* wait for reply */
14840   W (ret);
14841   return ret;
14842 }
14843
14844 #define api_show_lisp_map_register_state api_show_one_map_register_state
14845
14846 static int
14847 api_show_one_rloc_probe_state (vat_main_t * vam)
14848 {
14849   vl_api_show_one_rloc_probe_state_t *mp;
14850   int ret;
14851
14852   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
14853
14854   /* send */
14855   S (mp);
14856
14857   /* wait for reply */
14858   W (ret);
14859   return ret;
14860 }
14861
14862 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
14863
14864 static int
14865 api_one_add_del_l2_arp_entry (vat_main_t * vam)
14866 {
14867   vl_api_one_add_del_l2_arp_entry_t *mp;
14868   unformat_input_t *input = vam->input;
14869   u8 is_add = 1;
14870   u8 mac_set = 0;
14871   u8 bd_set = 0;
14872   u8 ip_set = 0;
14873   u8 mac[6] = { 0, };
14874   u32 ip4 = 0, bd = ~0;
14875   int ret;
14876
14877   /* Parse args required to build the message */
14878   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14879     {
14880       if (unformat (input, "del"))
14881         is_add = 0;
14882       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
14883         mac_set = 1;
14884       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
14885         ip_set = 1;
14886       else if (unformat (input, "bd %d", &bd))
14887         bd_set = 1;
14888       else
14889         {
14890           errmsg ("parse error '%U'", format_unformat_error, input);
14891           return -99;
14892         }
14893     }
14894
14895   if (!bd_set || !ip_set || (!mac_set && is_add))
14896     {
14897       errmsg ("Missing BD, IP or MAC!");
14898       return -99;
14899     }
14900
14901   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
14902   mp->is_add = is_add;
14903   clib_memcpy (mp->mac, mac, 6);
14904   mp->bd = clib_host_to_net_u32 (bd);
14905   mp->ip4 = ip4;
14906
14907   /* send */
14908   S (mp);
14909
14910   /* wait for reply */
14911   W (ret);
14912   return ret;
14913 }
14914
14915 static int
14916 api_one_l2_arp_bd_get (vat_main_t * vam)
14917 {
14918   vl_api_one_l2_arp_bd_get_t *mp;
14919   int ret;
14920
14921   M (ONE_L2_ARP_BD_GET, mp);
14922
14923   /* send */
14924   S (mp);
14925
14926   /* wait for reply */
14927   W (ret);
14928   return ret;
14929 }
14930
14931 static int
14932 api_one_l2_arp_entries_get (vat_main_t * vam)
14933 {
14934   vl_api_one_l2_arp_entries_get_t *mp;
14935   unformat_input_t *input = vam->input;
14936   u8 bd_set = 0;
14937   u32 bd = ~0;
14938   int ret;
14939
14940   /* Parse args required to build the message */
14941   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14942     {
14943       if (unformat (input, "bd %d", &bd))
14944         bd_set = 1;
14945       else
14946         {
14947           errmsg ("parse error '%U'", format_unformat_error, input);
14948           return -99;
14949         }
14950     }
14951
14952   if (!bd_set)
14953     {
14954       errmsg ("Expected bridge domain!");
14955       return -99;
14956     }
14957
14958   M (ONE_L2_ARP_ENTRIES_GET, mp);
14959   mp->bd = clib_host_to_net_u32 (bd);
14960
14961   /* send */
14962   S (mp);
14963
14964   /* wait for reply */
14965   W (ret);
14966   return ret;
14967 }
14968
14969 static int
14970 api_one_stats_enable_disable (vat_main_t * vam)
14971 {
14972   vl_api_one_stats_enable_disable_t *mp;
14973   unformat_input_t *input = vam->input;
14974   u8 is_set = 0;
14975   u8 is_en = 0;
14976   int ret;
14977
14978   /* Parse args required to build the message */
14979   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14980     {
14981       if (unformat (input, "enable"))
14982         {
14983           is_set = 1;
14984           is_en = 1;
14985         }
14986       else if (unformat (input, "disable"))
14987         {
14988           is_set = 1;
14989         }
14990       else
14991         break;
14992     }
14993
14994   if (!is_set)
14995     {
14996       errmsg ("Value not set");
14997       return -99;
14998     }
14999
15000   M (ONE_STATS_ENABLE_DISABLE, mp);
15001   mp->is_en = is_en;
15002
15003   /* send */
15004   S (mp);
15005
15006   /* wait for reply */
15007   W (ret);
15008   return ret;
15009 }
15010
15011 static int
15012 api_show_one_stats_enable_disable (vat_main_t * vam)
15013 {
15014   vl_api_show_one_stats_enable_disable_t *mp;
15015   int ret;
15016
15017   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
15018
15019   /* send */
15020   S (mp);
15021
15022   /* wait for reply */
15023   W (ret);
15024   return ret;
15025 }
15026
15027 static int
15028 api_show_one_map_request_mode (vat_main_t * vam)
15029 {
15030   vl_api_show_one_map_request_mode_t *mp;
15031   int ret;
15032
15033   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
15034
15035   /* send */
15036   S (mp);
15037
15038   /* wait for reply */
15039   W (ret);
15040   return ret;
15041 }
15042
15043 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
15044
15045 static int
15046 api_one_map_request_mode (vat_main_t * vam)
15047 {
15048   unformat_input_t *input = vam->input;
15049   vl_api_one_map_request_mode_t *mp;
15050   u8 mode = 0;
15051   int ret;
15052
15053   /* Parse args required to build the message */
15054   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15055     {
15056       if (unformat (input, "dst-only"))
15057         mode = 0;
15058       else if (unformat (input, "src-dst"))
15059         mode = 1;
15060       else
15061         {
15062           errmsg ("parse error '%U'", format_unformat_error, input);
15063           return -99;
15064         }
15065     }
15066
15067   M (ONE_MAP_REQUEST_MODE, mp);
15068
15069   mp->mode = mode;
15070
15071   /* send */
15072   S (mp);
15073
15074   /* wait for reply */
15075   W (ret);
15076   return ret;
15077 }
15078
15079 #define api_lisp_map_request_mode api_one_map_request_mode
15080
15081 /**
15082  * Enable/disable ONE proxy ITR.
15083  *
15084  * @param vam vpp API test context
15085  * @return return code
15086  */
15087 static int
15088 api_one_pitr_set_locator_set (vat_main_t * vam)
15089 {
15090   u8 ls_name_set = 0;
15091   unformat_input_t *input = vam->input;
15092   vl_api_one_pitr_set_locator_set_t *mp;
15093   u8 is_add = 1;
15094   u8 *ls_name = 0;
15095   int ret;
15096
15097   /* Parse args required to build the message */
15098   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15099     {
15100       if (unformat (input, "del"))
15101         is_add = 0;
15102       else if (unformat (input, "locator-set %s", &ls_name))
15103         ls_name_set = 1;
15104       else
15105         {
15106           errmsg ("parse error '%U'", format_unformat_error, input);
15107           return -99;
15108         }
15109     }
15110
15111   if (!ls_name_set)
15112     {
15113       errmsg ("locator-set name not set!");
15114       return -99;
15115     }
15116
15117   M (ONE_PITR_SET_LOCATOR_SET, mp);
15118
15119   mp->is_add = is_add;
15120   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
15121   vec_free (ls_name);
15122
15123   /* send */
15124   S (mp);
15125
15126   /* wait for reply */
15127   W (ret);
15128   return ret;
15129 }
15130
15131 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
15132
15133 static int
15134 api_show_one_pitr (vat_main_t * vam)
15135 {
15136   vl_api_show_one_pitr_t *mp;
15137   int ret;
15138
15139   if (!vam->json_output)
15140     {
15141       print (vam->ofp, "%=20s", "lisp status:");
15142     }
15143
15144   M (SHOW_ONE_PITR, mp);
15145   /* send it... */
15146   S (mp);
15147
15148   /* Wait for a reply... */
15149   W (ret);
15150   return ret;
15151 }
15152
15153 #define api_show_lisp_pitr api_show_one_pitr
15154
15155 static int
15156 api_one_use_petr (vat_main_t * vam)
15157 {
15158   unformat_input_t *input = vam->input;
15159   vl_api_one_use_petr_t *mp;
15160   u8 is_add = 0;
15161   ip_address_t ip;
15162   int ret;
15163
15164   memset (&ip, 0, sizeof (ip));
15165
15166   /* Parse args required to build the message */
15167   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15168     {
15169       if (unformat (input, "disable"))
15170         is_add = 0;
15171       else
15172         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
15173         {
15174           is_add = 1;
15175           ip_addr_version (&ip) = IP4;
15176         }
15177       else
15178         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
15179         {
15180           is_add = 1;
15181           ip_addr_version (&ip) = IP6;
15182         }
15183       else
15184         {
15185           errmsg ("parse error '%U'", format_unformat_error, input);
15186           return -99;
15187         }
15188     }
15189
15190   M (ONE_USE_PETR, mp);
15191
15192   mp->is_add = is_add;
15193   if (is_add)
15194     {
15195       mp->is_ip4 = ip_addr_version (&ip) == IP4 ? 1 : 0;
15196       if (mp->is_ip4)
15197         clib_memcpy (mp->address, &ip, 4);
15198       else
15199         clib_memcpy (mp->address, &ip, 16);
15200     }
15201
15202   /* send */
15203   S (mp);
15204
15205   /* wait for reply */
15206   W (ret);
15207   return ret;
15208 }
15209
15210 #define api_lisp_use_petr api_one_use_petr
15211
15212 static int
15213 api_show_one_use_petr (vat_main_t * vam)
15214 {
15215   vl_api_show_one_use_petr_t *mp;
15216   int ret;
15217
15218   if (!vam->json_output)
15219     {
15220       print (vam->ofp, "%=20s", "Proxy-ETR status:");
15221     }
15222
15223   M (SHOW_ONE_USE_PETR, mp);
15224   /* send it... */
15225   S (mp);
15226
15227   /* Wait for a reply... */
15228   W (ret);
15229   return ret;
15230 }
15231
15232 #define api_show_lisp_use_petr api_show_one_use_petr
15233
15234 /**
15235  * Add/delete mapping between vni and vrf
15236  */
15237 static int
15238 api_one_eid_table_add_del_map (vat_main_t * vam)
15239 {
15240   unformat_input_t *input = vam->input;
15241   vl_api_one_eid_table_add_del_map_t *mp;
15242   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
15243   u32 vni, vrf, bd_index;
15244   int ret;
15245
15246   /* Parse args required to build the message */
15247   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15248     {
15249       if (unformat (input, "del"))
15250         is_add = 0;
15251       else if (unformat (input, "vrf %d", &vrf))
15252         vrf_set = 1;
15253       else if (unformat (input, "bd_index %d", &bd_index))
15254         bd_index_set = 1;
15255       else if (unformat (input, "vni %d", &vni))
15256         vni_set = 1;
15257       else
15258         break;
15259     }
15260
15261   if (!vni_set || (!vrf_set && !bd_index_set))
15262     {
15263       errmsg ("missing arguments!");
15264       return -99;
15265     }
15266
15267   if (vrf_set && bd_index_set)
15268     {
15269       errmsg ("error: both vrf and bd entered!");
15270       return -99;
15271     }
15272
15273   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
15274
15275   mp->is_add = is_add;
15276   mp->vni = htonl (vni);
15277   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
15278   mp->is_l2 = bd_index_set;
15279
15280   /* send */
15281   S (mp);
15282
15283   /* wait for reply */
15284   W (ret);
15285   return ret;
15286 }
15287
15288 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
15289
15290 uword
15291 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
15292 {
15293   u32 *action = va_arg (*args, u32 *);
15294   u8 *s = 0;
15295
15296   if (unformat (input, "%s", &s))
15297     {
15298       if (!strcmp ((char *) s, "no-action"))
15299         action[0] = 0;
15300       else if (!strcmp ((char *) s, "natively-forward"))
15301         action[0] = 1;
15302       else if (!strcmp ((char *) s, "send-map-request"))
15303         action[0] = 2;
15304       else if (!strcmp ((char *) s, "drop"))
15305         action[0] = 3;
15306       else
15307         {
15308           clib_warning ("invalid action: '%s'", s);
15309           action[0] = 3;
15310         }
15311     }
15312   else
15313     return 0;
15314
15315   vec_free (s);
15316   return 1;
15317 }
15318
15319 /**
15320  * Add/del remote mapping to/from ONE control plane
15321  *
15322  * @param vam vpp API test context
15323  * @return return code
15324  */
15325 static int
15326 api_one_add_del_remote_mapping (vat_main_t * vam)
15327 {
15328   unformat_input_t *input = vam->input;
15329   vl_api_one_add_del_remote_mapping_t *mp;
15330   u32 vni = 0;
15331   lisp_eid_vat_t _eid, *eid = &_eid;
15332   lisp_eid_vat_t _seid, *seid = &_seid;
15333   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
15334   u32 action = ~0, p, w, data_len;
15335   ip4_address_t rloc4;
15336   ip6_address_t rloc6;
15337   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
15338   int ret;
15339
15340   memset (&rloc, 0, sizeof (rloc));
15341
15342   /* Parse args required to build the message */
15343   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15344     {
15345       if (unformat (input, "del-all"))
15346         {
15347           del_all = 1;
15348         }
15349       else if (unformat (input, "del"))
15350         {
15351           is_add = 0;
15352         }
15353       else if (unformat (input, "add"))
15354         {
15355           is_add = 1;
15356         }
15357       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
15358         {
15359           eid_set = 1;
15360         }
15361       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
15362         {
15363           seid_set = 1;
15364         }
15365       else if (unformat (input, "vni %d", &vni))
15366         {
15367           ;
15368         }
15369       else if (unformat (input, "p %d w %d", &p, &w))
15370         {
15371           if (!curr_rloc)
15372             {
15373               errmsg ("No RLOC configured for setting priority/weight!");
15374               return -99;
15375             }
15376           curr_rloc->priority = p;
15377           curr_rloc->weight = w;
15378         }
15379       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
15380         {
15381           rloc.is_ip4 = 1;
15382           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
15383           vec_add1 (rlocs, rloc);
15384           curr_rloc = &rlocs[vec_len (rlocs) - 1];
15385         }
15386       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
15387         {
15388           rloc.is_ip4 = 0;
15389           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
15390           vec_add1 (rlocs, rloc);
15391           curr_rloc = &rlocs[vec_len (rlocs) - 1];
15392         }
15393       else if (unformat (input, "action %U",
15394                          unformat_negative_mapping_action, &action))
15395         {
15396           ;
15397         }
15398       else
15399         {
15400           clib_warning ("parse error '%U'", format_unformat_error, input);
15401           return -99;
15402         }
15403     }
15404
15405   if (0 == eid_set)
15406     {
15407       errmsg ("missing params!");
15408       return -99;
15409     }
15410
15411   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
15412     {
15413       errmsg ("no action set for negative map-reply!");
15414       return -99;
15415     }
15416
15417   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
15418
15419   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
15420   mp->is_add = is_add;
15421   mp->vni = htonl (vni);
15422   mp->action = (u8) action;
15423   mp->is_src_dst = seid_set;
15424   mp->eid_len = eid->len;
15425   mp->seid_len = seid->len;
15426   mp->del_all = del_all;
15427   mp->eid_type = eid->type;
15428   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
15429   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
15430
15431   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
15432   clib_memcpy (mp->rlocs, rlocs, data_len);
15433   vec_free (rlocs);
15434
15435   /* send it... */
15436   S (mp);
15437
15438   /* Wait for a reply... */
15439   W (ret);
15440   return ret;
15441 }
15442
15443 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
15444
15445 /**
15446  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
15447  * forwarding entries in data-plane accordingly.
15448  *
15449  * @param vam vpp API test context
15450  * @return return code
15451  */
15452 static int
15453 api_one_add_del_adjacency (vat_main_t * vam)
15454 {
15455   unformat_input_t *input = vam->input;
15456   vl_api_one_add_del_adjacency_t *mp;
15457   u32 vni = 0;
15458   ip4_address_t leid4, reid4;
15459   ip6_address_t leid6, reid6;
15460   u8 reid_mac[6] = { 0 };
15461   u8 leid_mac[6] = { 0 };
15462   u8 reid_type, leid_type;
15463   u32 leid_len = 0, reid_len = 0, len;
15464   u8 is_add = 1;
15465   int ret;
15466
15467   leid_type = reid_type = (u8) ~ 0;
15468
15469   /* Parse args required to build the message */
15470   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15471     {
15472       if (unformat (input, "del"))
15473         {
15474           is_add = 0;
15475         }
15476       else if (unformat (input, "add"))
15477         {
15478           is_add = 1;
15479         }
15480       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
15481                          &reid4, &len))
15482         {
15483           reid_type = 0;        /* ipv4 */
15484           reid_len = len;
15485         }
15486       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
15487                          &reid6, &len))
15488         {
15489           reid_type = 1;        /* ipv6 */
15490           reid_len = len;
15491         }
15492       else if (unformat (input, "reid %U", unformat_ethernet_address,
15493                          reid_mac))
15494         {
15495           reid_type = 2;        /* mac */
15496         }
15497       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
15498                          &leid4, &len))
15499         {
15500           leid_type = 0;        /* ipv4 */
15501           leid_len = len;
15502         }
15503       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
15504                          &leid6, &len))
15505         {
15506           leid_type = 1;        /* ipv6 */
15507           leid_len = len;
15508         }
15509       else if (unformat (input, "leid %U", unformat_ethernet_address,
15510                          leid_mac))
15511         {
15512           leid_type = 2;        /* mac */
15513         }
15514       else if (unformat (input, "vni %d", &vni))
15515         {
15516           ;
15517         }
15518       else
15519         {
15520           errmsg ("parse error '%U'", format_unformat_error, input);
15521           return -99;
15522         }
15523     }
15524
15525   if ((u8) ~ 0 == reid_type)
15526     {
15527       errmsg ("missing params!");
15528       return -99;
15529     }
15530
15531   if (leid_type != reid_type)
15532     {
15533       errmsg ("remote and local EIDs are of different types!");
15534       return -99;
15535     }
15536
15537   M (ONE_ADD_DEL_ADJACENCY, mp);
15538   mp->is_add = is_add;
15539   mp->vni = htonl (vni);
15540   mp->leid_len = leid_len;
15541   mp->reid_len = reid_len;
15542   mp->eid_type = reid_type;
15543
15544   switch (mp->eid_type)
15545     {
15546     case 0:
15547       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
15548       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
15549       break;
15550     case 1:
15551       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
15552       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
15553       break;
15554     case 2:
15555       clib_memcpy (mp->leid, leid_mac, 6);
15556       clib_memcpy (mp->reid, reid_mac, 6);
15557       break;
15558     default:
15559       errmsg ("unknown EID type %d!", mp->eid_type);
15560       return 0;
15561     }
15562
15563   /* send it... */
15564   S (mp);
15565
15566   /* Wait for a reply... */
15567   W (ret);
15568   return ret;
15569 }
15570
15571 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
15572
15573 uword
15574 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
15575 {
15576   u32 *mode = va_arg (*args, u32 *);
15577
15578   if (unformat (input, "lisp"))
15579     *mode = 0;
15580   else if (unformat (input, "vxlan"))
15581     *mode = 1;
15582   else
15583     return 0;
15584
15585   return 1;
15586 }
15587
15588 static int
15589 api_gpe_get_encap_mode (vat_main_t * vam)
15590 {
15591   vl_api_gpe_get_encap_mode_t *mp;
15592   int ret;
15593
15594   /* Construct the API message */
15595   M (GPE_GET_ENCAP_MODE, mp);
15596
15597   /* send it... */
15598   S (mp);
15599
15600   /* Wait for a reply... */
15601   W (ret);
15602   return ret;
15603 }
15604
15605 static int
15606 api_gpe_set_encap_mode (vat_main_t * vam)
15607 {
15608   unformat_input_t *input = vam->input;
15609   vl_api_gpe_set_encap_mode_t *mp;
15610   int ret;
15611   u32 mode = 0;
15612
15613   /* Parse args required to build the message */
15614   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15615     {
15616       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
15617         ;
15618       else
15619         break;
15620     }
15621
15622   /* Construct the API message */
15623   M (GPE_SET_ENCAP_MODE, mp);
15624
15625   mp->mode = mode;
15626
15627   /* send it... */
15628   S (mp);
15629
15630   /* Wait for a reply... */
15631   W (ret);
15632   return ret;
15633 }
15634
15635 static int
15636 api_lisp_gpe_add_del_iface (vat_main_t * vam)
15637 {
15638   unformat_input_t *input = vam->input;
15639   vl_api_gpe_add_del_iface_t *mp;
15640   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
15641   u32 dp_table = 0, vni = 0;
15642   int ret;
15643
15644   /* Parse args required to build the message */
15645   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15646     {
15647       if (unformat (input, "up"))
15648         {
15649           action_set = 1;
15650           is_add = 1;
15651         }
15652       else if (unformat (input, "down"))
15653         {
15654           action_set = 1;
15655           is_add = 0;
15656         }
15657       else if (unformat (input, "table_id %d", &dp_table))
15658         {
15659           dp_table_set = 1;
15660         }
15661       else if (unformat (input, "bd_id %d", &dp_table))
15662         {
15663           dp_table_set = 1;
15664           is_l2 = 1;
15665         }
15666       else if (unformat (input, "vni %d", &vni))
15667         {
15668           vni_set = 1;
15669         }
15670       else
15671         break;
15672     }
15673
15674   if (action_set == 0)
15675     {
15676       errmsg ("Action not set");
15677       return -99;
15678     }
15679   if (dp_table_set == 0 || vni_set == 0)
15680     {
15681       errmsg ("vni and dp_table must be set");
15682       return -99;
15683     }
15684
15685   /* Construct the API message */
15686   M (GPE_ADD_DEL_IFACE, mp);
15687
15688   mp->is_add = is_add;
15689   mp->dp_table = dp_table;
15690   mp->is_l2 = is_l2;
15691   mp->vni = vni;
15692
15693   /* send it... */
15694   S (mp);
15695
15696   /* Wait for a reply... */
15697   W (ret);
15698   return ret;
15699 }
15700
15701 /**
15702  * Add/del map request itr rlocs from ONE control plane and updates
15703  *
15704  * @param vam vpp API test context
15705  * @return return code
15706  */
15707 static int
15708 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
15709 {
15710   unformat_input_t *input = vam->input;
15711   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
15712   u8 *locator_set_name = 0;
15713   u8 locator_set_name_set = 0;
15714   u8 is_add = 1;
15715   int ret;
15716
15717   /* Parse args required to build the message */
15718   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15719     {
15720       if (unformat (input, "del"))
15721         {
15722           is_add = 0;
15723         }
15724       else if (unformat (input, "%_%v%_", &locator_set_name))
15725         {
15726           locator_set_name_set = 1;
15727         }
15728       else
15729         {
15730           clib_warning ("parse error '%U'", format_unformat_error, input);
15731           return -99;
15732         }
15733     }
15734
15735   if (is_add && !locator_set_name_set)
15736     {
15737       errmsg ("itr-rloc is not set!");
15738       return -99;
15739     }
15740
15741   if (is_add && vec_len (locator_set_name) > 64)
15742     {
15743       errmsg ("itr-rloc locator-set name too long");
15744       vec_free (locator_set_name);
15745       return -99;
15746     }
15747
15748   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
15749   mp->is_add = is_add;
15750   if (is_add)
15751     {
15752       clib_memcpy (mp->locator_set_name, locator_set_name,
15753                    vec_len (locator_set_name));
15754     }
15755   else
15756     {
15757       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
15758     }
15759   vec_free (locator_set_name);
15760
15761   /* send it... */
15762   S (mp);
15763
15764   /* Wait for a reply... */
15765   W (ret);
15766   return ret;
15767 }
15768
15769 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
15770
15771 static int
15772 api_one_locator_dump (vat_main_t * vam)
15773 {
15774   unformat_input_t *input = vam->input;
15775   vl_api_one_locator_dump_t *mp;
15776   vl_api_control_ping_t *mp_ping;
15777   u8 is_index_set = 0, is_name_set = 0;
15778   u8 *ls_name = 0;
15779   u32 ls_index = ~0;
15780   int ret;
15781
15782   /* Parse args required to build the message */
15783   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15784     {
15785       if (unformat (input, "ls_name %_%v%_", &ls_name))
15786         {
15787           is_name_set = 1;
15788         }
15789       else if (unformat (input, "ls_index %d", &ls_index))
15790         {
15791           is_index_set = 1;
15792         }
15793       else
15794         {
15795           errmsg ("parse error '%U'", format_unformat_error, input);
15796           return -99;
15797         }
15798     }
15799
15800   if (!is_index_set && !is_name_set)
15801     {
15802       errmsg ("error: expected one of index or name!");
15803       return -99;
15804     }
15805
15806   if (is_index_set && is_name_set)
15807     {
15808       errmsg ("error: only one param expected!");
15809       return -99;
15810     }
15811
15812   if (vec_len (ls_name) > 62)
15813     {
15814       errmsg ("error: locator set name too long!");
15815       return -99;
15816     }
15817
15818   if (!vam->json_output)
15819     {
15820       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
15821     }
15822
15823   M (ONE_LOCATOR_DUMP, mp);
15824   mp->is_index_set = is_index_set;
15825
15826   if (is_index_set)
15827     mp->ls_index = clib_host_to_net_u32 (ls_index);
15828   else
15829     {
15830       vec_add1 (ls_name, 0);
15831       strncpy ((char *) mp->ls_name, (char *) ls_name,
15832                sizeof (mp->ls_name) - 1);
15833     }
15834
15835   /* send it... */
15836   S (mp);
15837
15838   /* Use a control ping for synchronization */
15839   M (CONTROL_PING, mp_ping);
15840   S (mp_ping);
15841
15842   /* Wait for a reply... */
15843   W (ret);
15844   return ret;
15845 }
15846
15847 #define api_lisp_locator_dump api_one_locator_dump
15848
15849 static int
15850 api_one_locator_set_dump (vat_main_t * vam)
15851 {
15852   vl_api_one_locator_set_dump_t *mp;
15853   vl_api_control_ping_t *mp_ping;
15854   unformat_input_t *input = vam->input;
15855   u8 filter = 0;
15856   int ret;
15857
15858   /* Parse args required to build the message */
15859   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15860     {
15861       if (unformat (input, "local"))
15862         {
15863           filter = 1;
15864         }
15865       else if (unformat (input, "remote"))
15866         {
15867           filter = 2;
15868         }
15869       else
15870         {
15871           errmsg ("parse error '%U'", format_unformat_error, input);
15872           return -99;
15873         }
15874     }
15875
15876   if (!vam->json_output)
15877     {
15878       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
15879     }
15880
15881   M (ONE_LOCATOR_SET_DUMP, mp);
15882
15883   mp->filter = filter;
15884
15885   /* send it... */
15886   S (mp);
15887
15888   /* Use a control ping for synchronization */
15889   M (CONTROL_PING, mp_ping);
15890   S (mp_ping);
15891
15892   /* Wait for a reply... */
15893   W (ret);
15894   return ret;
15895 }
15896
15897 #define api_lisp_locator_set_dump api_one_locator_set_dump
15898
15899 static int
15900 api_one_eid_table_map_dump (vat_main_t * vam)
15901 {
15902   u8 is_l2 = 0;
15903   u8 mode_set = 0;
15904   unformat_input_t *input = vam->input;
15905   vl_api_one_eid_table_map_dump_t *mp;
15906   vl_api_control_ping_t *mp_ping;
15907   int ret;
15908
15909   /* Parse args required to build the message */
15910   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15911     {
15912       if (unformat (input, "l2"))
15913         {
15914           is_l2 = 1;
15915           mode_set = 1;
15916         }
15917       else if (unformat (input, "l3"))
15918         {
15919           is_l2 = 0;
15920           mode_set = 1;
15921         }
15922       else
15923         {
15924           errmsg ("parse error '%U'", format_unformat_error, input);
15925           return -99;
15926         }
15927     }
15928
15929   if (!mode_set)
15930     {
15931       errmsg ("expected one of 'l2' or 'l3' parameter!");
15932       return -99;
15933     }
15934
15935   if (!vam->json_output)
15936     {
15937       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
15938     }
15939
15940   M (ONE_EID_TABLE_MAP_DUMP, mp);
15941   mp->is_l2 = is_l2;
15942
15943   /* send it... */
15944   S (mp);
15945
15946   /* Use a control ping for synchronization */
15947   M (CONTROL_PING, mp_ping);
15948   S (mp_ping);
15949
15950   /* Wait for a reply... */
15951   W (ret);
15952   return ret;
15953 }
15954
15955 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
15956
15957 static int
15958 api_one_eid_table_vni_dump (vat_main_t * vam)
15959 {
15960   vl_api_one_eid_table_vni_dump_t *mp;
15961   vl_api_control_ping_t *mp_ping;
15962   int ret;
15963
15964   if (!vam->json_output)
15965     {
15966       print (vam->ofp, "VNI");
15967     }
15968
15969   M (ONE_EID_TABLE_VNI_DUMP, mp);
15970
15971   /* send it... */
15972   S (mp);
15973
15974   /* Use a control ping for synchronization */
15975   M (CONTROL_PING, mp_ping);
15976   S (mp_ping);
15977
15978   /* Wait for a reply... */
15979   W (ret);
15980   return ret;
15981 }
15982
15983 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
15984
15985 static int
15986 api_one_eid_table_dump (vat_main_t * vam)
15987 {
15988   unformat_input_t *i = vam->input;
15989   vl_api_one_eid_table_dump_t *mp;
15990   vl_api_control_ping_t *mp_ping;
15991   struct in_addr ip4;
15992   struct in6_addr ip6;
15993   u8 mac[6];
15994   u8 eid_type = ~0, eid_set = 0;
15995   u32 prefix_length = ~0, t, vni = 0;
15996   u8 filter = 0;
15997   int ret;
15998
15999   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16000     {
16001       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
16002         {
16003           eid_set = 1;
16004           eid_type = 0;
16005           prefix_length = t;
16006         }
16007       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
16008         {
16009           eid_set = 1;
16010           eid_type = 1;
16011           prefix_length = t;
16012         }
16013       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
16014         {
16015           eid_set = 1;
16016           eid_type = 2;
16017         }
16018       else if (unformat (i, "vni %d", &t))
16019         {
16020           vni = t;
16021         }
16022       else if (unformat (i, "local"))
16023         {
16024           filter = 1;
16025         }
16026       else if (unformat (i, "remote"))
16027         {
16028           filter = 2;
16029         }
16030       else
16031         {
16032           errmsg ("parse error '%U'", format_unformat_error, i);
16033           return -99;
16034         }
16035     }
16036
16037   if (!vam->json_output)
16038     {
16039       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
16040              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
16041     }
16042
16043   M (ONE_EID_TABLE_DUMP, mp);
16044
16045   mp->filter = filter;
16046   if (eid_set)
16047     {
16048       mp->eid_set = 1;
16049       mp->vni = htonl (vni);
16050       mp->eid_type = eid_type;
16051       switch (eid_type)
16052         {
16053         case 0:
16054           mp->prefix_length = prefix_length;
16055           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
16056           break;
16057         case 1:
16058           mp->prefix_length = prefix_length;
16059           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
16060           break;
16061         case 2:
16062           clib_memcpy (mp->eid, mac, sizeof (mac));
16063           break;
16064         default:
16065           errmsg ("unknown EID type %d!", eid_type);
16066           return -99;
16067         }
16068     }
16069
16070   /* send it... */
16071   S (mp);
16072
16073   /* Use a control ping for synchronization */
16074   M (CONTROL_PING, mp_ping);
16075   S (mp_ping);
16076
16077   /* Wait for a reply... */
16078   W (ret);
16079   return ret;
16080 }
16081
16082 #define api_lisp_eid_table_dump api_one_eid_table_dump
16083
16084 static int
16085 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
16086 {
16087   unformat_input_t *i = vam->input;
16088   vl_api_gpe_fwd_entries_get_t *mp;
16089   u8 vni_set = 0;
16090   u32 vni = ~0;
16091   int ret;
16092
16093   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16094     {
16095       if (unformat (i, "vni %d", &vni))
16096         {
16097           vni_set = 1;
16098         }
16099       else
16100         {
16101           errmsg ("parse error '%U'", format_unformat_error, i);
16102           return -99;
16103         }
16104     }
16105
16106   if (!vni_set)
16107     {
16108       errmsg ("vni not set!");
16109       return -99;
16110     }
16111
16112   if (!vam->json_output)
16113     {
16114       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
16115              "leid", "reid");
16116     }
16117
16118   M (GPE_FWD_ENTRIES_GET, mp);
16119   mp->vni = clib_host_to_net_u32 (vni);
16120
16121   /* send it... */
16122   S (mp);
16123
16124   /* Wait for a reply... */
16125   W (ret);
16126   return ret;
16127 }
16128
16129 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
16130 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
16131 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
16132 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
16133 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
16134 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
16135
16136 static int
16137 api_one_adjacencies_get (vat_main_t * vam)
16138 {
16139   unformat_input_t *i = vam->input;
16140   vl_api_one_adjacencies_get_t *mp;
16141   u8 vni_set = 0;
16142   u32 vni = ~0;
16143   int ret;
16144
16145   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16146     {
16147       if (unformat (i, "vni %d", &vni))
16148         {
16149           vni_set = 1;
16150         }
16151       else
16152         {
16153           errmsg ("parse error '%U'", format_unformat_error, i);
16154           return -99;
16155         }
16156     }
16157
16158   if (!vni_set)
16159     {
16160       errmsg ("vni not set!");
16161       return -99;
16162     }
16163
16164   if (!vam->json_output)
16165     {
16166       print (vam->ofp, "%s %40s", "leid", "reid");
16167     }
16168
16169   M (ONE_ADJACENCIES_GET, mp);
16170   mp->vni = clib_host_to_net_u32 (vni);
16171
16172   /* send it... */
16173   S (mp);
16174
16175   /* Wait for a reply... */
16176   W (ret);
16177   return ret;
16178 }
16179
16180 #define api_lisp_adjacencies_get api_one_adjacencies_get
16181
16182 static int
16183 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
16184 {
16185   vl_api_gpe_fwd_entry_vnis_get_t *mp;
16186   int ret;
16187
16188   if (!vam->json_output)
16189     {
16190       print (vam->ofp, "VNIs");
16191     }
16192
16193   M (GPE_FWD_ENTRY_VNIS_GET, mp);
16194
16195   /* send it... */
16196   S (mp);
16197
16198   /* Wait for a reply... */
16199   W (ret);
16200   return ret;
16201 }
16202
16203 static int
16204 api_one_map_server_dump (vat_main_t * vam)
16205 {
16206   vl_api_one_map_server_dump_t *mp;
16207   vl_api_control_ping_t *mp_ping;
16208   int ret;
16209
16210   if (!vam->json_output)
16211     {
16212       print (vam->ofp, "%=20s", "Map server");
16213     }
16214
16215   M (ONE_MAP_SERVER_DUMP, mp);
16216   /* send it... */
16217   S (mp);
16218
16219   /* Use a control ping for synchronization */
16220   M (CONTROL_PING, mp_ping);
16221   S (mp_ping);
16222
16223   /* Wait for a reply... */
16224   W (ret);
16225   return ret;
16226 }
16227
16228 #define api_lisp_map_server_dump api_one_map_server_dump
16229
16230 static int
16231 api_one_map_resolver_dump (vat_main_t * vam)
16232 {
16233   vl_api_one_map_resolver_dump_t *mp;
16234   vl_api_control_ping_t *mp_ping;
16235   int ret;
16236
16237   if (!vam->json_output)
16238     {
16239       print (vam->ofp, "%=20s", "Map resolver");
16240     }
16241
16242   M (ONE_MAP_RESOLVER_DUMP, mp);
16243   /* send it... */
16244   S (mp);
16245
16246   /* Use a control ping for synchronization */
16247   M (CONTROL_PING, mp_ping);
16248   S (mp_ping);
16249
16250   /* Wait for a reply... */
16251   W (ret);
16252   return ret;
16253 }
16254
16255 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
16256
16257 static int
16258 api_one_stats_flush (vat_main_t * vam)
16259 {
16260   vl_api_one_stats_flush_t *mp;
16261   int ret = 0;
16262
16263   M (ONE_STATS_FLUSH, mp);
16264   S (mp);
16265   W (ret);
16266   return ret;
16267 }
16268
16269 static int
16270 api_one_stats_dump (vat_main_t * vam)
16271 {
16272   vl_api_one_stats_dump_t *mp;
16273   vl_api_control_ping_t *mp_ping;
16274   int ret;
16275
16276   M (ONE_STATS_DUMP, mp);
16277   /* send it... */
16278   S (mp);
16279
16280   /* Use a control ping for synchronization */
16281   M (CONTROL_PING, mp_ping);
16282   S (mp_ping);
16283
16284   /* Wait for a reply... */
16285   W (ret);
16286   return ret;
16287 }
16288
16289 static int
16290 api_show_one_status (vat_main_t * vam)
16291 {
16292   vl_api_show_one_status_t *mp;
16293   int ret;
16294
16295   if (!vam->json_output)
16296     {
16297       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
16298     }
16299
16300   M (SHOW_ONE_STATUS, mp);
16301   /* send it... */
16302   S (mp);
16303   /* Wait for a reply... */
16304   W (ret);
16305   return ret;
16306 }
16307
16308 #define api_show_lisp_status api_show_one_status
16309
16310 static int
16311 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
16312 {
16313   vl_api_gpe_fwd_entry_path_dump_t *mp;
16314   vl_api_control_ping_t *mp_ping;
16315   unformat_input_t *i = vam->input;
16316   u32 fwd_entry_index = ~0;
16317   int ret;
16318
16319   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16320     {
16321       if (unformat (i, "index %d", &fwd_entry_index))
16322         ;
16323       else
16324         break;
16325     }
16326
16327   if (~0 == fwd_entry_index)
16328     {
16329       errmsg ("no index specified!");
16330       return -99;
16331     }
16332
16333   if (!vam->json_output)
16334     {
16335       print (vam->ofp, "first line");
16336     }
16337
16338   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
16339
16340   /* send it... */
16341   S (mp);
16342   /* Use a control ping for synchronization */
16343   M (CONTROL_PING, mp_ping);
16344   S (mp_ping);
16345
16346   /* Wait for a reply... */
16347   W (ret);
16348   return ret;
16349 }
16350
16351 static int
16352 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
16353 {
16354   vl_api_one_get_map_request_itr_rlocs_t *mp;
16355   int ret;
16356
16357   if (!vam->json_output)
16358     {
16359       print (vam->ofp, "%=20s", "itr-rlocs:");
16360     }
16361
16362   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
16363   /* send it... */
16364   S (mp);
16365   /* Wait for a reply... */
16366   W (ret);
16367   return ret;
16368 }
16369
16370 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
16371
16372 static int
16373 api_af_packet_create (vat_main_t * vam)
16374 {
16375   unformat_input_t *i = vam->input;
16376   vl_api_af_packet_create_t *mp;
16377   u8 *host_if_name = 0;
16378   u8 hw_addr[6];
16379   u8 random_hw_addr = 1;
16380   int ret;
16381
16382   memset (hw_addr, 0, sizeof (hw_addr));
16383
16384   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16385     {
16386       if (unformat (i, "name %s", &host_if_name))
16387         vec_add1 (host_if_name, 0);
16388       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
16389         random_hw_addr = 0;
16390       else
16391         break;
16392     }
16393
16394   if (!vec_len (host_if_name))
16395     {
16396       errmsg ("host-interface name must be specified");
16397       return -99;
16398     }
16399
16400   if (vec_len (host_if_name) > 64)
16401     {
16402       errmsg ("host-interface name too long");
16403       return -99;
16404     }
16405
16406   M (AF_PACKET_CREATE, mp);
16407
16408   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
16409   clib_memcpy (mp->hw_addr, hw_addr, 6);
16410   mp->use_random_hw_addr = random_hw_addr;
16411   vec_free (host_if_name);
16412
16413   S (mp);
16414
16415   /* *INDENT-OFF* */
16416   W2 (ret,
16417       ({
16418         if (ret == 0)
16419           fprintf (vam->ofp ? vam->ofp : stderr,
16420                    " new sw_if_index = %d\n", vam->sw_if_index);
16421       }));
16422   /* *INDENT-ON* */
16423   return ret;
16424 }
16425
16426 static int
16427 api_af_packet_delete (vat_main_t * vam)
16428 {
16429   unformat_input_t *i = vam->input;
16430   vl_api_af_packet_delete_t *mp;
16431   u8 *host_if_name = 0;
16432   int ret;
16433
16434   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16435     {
16436       if (unformat (i, "name %s", &host_if_name))
16437         vec_add1 (host_if_name, 0);
16438       else
16439         break;
16440     }
16441
16442   if (!vec_len (host_if_name))
16443     {
16444       errmsg ("host-interface name must be specified");
16445       return -99;
16446     }
16447
16448   if (vec_len (host_if_name) > 64)
16449     {
16450       errmsg ("host-interface name too long");
16451       return -99;
16452     }
16453
16454   M (AF_PACKET_DELETE, mp);
16455
16456   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
16457   vec_free (host_if_name);
16458
16459   S (mp);
16460   W (ret);
16461   return ret;
16462 }
16463
16464 static int
16465 api_policer_add_del (vat_main_t * vam)
16466 {
16467   unformat_input_t *i = vam->input;
16468   vl_api_policer_add_del_t *mp;
16469   u8 is_add = 1;
16470   u8 *name = 0;
16471   u32 cir = 0;
16472   u32 eir = 0;
16473   u64 cb = 0;
16474   u64 eb = 0;
16475   u8 rate_type = 0;
16476   u8 round_type = 0;
16477   u8 type = 0;
16478   u8 color_aware = 0;
16479   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
16480   int ret;
16481
16482   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
16483   conform_action.dscp = 0;
16484   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
16485   exceed_action.dscp = 0;
16486   violate_action.action_type = SSE2_QOS_ACTION_DROP;
16487   violate_action.dscp = 0;
16488
16489   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16490     {
16491       if (unformat (i, "del"))
16492         is_add = 0;
16493       else if (unformat (i, "name %s", &name))
16494         vec_add1 (name, 0);
16495       else if (unformat (i, "cir %u", &cir))
16496         ;
16497       else if (unformat (i, "eir %u", &eir))
16498         ;
16499       else if (unformat (i, "cb %u", &cb))
16500         ;
16501       else if (unformat (i, "eb %u", &eb))
16502         ;
16503       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
16504                          &rate_type))
16505         ;
16506       else if (unformat (i, "round_type %U", unformat_policer_round_type,
16507                          &round_type))
16508         ;
16509       else if (unformat (i, "type %U", unformat_policer_type, &type))
16510         ;
16511       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
16512                          &conform_action))
16513         ;
16514       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
16515                          &exceed_action))
16516         ;
16517       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
16518                          &violate_action))
16519         ;
16520       else if (unformat (i, "color-aware"))
16521         color_aware = 1;
16522       else
16523         break;
16524     }
16525
16526   if (!vec_len (name))
16527     {
16528       errmsg ("policer name must be specified");
16529       return -99;
16530     }
16531
16532   if (vec_len (name) > 64)
16533     {
16534       errmsg ("policer name too long");
16535       return -99;
16536     }
16537
16538   M (POLICER_ADD_DEL, mp);
16539
16540   clib_memcpy (mp->name, name, vec_len (name));
16541   vec_free (name);
16542   mp->is_add = is_add;
16543   mp->cir = cir;
16544   mp->eir = eir;
16545   mp->cb = cb;
16546   mp->eb = eb;
16547   mp->rate_type = rate_type;
16548   mp->round_type = round_type;
16549   mp->type = type;
16550   mp->conform_action_type = conform_action.action_type;
16551   mp->conform_dscp = conform_action.dscp;
16552   mp->exceed_action_type = exceed_action.action_type;
16553   mp->exceed_dscp = exceed_action.dscp;
16554   mp->violate_action_type = violate_action.action_type;
16555   mp->violate_dscp = violate_action.dscp;
16556   mp->color_aware = color_aware;
16557
16558   S (mp);
16559   W (ret);
16560   return ret;
16561 }
16562
16563 static int
16564 api_policer_dump (vat_main_t * vam)
16565 {
16566   unformat_input_t *i = vam->input;
16567   vl_api_policer_dump_t *mp;
16568   vl_api_control_ping_t *mp_ping;
16569   u8 *match_name = 0;
16570   u8 match_name_valid = 0;
16571   int ret;
16572
16573   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16574     {
16575       if (unformat (i, "name %s", &match_name))
16576         {
16577           vec_add1 (match_name, 0);
16578           match_name_valid = 1;
16579         }
16580       else
16581         break;
16582     }
16583
16584   M (POLICER_DUMP, mp);
16585   mp->match_name_valid = match_name_valid;
16586   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
16587   vec_free (match_name);
16588   /* send it... */
16589   S (mp);
16590
16591   /* Use a control ping for synchronization */
16592   M (CONTROL_PING, mp_ping);
16593   S (mp_ping);
16594
16595   /* Wait for a reply... */
16596   W (ret);
16597   return ret;
16598 }
16599
16600 static int
16601 api_policer_classify_set_interface (vat_main_t * vam)
16602 {
16603   unformat_input_t *i = vam->input;
16604   vl_api_policer_classify_set_interface_t *mp;
16605   u32 sw_if_index;
16606   int sw_if_index_set;
16607   u32 ip4_table_index = ~0;
16608   u32 ip6_table_index = ~0;
16609   u32 l2_table_index = ~0;
16610   u8 is_add = 1;
16611   int ret;
16612
16613   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16614     {
16615       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16616         sw_if_index_set = 1;
16617       else if (unformat (i, "sw_if_index %d", &sw_if_index))
16618         sw_if_index_set = 1;
16619       else if (unformat (i, "del"))
16620         is_add = 0;
16621       else if (unformat (i, "ip4-table %d", &ip4_table_index))
16622         ;
16623       else if (unformat (i, "ip6-table %d", &ip6_table_index))
16624         ;
16625       else if (unformat (i, "l2-table %d", &l2_table_index))
16626         ;
16627       else
16628         {
16629           clib_warning ("parse error '%U'", format_unformat_error, i);
16630           return -99;
16631         }
16632     }
16633
16634   if (sw_if_index_set == 0)
16635     {
16636       errmsg ("missing interface name or sw_if_index");
16637       return -99;
16638     }
16639
16640   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
16641
16642   mp->sw_if_index = ntohl (sw_if_index);
16643   mp->ip4_table_index = ntohl (ip4_table_index);
16644   mp->ip6_table_index = ntohl (ip6_table_index);
16645   mp->l2_table_index = ntohl (l2_table_index);
16646   mp->is_add = is_add;
16647
16648   S (mp);
16649   W (ret);
16650   return ret;
16651 }
16652
16653 static int
16654 api_policer_classify_dump (vat_main_t * vam)
16655 {
16656   unformat_input_t *i = vam->input;
16657   vl_api_policer_classify_dump_t *mp;
16658   vl_api_control_ping_t *mp_ping;
16659   u8 type = POLICER_CLASSIFY_N_TABLES;
16660   int ret;
16661
16662   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
16663     ;
16664   else
16665     {
16666       errmsg ("classify table type must be specified");
16667       return -99;
16668     }
16669
16670   if (!vam->json_output)
16671     {
16672       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
16673     }
16674
16675   M (POLICER_CLASSIFY_DUMP, mp);
16676   mp->type = type;
16677   /* send it... */
16678   S (mp);
16679
16680   /* Use a control ping for synchronization */
16681   M (CONTROL_PING, mp_ping);
16682   S (mp_ping);
16683
16684   /* Wait for a reply... */
16685   W (ret);
16686   return ret;
16687 }
16688
16689 static int
16690 api_netmap_create (vat_main_t * vam)
16691 {
16692   unformat_input_t *i = vam->input;
16693   vl_api_netmap_create_t *mp;
16694   u8 *if_name = 0;
16695   u8 hw_addr[6];
16696   u8 random_hw_addr = 1;
16697   u8 is_pipe = 0;
16698   u8 is_master = 0;
16699   int ret;
16700
16701   memset (hw_addr, 0, sizeof (hw_addr));
16702
16703   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16704     {
16705       if (unformat (i, "name %s", &if_name))
16706         vec_add1 (if_name, 0);
16707       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
16708         random_hw_addr = 0;
16709       else if (unformat (i, "pipe"))
16710         is_pipe = 1;
16711       else if (unformat (i, "master"))
16712         is_master = 1;
16713       else if (unformat (i, "slave"))
16714         is_master = 0;
16715       else
16716         break;
16717     }
16718
16719   if (!vec_len (if_name))
16720     {
16721       errmsg ("interface name must be specified");
16722       return -99;
16723     }
16724
16725   if (vec_len (if_name) > 64)
16726     {
16727       errmsg ("interface name too long");
16728       return -99;
16729     }
16730
16731   M (NETMAP_CREATE, mp);
16732
16733   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
16734   clib_memcpy (mp->hw_addr, hw_addr, 6);
16735   mp->use_random_hw_addr = random_hw_addr;
16736   mp->is_pipe = is_pipe;
16737   mp->is_master = is_master;
16738   vec_free (if_name);
16739
16740   S (mp);
16741   W (ret);
16742   return ret;
16743 }
16744
16745 static int
16746 api_netmap_delete (vat_main_t * vam)
16747 {
16748   unformat_input_t *i = vam->input;
16749   vl_api_netmap_delete_t *mp;
16750   u8 *if_name = 0;
16751   int ret;
16752
16753   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16754     {
16755       if (unformat (i, "name %s", &if_name))
16756         vec_add1 (if_name, 0);
16757       else
16758         break;
16759     }
16760
16761   if (!vec_len (if_name))
16762     {
16763       errmsg ("interface name must be specified");
16764       return -99;
16765     }
16766
16767   if (vec_len (if_name) > 64)
16768     {
16769       errmsg ("interface name too long");
16770       return -99;
16771     }
16772
16773   M (NETMAP_DELETE, mp);
16774
16775   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
16776   vec_free (if_name);
16777
16778   S (mp);
16779   W (ret);
16780   return ret;
16781 }
16782
16783 static void
16784 vl_api_mpls_fib_path_print (vat_main_t * vam, vl_api_fib_path2_t * fp)
16785 {
16786   if (fp->afi == IP46_TYPE_IP6)
16787     print (vam->ofp,
16788            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16789            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16790            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16791            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16792            format_ip6_address, fp->next_hop);
16793   else if (fp->afi == IP46_TYPE_IP4)
16794     print (vam->ofp,
16795            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16796            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16797            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16798            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16799            format_ip4_address, fp->next_hop);
16800 }
16801
16802 static void
16803 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
16804                                  vl_api_fib_path2_t * fp)
16805 {
16806   struct in_addr ip4;
16807   struct in6_addr ip6;
16808
16809   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
16810   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
16811   vat_json_object_add_uint (node, "is_local", fp->is_local);
16812   vat_json_object_add_uint (node, "is_drop", fp->is_drop);
16813   vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
16814   vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
16815   vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
16816   if (fp->afi == IP46_TYPE_IP4)
16817     {
16818       clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
16819       vat_json_object_add_ip4 (node, "next_hop", ip4);
16820     }
16821   else if (fp->afi == IP46_TYPE_IP6)
16822     {
16823       clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
16824       vat_json_object_add_ip6 (node, "next_hop", ip6);
16825     }
16826 }
16827
16828 static void
16829 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
16830 {
16831   vat_main_t *vam = &vat_main;
16832   int count = ntohl (mp->mt_count);
16833   vl_api_fib_path2_t *fp;
16834   i32 i;
16835
16836   print (vam->ofp, "[%d]: sw_if_index %d via:",
16837          ntohl (mp->mt_tunnel_index), ntohl (mp->mt_sw_if_index));
16838   fp = mp->mt_paths;
16839   for (i = 0; i < count; i++)
16840     {
16841       vl_api_mpls_fib_path_print (vam, fp);
16842       fp++;
16843     }
16844
16845   print (vam->ofp, "");
16846 }
16847
16848 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
16849 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
16850
16851 static void
16852 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
16853 {
16854   vat_main_t *vam = &vat_main;
16855   vat_json_node_t *node = NULL;
16856   int count = ntohl (mp->mt_count);
16857   vl_api_fib_path2_t *fp;
16858   i32 i;
16859
16860   if (VAT_JSON_ARRAY != vam->json_tree.type)
16861     {
16862       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16863       vat_json_init_array (&vam->json_tree);
16864     }
16865   node = vat_json_array_add (&vam->json_tree);
16866
16867   vat_json_init_object (node);
16868   vat_json_object_add_uint (node, "tunnel_index",
16869                             ntohl (mp->mt_tunnel_index));
16870   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->mt_sw_if_index));
16871
16872   vat_json_object_add_uint (node, "l2_only", mp->mt_l2_only);
16873
16874   fp = mp->mt_paths;
16875   for (i = 0; i < count; i++)
16876     {
16877       vl_api_mpls_fib_path_json_print (node, fp);
16878       fp++;
16879     }
16880 }
16881
16882 static int
16883 api_mpls_tunnel_dump (vat_main_t * vam)
16884 {
16885   vl_api_mpls_tunnel_dump_t *mp;
16886   vl_api_control_ping_t *mp_ping;
16887   i32 index = -1;
16888   int ret;
16889
16890   /* Parse args required to build the message */
16891   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
16892     {
16893       if (!unformat (vam->input, "tunnel_index %d", &index))
16894         {
16895           index = -1;
16896           break;
16897         }
16898     }
16899
16900   print (vam->ofp, "  tunnel_index %d", index);
16901
16902   M (MPLS_TUNNEL_DUMP, mp);
16903   mp->tunnel_index = htonl (index);
16904   S (mp);
16905
16906   /* Use a control ping for synchronization */
16907   M (CONTROL_PING, mp_ping);
16908   S (mp_ping);
16909
16910   W (ret);
16911   return ret;
16912 }
16913
16914 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
16915 #define vl_api_mpls_fib_details_t_print vl_noop_handler
16916
16917
16918 static void
16919 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
16920 {
16921   vat_main_t *vam = &vat_main;
16922   int count = ntohl (mp->count);
16923   vl_api_fib_path2_t *fp;
16924   int i;
16925
16926   print (vam->ofp,
16927          "table-id %d, label %u, ess_bit %u",
16928          ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
16929   fp = mp->path;
16930   for (i = 0; i < count; i++)
16931     {
16932       vl_api_mpls_fib_path_print (vam, fp);
16933       fp++;
16934     }
16935 }
16936
16937 static void vl_api_mpls_fib_details_t_handler_json
16938   (vl_api_mpls_fib_details_t * mp)
16939 {
16940   vat_main_t *vam = &vat_main;
16941   int count = ntohl (mp->count);
16942   vat_json_node_t *node = NULL;
16943   vl_api_fib_path2_t *fp;
16944   int i;
16945
16946   if (VAT_JSON_ARRAY != vam->json_tree.type)
16947     {
16948       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16949       vat_json_init_array (&vam->json_tree);
16950     }
16951   node = vat_json_array_add (&vam->json_tree);
16952
16953   vat_json_init_object (node);
16954   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
16955   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
16956   vat_json_object_add_uint (node, "label", ntohl (mp->label));
16957   vat_json_object_add_uint (node, "path_count", count);
16958   fp = mp->path;
16959   for (i = 0; i < count; i++)
16960     {
16961       vl_api_mpls_fib_path_json_print (node, fp);
16962       fp++;
16963     }
16964 }
16965
16966 static int
16967 api_mpls_fib_dump (vat_main_t * vam)
16968 {
16969   vl_api_mpls_fib_dump_t *mp;
16970   vl_api_control_ping_t *mp_ping;
16971   int ret;
16972
16973   M (MPLS_FIB_DUMP, mp);
16974   S (mp);
16975
16976   /* Use a control ping for synchronization */
16977   M (CONTROL_PING, mp_ping);
16978   S (mp_ping);
16979
16980   W (ret);
16981   return ret;
16982 }
16983
16984 #define vl_api_ip_fib_details_t_endian vl_noop_handler
16985 #define vl_api_ip_fib_details_t_print vl_noop_handler
16986
16987 static void
16988 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
16989 {
16990   vat_main_t *vam = &vat_main;
16991   int count = ntohl (mp->count);
16992   vl_api_fib_path_t *fp;
16993   int i;
16994
16995   print (vam->ofp,
16996          "table-id %d, prefix %U/%d",
16997          ntohl (mp->table_id), format_ip4_address, mp->address,
16998          mp->address_length);
16999   fp = mp->path;
17000   for (i = 0; i < count; i++)
17001     {
17002       if (fp->afi == IP46_TYPE_IP6)
17003         print (vam->ofp,
17004                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
17005                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
17006                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
17007                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
17008                format_ip6_address, fp->next_hop);
17009       else if (fp->afi == IP46_TYPE_IP4)
17010         print (vam->ofp,
17011                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
17012                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
17013                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
17014                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
17015                format_ip4_address, fp->next_hop);
17016       fp++;
17017     }
17018 }
17019
17020 static void vl_api_ip_fib_details_t_handler_json
17021   (vl_api_ip_fib_details_t * mp)
17022 {
17023   vat_main_t *vam = &vat_main;
17024   int count = ntohl (mp->count);
17025   vat_json_node_t *node = NULL;
17026   struct in_addr ip4;
17027   struct in6_addr ip6;
17028   vl_api_fib_path_t *fp;
17029   int i;
17030
17031   if (VAT_JSON_ARRAY != vam->json_tree.type)
17032     {
17033       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17034       vat_json_init_array (&vam->json_tree);
17035     }
17036   node = vat_json_array_add (&vam->json_tree);
17037
17038   vat_json_init_object (node);
17039   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
17040   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
17041   vat_json_object_add_ip4 (node, "prefix", ip4);
17042   vat_json_object_add_uint (node, "mask_length", mp->address_length);
17043   vat_json_object_add_uint (node, "path_count", count);
17044   fp = mp->path;
17045   for (i = 0; i < count; i++)
17046     {
17047       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
17048       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
17049       vat_json_object_add_uint (node, "is_local", fp->is_local);
17050       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
17051       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
17052       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
17053       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
17054       if (fp->afi == IP46_TYPE_IP4)
17055         {
17056           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
17057           vat_json_object_add_ip4 (node, "next_hop", ip4);
17058         }
17059       else if (fp->afi == IP46_TYPE_IP6)
17060         {
17061           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
17062           vat_json_object_add_ip6 (node, "next_hop", ip6);
17063         }
17064     }
17065 }
17066
17067 static int
17068 api_ip_fib_dump (vat_main_t * vam)
17069 {
17070   vl_api_ip_fib_dump_t *mp;
17071   vl_api_control_ping_t *mp_ping;
17072   int ret;
17073
17074   M (IP_FIB_DUMP, mp);
17075   S (mp);
17076
17077   /* Use a control ping for synchronization */
17078   M (CONTROL_PING, mp_ping);
17079   S (mp_ping);
17080
17081   W (ret);
17082   return ret;
17083 }
17084
17085 static int
17086 api_ip_mfib_dump (vat_main_t * vam)
17087 {
17088   vl_api_ip_mfib_dump_t *mp;
17089   vl_api_control_ping_t *mp_ping;
17090   int ret;
17091
17092   M (IP_MFIB_DUMP, mp);
17093   S (mp);
17094
17095   /* Use a control ping for synchronization */
17096   M (CONTROL_PING, mp_ping);
17097   S (mp_ping);
17098
17099   W (ret);
17100   return ret;
17101 }
17102
17103 static void vl_api_ip_neighbor_details_t_handler
17104   (vl_api_ip_neighbor_details_t * mp)
17105 {
17106   vat_main_t *vam = &vat_main;
17107
17108   print (vam->ofp, "%c %U %U",
17109          (mp->is_static) ? 'S' : 'D',
17110          format_ethernet_address, &mp->mac_address,
17111          (mp->is_ipv6) ? format_ip6_address : format_ip4_address,
17112          &mp->ip_address);
17113 }
17114
17115 static void vl_api_ip_neighbor_details_t_handler_json
17116   (vl_api_ip_neighbor_details_t * mp)
17117 {
17118
17119   vat_main_t *vam = &vat_main;
17120   vat_json_node_t *node;
17121   struct in_addr ip4;
17122   struct in6_addr ip6;
17123
17124   if (VAT_JSON_ARRAY != vam->json_tree.type)
17125     {
17126       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17127       vat_json_init_array (&vam->json_tree);
17128     }
17129   node = vat_json_array_add (&vam->json_tree);
17130
17131   vat_json_init_object (node);
17132   vat_json_object_add_string_copy (node, "flag",
17133                                    (mp->is_static) ? (u8 *) "static" : (u8 *)
17134                                    "dynamic");
17135
17136   vat_json_object_add_string_copy (node, "link_layer",
17137                                    format (0, "%U", format_ethernet_address,
17138                                            &mp->mac_address));
17139
17140   if (mp->is_ipv6)
17141     {
17142       clib_memcpy (&ip6, &mp->ip_address, sizeof (ip6));
17143       vat_json_object_add_ip6 (node, "ip_address", ip6);
17144     }
17145   else
17146     {
17147       clib_memcpy (&ip4, &mp->ip_address, sizeof (ip4));
17148       vat_json_object_add_ip4 (node, "ip_address", ip4);
17149     }
17150 }
17151
17152 static int
17153 api_ip_neighbor_dump (vat_main_t * vam)
17154 {
17155   unformat_input_t *i = vam->input;
17156   vl_api_ip_neighbor_dump_t *mp;
17157   vl_api_control_ping_t *mp_ping;
17158   u8 is_ipv6 = 0;
17159   u32 sw_if_index = ~0;
17160   int ret;
17161
17162   /* Parse args required to build the message */
17163   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17164     {
17165       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17166         ;
17167       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17168         ;
17169       else if (unformat (i, "ip6"))
17170         is_ipv6 = 1;
17171       else
17172         break;
17173     }
17174
17175   if (sw_if_index == ~0)
17176     {
17177       errmsg ("missing interface name or sw_if_index");
17178       return -99;
17179     }
17180
17181   M (IP_NEIGHBOR_DUMP, mp);
17182   mp->is_ipv6 = (u8) is_ipv6;
17183   mp->sw_if_index = ntohl (sw_if_index);
17184   S (mp);
17185
17186   /* Use a control ping for synchronization */
17187   M (CONTROL_PING, mp_ping);
17188   S (mp_ping);
17189
17190   W (ret);
17191   return ret;
17192 }
17193
17194 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
17195 #define vl_api_ip6_fib_details_t_print vl_noop_handler
17196
17197 static void
17198 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
17199 {
17200   vat_main_t *vam = &vat_main;
17201   int count = ntohl (mp->count);
17202   vl_api_fib_path_t *fp;
17203   int i;
17204
17205   print (vam->ofp,
17206          "table-id %d, prefix %U/%d",
17207          ntohl (mp->table_id), format_ip6_address, mp->address,
17208          mp->address_length);
17209   fp = mp->path;
17210   for (i = 0; i < count; i++)
17211     {
17212       if (fp->afi == IP46_TYPE_IP6)
17213         print (vam->ofp,
17214                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
17215                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
17216                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
17217                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
17218                format_ip6_address, fp->next_hop);
17219       else if (fp->afi == IP46_TYPE_IP4)
17220         print (vam->ofp,
17221                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
17222                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
17223                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
17224                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
17225                format_ip4_address, fp->next_hop);
17226       fp++;
17227     }
17228 }
17229
17230 static void vl_api_ip6_fib_details_t_handler_json
17231   (vl_api_ip6_fib_details_t * mp)
17232 {
17233   vat_main_t *vam = &vat_main;
17234   int count = ntohl (mp->count);
17235   vat_json_node_t *node = NULL;
17236   struct in_addr ip4;
17237   struct in6_addr ip6;
17238   vl_api_fib_path_t *fp;
17239   int i;
17240
17241   if (VAT_JSON_ARRAY != vam->json_tree.type)
17242     {
17243       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17244       vat_json_init_array (&vam->json_tree);
17245     }
17246   node = vat_json_array_add (&vam->json_tree);
17247
17248   vat_json_init_object (node);
17249   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
17250   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
17251   vat_json_object_add_ip6 (node, "prefix", ip6);
17252   vat_json_object_add_uint (node, "mask_length", mp->address_length);
17253   vat_json_object_add_uint (node, "path_count", count);
17254   fp = mp->path;
17255   for (i = 0; i < count; i++)
17256     {
17257       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
17258       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
17259       vat_json_object_add_uint (node, "is_local", fp->is_local);
17260       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
17261       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
17262       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
17263       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
17264       if (fp->afi == IP46_TYPE_IP4)
17265         {
17266           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
17267           vat_json_object_add_ip4 (node, "next_hop", ip4);
17268         }
17269       else if (fp->afi == IP46_TYPE_IP6)
17270         {
17271           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
17272           vat_json_object_add_ip6 (node, "next_hop", ip6);
17273         }
17274     }
17275 }
17276
17277 static int
17278 api_ip6_fib_dump (vat_main_t * vam)
17279 {
17280   vl_api_ip6_fib_dump_t *mp;
17281   vl_api_control_ping_t *mp_ping;
17282   int ret;
17283
17284   M (IP6_FIB_DUMP, mp);
17285   S (mp);
17286
17287   /* Use a control ping for synchronization */
17288   M (CONTROL_PING, mp_ping);
17289   S (mp_ping);
17290
17291   W (ret);
17292   return ret;
17293 }
17294
17295 static int
17296 api_ip6_mfib_dump (vat_main_t * vam)
17297 {
17298   vl_api_ip6_mfib_dump_t *mp;
17299   vl_api_control_ping_t *mp_ping;
17300   int ret;
17301
17302   M (IP6_MFIB_DUMP, mp);
17303   S (mp);
17304
17305   /* Use a control ping for synchronization */
17306   M (CONTROL_PING, mp_ping);
17307   S (mp_ping);
17308
17309   W (ret);
17310   return ret;
17311 }
17312
17313 int
17314 api_classify_table_ids (vat_main_t * vam)
17315 {
17316   vl_api_classify_table_ids_t *mp;
17317   int ret;
17318
17319   /* Construct the API message */
17320   M (CLASSIFY_TABLE_IDS, mp);
17321   mp->context = 0;
17322
17323   S (mp);
17324   W (ret);
17325   return ret;
17326 }
17327
17328 int
17329 api_classify_table_by_interface (vat_main_t * vam)
17330 {
17331   unformat_input_t *input = vam->input;
17332   vl_api_classify_table_by_interface_t *mp;
17333
17334   u32 sw_if_index = ~0;
17335   int ret;
17336   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17337     {
17338       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17339         ;
17340       else if (unformat (input, "sw_if_index %d", &sw_if_index))
17341         ;
17342       else
17343         break;
17344     }
17345   if (sw_if_index == ~0)
17346     {
17347       errmsg ("missing interface name or sw_if_index");
17348       return -99;
17349     }
17350
17351   /* Construct the API message */
17352   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
17353   mp->context = 0;
17354   mp->sw_if_index = ntohl (sw_if_index);
17355
17356   S (mp);
17357   W (ret);
17358   return ret;
17359 }
17360
17361 int
17362 api_classify_table_info (vat_main_t * vam)
17363 {
17364   unformat_input_t *input = vam->input;
17365   vl_api_classify_table_info_t *mp;
17366
17367   u32 table_id = ~0;
17368   int ret;
17369   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17370     {
17371       if (unformat (input, "table_id %d", &table_id))
17372         ;
17373       else
17374         break;
17375     }
17376   if (table_id == ~0)
17377     {
17378       errmsg ("missing table id");
17379       return -99;
17380     }
17381
17382   /* Construct the API message */
17383   M (CLASSIFY_TABLE_INFO, mp);
17384   mp->context = 0;
17385   mp->table_id = ntohl (table_id);
17386
17387   S (mp);
17388   W (ret);
17389   return ret;
17390 }
17391
17392 int
17393 api_classify_session_dump (vat_main_t * vam)
17394 {
17395   unformat_input_t *input = vam->input;
17396   vl_api_classify_session_dump_t *mp;
17397   vl_api_control_ping_t *mp_ping;
17398
17399   u32 table_id = ~0;
17400   int ret;
17401   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17402     {
17403       if (unformat (input, "table_id %d", &table_id))
17404         ;
17405       else
17406         break;
17407     }
17408   if (table_id == ~0)
17409     {
17410       errmsg ("missing table id");
17411       return -99;
17412     }
17413
17414   /* Construct the API message */
17415   M (CLASSIFY_SESSION_DUMP, mp);
17416   mp->context = 0;
17417   mp->table_id = ntohl (table_id);
17418   S (mp);
17419
17420   /* Use a control ping for synchronization */
17421   M (CONTROL_PING, mp_ping);
17422   S (mp_ping);
17423
17424   W (ret);
17425   return ret;
17426 }
17427
17428 static void
17429 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
17430 {
17431   vat_main_t *vam = &vat_main;
17432
17433   print (vam->ofp, "collector_address %U, collector_port %d, "
17434          "src_address %U, vrf_id %d, path_mtu %u, "
17435          "template_interval %u, udp_checksum %d",
17436          format_ip4_address, mp->collector_address,
17437          ntohs (mp->collector_port),
17438          format_ip4_address, mp->src_address,
17439          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
17440          ntohl (mp->template_interval), mp->udp_checksum);
17441
17442   vam->retval = 0;
17443   vam->result_ready = 1;
17444 }
17445
17446 static void
17447   vl_api_ipfix_exporter_details_t_handler_json
17448   (vl_api_ipfix_exporter_details_t * mp)
17449 {
17450   vat_main_t *vam = &vat_main;
17451   vat_json_node_t node;
17452   struct in_addr collector_address;
17453   struct in_addr src_address;
17454
17455   vat_json_init_object (&node);
17456   clib_memcpy (&collector_address, &mp->collector_address,
17457                sizeof (collector_address));
17458   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
17459   vat_json_object_add_uint (&node, "collector_port",
17460                             ntohs (mp->collector_port));
17461   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
17462   vat_json_object_add_ip4 (&node, "src_address", src_address);
17463   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
17464   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
17465   vat_json_object_add_uint (&node, "template_interval",
17466                             ntohl (mp->template_interval));
17467   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
17468
17469   vat_json_print (vam->ofp, &node);
17470   vat_json_free (&node);
17471   vam->retval = 0;
17472   vam->result_ready = 1;
17473 }
17474
17475 int
17476 api_ipfix_exporter_dump (vat_main_t * vam)
17477 {
17478   vl_api_ipfix_exporter_dump_t *mp;
17479   int ret;
17480
17481   /* Construct the API message */
17482   M (IPFIX_EXPORTER_DUMP, mp);
17483   mp->context = 0;
17484
17485   S (mp);
17486   W (ret);
17487   return ret;
17488 }
17489
17490 static int
17491 api_ipfix_classify_stream_dump (vat_main_t * vam)
17492 {
17493   vl_api_ipfix_classify_stream_dump_t *mp;
17494   int ret;
17495
17496   /* Construct the API message */
17497   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
17498   mp->context = 0;
17499
17500   S (mp);
17501   W (ret);
17502   return ret;
17503   /* NOTREACHED */
17504   return 0;
17505 }
17506
17507 static void
17508   vl_api_ipfix_classify_stream_details_t_handler
17509   (vl_api_ipfix_classify_stream_details_t * mp)
17510 {
17511   vat_main_t *vam = &vat_main;
17512   print (vam->ofp, "domain_id %d, src_port %d",
17513          ntohl (mp->domain_id), ntohs (mp->src_port));
17514   vam->retval = 0;
17515   vam->result_ready = 1;
17516 }
17517
17518 static void
17519   vl_api_ipfix_classify_stream_details_t_handler_json
17520   (vl_api_ipfix_classify_stream_details_t * mp)
17521 {
17522   vat_main_t *vam = &vat_main;
17523   vat_json_node_t node;
17524
17525   vat_json_init_object (&node);
17526   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
17527   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
17528
17529   vat_json_print (vam->ofp, &node);
17530   vat_json_free (&node);
17531   vam->retval = 0;
17532   vam->result_ready = 1;
17533 }
17534
17535 static int
17536 api_ipfix_classify_table_dump (vat_main_t * vam)
17537 {
17538   vl_api_ipfix_classify_table_dump_t *mp;
17539   vl_api_control_ping_t *mp_ping;
17540   int ret;
17541
17542   if (!vam->json_output)
17543     {
17544       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
17545              "transport_protocol");
17546     }
17547
17548   /* Construct the API message */
17549   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
17550
17551   /* send it... */
17552   S (mp);
17553
17554   /* Use a control ping for synchronization */
17555   M (CONTROL_PING, mp_ping);
17556   S (mp_ping);
17557
17558   W (ret);
17559   return ret;
17560 }
17561
17562 static void
17563   vl_api_ipfix_classify_table_details_t_handler
17564   (vl_api_ipfix_classify_table_details_t * mp)
17565 {
17566   vat_main_t *vam = &vat_main;
17567   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
17568          mp->transport_protocol);
17569 }
17570
17571 static void
17572   vl_api_ipfix_classify_table_details_t_handler_json
17573   (vl_api_ipfix_classify_table_details_t * mp)
17574 {
17575   vat_json_node_t *node = NULL;
17576   vat_main_t *vam = &vat_main;
17577
17578   if (VAT_JSON_ARRAY != vam->json_tree.type)
17579     {
17580       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17581       vat_json_init_array (&vam->json_tree);
17582     }
17583
17584   node = vat_json_array_add (&vam->json_tree);
17585   vat_json_init_object (node);
17586
17587   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
17588   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
17589   vat_json_object_add_uint (node, "transport_protocol",
17590                             mp->transport_protocol);
17591 }
17592
17593 static int
17594 api_sw_interface_span_enable_disable (vat_main_t * vam)
17595 {
17596   unformat_input_t *i = vam->input;
17597   vl_api_sw_interface_span_enable_disable_t *mp;
17598   u32 src_sw_if_index = ~0;
17599   u32 dst_sw_if_index = ~0;
17600   u8 state = 3;
17601   int ret;
17602
17603   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17604     {
17605       if (unformat
17606           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
17607         ;
17608       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
17609         ;
17610       else
17611         if (unformat
17612             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
17613         ;
17614       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
17615         ;
17616       else if (unformat (i, "disable"))
17617         state = 0;
17618       else if (unformat (i, "rx"))
17619         state = 1;
17620       else if (unformat (i, "tx"))
17621         state = 2;
17622       else if (unformat (i, "both"))
17623         state = 3;
17624       else
17625         break;
17626     }
17627
17628   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
17629
17630   mp->sw_if_index_from = htonl (src_sw_if_index);
17631   mp->sw_if_index_to = htonl (dst_sw_if_index);
17632   mp->state = state;
17633
17634   S (mp);
17635   W (ret);
17636   return ret;
17637 }
17638
17639 static void
17640 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
17641                                             * mp)
17642 {
17643   vat_main_t *vam = &vat_main;
17644   u8 *sw_if_from_name = 0;
17645   u8 *sw_if_to_name = 0;
17646   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
17647   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
17648   char *states[] = { "none", "rx", "tx", "both" };
17649   hash_pair_t *p;
17650
17651   /* *INDENT-OFF* */
17652   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
17653   ({
17654     if ((u32) p->value[0] == sw_if_index_from)
17655       {
17656         sw_if_from_name = (u8 *)(p->key);
17657         if (sw_if_to_name)
17658           break;
17659       }
17660     if ((u32) p->value[0] == sw_if_index_to)
17661       {
17662         sw_if_to_name = (u8 *)(p->key);
17663         if (sw_if_from_name)
17664           break;
17665       }
17666   }));
17667   /* *INDENT-ON* */
17668   print (vam->ofp, "%20s => %20s (%s)",
17669          sw_if_from_name, sw_if_to_name, states[mp->state]);
17670 }
17671
17672 static void
17673   vl_api_sw_interface_span_details_t_handler_json
17674   (vl_api_sw_interface_span_details_t * mp)
17675 {
17676   vat_main_t *vam = &vat_main;
17677   vat_json_node_t *node = NULL;
17678   u8 *sw_if_from_name = 0;
17679   u8 *sw_if_to_name = 0;
17680   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
17681   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
17682   hash_pair_t *p;
17683
17684   /* *INDENT-OFF* */
17685   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
17686   ({
17687     if ((u32) p->value[0] == sw_if_index_from)
17688       {
17689         sw_if_from_name = (u8 *)(p->key);
17690         if (sw_if_to_name)
17691           break;
17692       }
17693     if ((u32) p->value[0] == sw_if_index_to)
17694       {
17695         sw_if_to_name = (u8 *)(p->key);
17696         if (sw_if_from_name)
17697           break;
17698       }
17699   }));
17700   /* *INDENT-ON* */
17701
17702   if (VAT_JSON_ARRAY != vam->json_tree.type)
17703     {
17704       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17705       vat_json_init_array (&vam->json_tree);
17706     }
17707   node = vat_json_array_add (&vam->json_tree);
17708
17709   vat_json_init_object (node);
17710   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
17711   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
17712   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
17713   if (0 != sw_if_to_name)
17714     {
17715       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
17716     }
17717   vat_json_object_add_uint (node, "state", mp->state);
17718 }
17719
17720 static int
17721 api_sw_interface_span_dump (vat_main_t * vam)
17722 {
17723   vl_api_sw_interface_span_dump_t *mp;
17724   vl_api_control_ping_t *mp_ping;
17725   int ret;
17726
17727   M (SW_INTERFACE_SPAN_DUMP, mp);
17728   S (mp);
17729
17730   /* Use a control ping for synchronization */
17731   M (CONTROL_PING, mp_ping);
17732   S (mp_ping);
17733
17734   W (ret);
17735   return ret;
17736 }
17737
17738 int
17739 api_pg_create_interface (vat_main_t * vam)
17740 {
17741   unformat_input_t *input = vam->input;
17742   vl_api_pg_create_interface_t *mp;
17743
17744   u32 if_id = ~0;
17745   int ret;
17746   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17747     {
17748       if (unformat (input, "if_id %d", &if_id))
17749         ;
17750       else
17751         break;
17752     }
17753   if (if_id == ~0)
17754     {
17755       errmsg ("missing pg interface index");
17756       return -99;
17757     }
17758
17759   /* Construct the API message */
17760   M (PG_CREATE_INTERFACE, mp);
17761   mp->context = 0;
17762   mp->interface_id = ntohl (if_id);
17763
17764   S (mp);
17765   W (ret);
17766   return ret;
17767 }
17768
17769 int
17770 api_pg_capture (vat_main_t * vam)
17771 {
17772   unformat_input_t *input = vam->input;
17773   vl_api_pg_capture_t *mp;
17774
17775   u32 if_id = ~0;
17776   u8 enable = 1;
17777   u32 count = 1;
17778   u8 pcap_file_set = 0;
17779   u8 *pcap_file = 0;
17780   int ret;
17781   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17782     {
17783       if (unformat (input, "if_id %d", &if_id))
17784         ;
17785       else if (unformat (input, "pcap %s", &pcap_file))
17786         pcap_file_set = 1;
17787       else if (unformat (input, "count %d", &count))
17788         ;
17789       else if (unformat (input, "disable"))
17790         enable = 0;
17791       else
17792         break;
17793     }
17794   if (if_id == ~0)
17795     {
17796       errmsg ("missing pg interface index");
17797       return -99;
17798     }
17799   if (pcap_file_set > 0)
17800     {
17801       if (vec_len (pcap_file) > 255)
17802         {
17803           errmsg ("pcap file name is too long");
17804           return -99;
17805         }
17806     }
17807
17808   u32 name_len = vec_len (pcap_file);
17809   /* Construct the API message */
17810   M (PG_CAPTURE, mp);
17811   mp->context = 0;
17812   mp->interface_id = ntohl (if_id);
17813   mp->is_enabled = enable;
17814   mp->count = ntohl (count);
17815   mp->pcap_name_length = ntohl (name_len);
17816   if (pcap_file_set != 0)
17817     {
17818       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
17819     }
17820   vec_free (pcap_file);
17821
17822   S (mp);
17823   W (ret);
17824   return ret;
17825 }
17826
17827 int
17828 api_pg_enable_disable (vat_main_t * vam)
17829 {
17830   unformat_input_t *input = vam->input;
17831   vl_api_pg_enable_disable_t *mp;
17832
17833   u8 enable = 1;
17834   u8 stream_name_set = 0;
17835   u8 *stream_name = 0;
17836   int ret;
17837   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17838     {
17839       if (unformat (input, "stream %s", &stream_name))
17840         stream_name_set = 1;
17841       else if (unformat (input, "disable"))
17842         enable = 0;
17843       else
17844         break;
17845     }
17846
17847   if (stream_name_set > 0)
17848     {
17849       if (vec_len (stream_name) > 255)
17850         {
17851           errmsg ("stream name too long");
17852           return -99;
17853         }
17854     }
17855
17856   u32 name_len = vec_len (stream_name);
17857   /* Construct the API message */
17858   M (PG_ENABLE_DISABLE, mp);
17859   mp->context = 0;
17860   mp->is_enabled = enable;
17861   if (stream_name_set != 0)
17862     {
17863       mp->stream_name_length = ntohl (name_len);
17864       clib_memcpy (mp->stream_name, stream_name, name_len);
17865     }
17866   vec_free (stream_name);
17867
17868   S (mp);
17869   W (ret);
17870   return ret;
17871 }
17872
17873 int
17874 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
17875 {
17876   unformat_input_t *input = vam->input;
17877   vl_api_ip_source_and_port_range_check_add_del_t *mp;
17878
17879   u16 *low_ports = 0;
17880   u16 *high_ports = 0;
17881   u16 this_low;
17882   u16 this_hi;
17883   ip4_address_t ip4_addr;
17884   ip6_address_t ip6_addr;
17885   u32 length;
17886   u32 tmp, tmp2;
17887   u8 prefix_set = 0;
17888   u32 vrf_id = ~0;
17889   u8 is_add = 1;
17890   u8 is_ipv6 = 0;
17891   int ret;
17892
17893   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17894     {
17895       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
17896         {
17897           prefix_set = 1;
17898         }
17899       else
17900         if (unformat
17901             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
17902         {
17903           prefix_set = 1;
17904           is_ipv6 = 1;
17905         }
17906       else if (unformat (input, "vrf %d", &vrf_id))
17907         ;
17908       else if (unformat (input, "del"))
17909         is_add = 0;
17910       else if (unformat (input, "port %d", &tmp))
17911         {
17912           if (tmp == 0 || tmp > 65535)
17913             {
17914               errmsg ("port %d out of range", tmp);
17915               return -99;
17916             }
17917           this_low = tmp;
17918           this_hi = this_low + 1;
17919           vec_add1 (low_ports, this_low);
17920           vec_add1 (high_ports, this_hi);
17921         }
17922       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
17923         {
17924           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
17925             {
17926               errmsg ("incorrect range parameters");
17927               return -99;
17928             }
17929           this_low = tmp;
17930           /* Note: in debug CLI +1 is added to high before
17931              passing to real fn that does "the work"
17932              (ip_source_and_port_range_check_add_del).
17933              This fn is a wrapper around the binary API fn a
17934              control plane will call, which expects this increment
17935              to have occurred. Hence letting the binary API control
17936              plane fn do the increment for consistency between VAT
17937              and other control planes.
17938            */
17939           this_hi = tmp2;
17940           vec_add1 (low_ports, this_low);
17941           vec_add1 (high_ports, this_hi);
17942         }
17943       else
17944         break;
17945     }
17946
17947   if (prefix_set == 0)
17948     {
17949       errmsg ("<address>/<mask> not specified");
17950       return -99;
17951     }
17952
17953   if (vrf_id == ~0)
17954     {
17955       errmsg ("VRF ID required, not specified");
17956       return -99;
17957     }
17958
17959   if (vrf_id == 0)
17960     {
17961       errmsg
17962         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
17963       return -99;
17964     }
17965
17966   if (vec_len (low_ports) == 0)
17967     {
17968       errmsg ("At least one port or port range required");
17969       return -99;
17970     }
17971
17972   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
17973
17974   mp->is_add = is_add;
17975
17976   if (is_ipv6)
17977     {
17978       mp->is_ipv6 = 1;
17979       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
17980     }
17981   else
17982     {
17983       mp->is_ipv6 = 0;
17984       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
17985     }
17986
17987   mp->mask_length = length;
17988   mp->number_of_ranges = vec_len (low_ports);
17989
17990   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
17991   vec_free (low_ports);
17992
17993   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
17994   vec_free (high_ports);
17995
17996   mp->vrf_id = ntohl (vrf_id);
17997
17998   S (mp);
17999   W (ret);
18000   return ret;
18001 }
18002
18003 int
18004 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
18005 {
18006   unformat_input_t *input = vam->input;
18007   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
18008   u32 sw_if_index = ~0;
18009   int vrf_set = 0;
18010   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
18011   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
18012   u8 is_add = 1;
18013   int ret;
18014
18015   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18016     {
18017       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18018         ;
18019       else if (unformat (input, "sw_if_index %d", &sw_if_index))
18020         ;
18021       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
18022         vrf_set = 1;
18023       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
18024         vrf_set = 1;
18025       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
18026         vrf_set = 1;
18027       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
18028         vrf_set = 1;
18029       else if (unformat (input, "del"))
18030         is_add = 0;
18031       else
18032         break;
18033     }
18034
18035   if (sw_if_index == ~0)
18036     {
18037       errmsg ("Interface required but not specified");
18038       return -99;
18039     }
18040
18041   if (vrf_set == 0)
18042     {
18043       errmsg ("VRF ID required but not specified");
18044       return -99;
18045     }
18046
18047   if (tcp_out_vrf_id == 0
18048       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
18049     {
18050       errmsg
18051         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
18052       return -99;
18053     }
18054
18055   /* Construct the API message */
18056   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
18057
18058   mp->sw_if_index = ntohl (sw_if_index);
18059   mp->is_add = is_add;
18060   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
18061   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
18062   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
18063   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
18064
18065   /* send it... */
18066   S (mp);
18067
18068   /* Wait for a reply... */
18069   W (ret);
18070   return ret;
18071 }
18072
18073 static int
18074 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
18075 {
18076   unformat_input_t *i = vam->input;
18077   vl_api_ipsec_gre_add_del_tunnel_t *mp;
18078   u32 local_sa_id = 0;
18079   u32 remote_sa_id = 0;
18080   ip4_address_t src_address;
18081   ip4_address_t dst_address;
18082   u8 is_add = 1;
18083   int ret;
18084
18085   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18086     {
18087       if (unformat (i, "local_sa %d", &local_sa_id))
18088         ;
18089       else if (unformat (i, "remote_sa %d", &remote_sa_id))
18090         ;
18091       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
18092         ;
18093       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
18094         ;
18095       else if (unformat (i, "del"))
18096         is_add = 0;
18097       else
18098         {
18099           clib_warning ("parse error '%U'", format_unformat_error, i);
18100           return -99;
18101         }
18102     }
18103
18104   M (IPSEC_GRE_ADD_DEL_TUNNEL, mp);
18105
18106   mp->local_sa_id = ntohl (local_sa_id);
18107   mp->remote_sa_id = ntohl (remote_sa_id);
18108   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
18109   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
18110   mp->is_add = is_add;
18111
18112   S (mp);
18113   W (ret);
18114   return ret;
18115 }
18116
18117 static int
18118 api_punt (vat_main_t * vam)
18119 {
18120   unformat_input_t *i = vam->input;
18121   vl_api_punt_t *mp;
18122   u32 ipv = ~0;
18123   u32 protocol = ~0;
18124   u32 port = ~0;
18125   int is_add = 1;
18126   int ret;
18127
18128   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18129     {
18130       if (unformat (i, "ip %d", &ipv))
18131         ;
18132       else if (unformat (i, "protocol %d", &protocol))
18133         ;
18134       else if (unformat (i, "port %d", &port))
18135         ;
18136       else if (unformat (i, "del"))
18137         is_add = 0;
18138       else
18139         {
18140           clib_warning ("parse error '%U'", format_unformat_error, i);
18141           return -99;
18142         }
18143     }
18144
18145   M (PUNT, mp);
18146
18147   mp->is_add = (u8) is_add;
18148   mp->ipv = (u8) ipv;
18149   mp->l4_protocol = (u8) protocol;
18150   mp->l4_port = htons ((u16) port);
18151
18152   S (mp);
18153   W (ret);
18154   return ret;
18155 }
18156
18157 static void vl_api_ipsec_gre_tunnel_details_t_handler
18158   (vl_api_ipsec_gre_tunnel_details_t * mp)
18159 {
18160   vat_main_t *vam = &vat_main;
18161
18162   print (vam->ofp, "%11d%15U%15U%14d%14d",
18163          ntohl (mp->sw_if_index),
18164          format_ip4_address, &mp->src_address,
18165          format_ip4_address, &mp->dst_address,
18166          ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
18167 }
18168
18169 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
18170   (vl_api_ipsec_gre_tunnel_details_t * mp)
18171 {
18172   vat_main_t *vam = &vat_main;
18173   vat_json_node_t *node = NULL;
18174   struct in_addr ip4;
18175
18176   if (VAT_JSON_ARRAY != vam->json_tree.type)
18177     {
18178       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18179       vat_json_init_array (&vam->json_tree);
18180     }
18181   node = vat_json_array_add (&vam->json_tree);
18182
18183   vat_json_init_object (node);
18184   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
18185   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
18186   vat_json_object_add_ip4 (node, "src_address", ip4);
18187   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
18188   vat_json_object_add_ip4 (node, "dst_address", ip4);
18189   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
18190   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
18191 }
18192
18193 static int
18194 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
18195 {
18196   unformat_input_t *i = vam->input;
18197   vl_api_ipsec_gre_tunnel_dump_t *mp;
18198   vl_api_control_ping_t *mp_ping;
18199   u32 sw_if_index;
18200   u8 sw_if_index_set = 0;
18201   int ret;
18202
18203   /* Parse args required to build the message */
18204   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18205     {
18206       if (unformat (i, "sw_if_index %d", &sw_if_index))
18207         sw_if_index_set = 1;
18208       else
18209         break;
18210     }
18211
18212   if (sw_if_index_set == 0)
18213     {
18214       sw_if_index = ~0;
18215     }
18216
18217   if (!vam->json_output)
18218     {
18219       print (vam->ofp, "%11s%15s%15s%14s%14s",
18220              "sw_if_index", "src_address", "dst_address",
18221              "local_sa_id", "remote_sa_id");
18222     }
18223
18224   /* Get list of gre-tunnel interfaces */
18225   M (IPSEC_GRE_TUNNEL_DUMP, mp);
18226
18227   mp->sw_if_index = htonl (sw_if_index);
18228
18229   S (mp);
18230
18231   /* Use a control ping for synchronization */
18232   M (CONTROL_PING, mp_ping);
18233   S (mp_ping);
18234
18235   W (ret);
18236   return ret;
18237 }
18238
18239 static int
18240 api_delete_subif (vat_main_t * vam)
18241 {
18242   unformat_input_t *i = vam->input;
18243   vl_api_delete_subif_t *mp;
18244   u32 sw_if_index = ~0;
18245   int ret;
18246
18247   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18248     {
18249       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18250         ;
18251       if (unformat (i, "sw_if_index %d", &sw_if_index))
18252         ;
18253       else
18254         break;
18255     }
18256
18257   if (sw_if_index == ~0)
18258     {
18259       errmsg ("missing sw_if_index");
18260       return -99;
18261     }
18262
18263   /* Construct the API message */
18264   M (DELETE_SUBIF, mp);
18265   mp->sw_if_index = ntohl (sw_if_index);
18266
18267   S (mp);
18268   W (ret);
18269   return ret;
18270 }
18271
18272 #define foreach_pbb_vtr_op      \
18273 _("disable",  L2_VTR_DISABLED)  \
18274 _("pop",  L2_VTR_POP_2)         \
18275 _("push",  L2_VTR_PUSH_2)
18276
18277 static int
18278 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
18279 {
18280   unformat_input_t *i = vam->input;
18281   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
18282   u32 sw_if_index = ~0, vtr_op = ~0;
18283   u16 outer_tag = ~0;
18284   u8 dmac[6], smac[6];
18285   u8 dmac_set = 0, smac_set = 0;
18286   u16 vlanid = 0;
18287   u32 sid = ~0;
18288   u32 tmp;
18289   int ret;
18290
18291   /* Shut up coverity */
18292   memset (dmac, 0, sizeof (dmac));
18293   memset (smac, 0, sizeof (smac));
18294
18295   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18296     {
18297       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18298         ;
18299       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18300         ;
18301       else if (unformat (i, "vtr_op %d", &vtr_op))
18302         ;
18303 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
18304       foreach_pbb_vtr_op
18305 #undef _
18306         else if (unformat (i, "translate_pbb_stag"))
18307         {
18308           if (unformat (i, "%d", &tmp))
18309             {
18310               vtr_op = L2_VTR_TRANSLATE_2_1;
18311               outer_tag = tmp;
18312             }
18313           else
18314             {
18315               errmsg
18316                 ("translate_pbb_stag operation requires outer tag definition");
18317               return -99;
18318             }
18319         }
18320       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
18321         dmac_set++;
18322       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
18323         smac_set++;
18324       else if (unformat (i, "sid %d", &sid))
18325         ;
18326       else if (unformat (i, "vlanid %d", &tmp))
18327         vlanid = tmp;
18328       else
18329         {
18330           clib_warning ("parse error '%U'", format_unformat_error, i);
18331           return -99;
18332         }
18333     }
18334
18335   if ((sw_if_index == ~0) || (vtr_op == ~0))
18336     {
18337       errmsg ("missing sw_if_index or vtr operation");
18338       return -99;
18339     }
18340   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
18341       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
18342     {
18343       errmsg
18344         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
18345       return -99;
18346     }
18347
18348   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
18349   mp->sw_if_index = ntohl (sw_if_index);
18350   mp->vtr_op = ntohl (vtr_op);
18351   mp->outer_tag = ntohs (outer_tag);
18352   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
18353   clib_memcpy (mp->b_smac, smac, sizeof (smac));
18354   mp->b_vlanid = ntohs (vlanid);
18355   mp->i_sid = ntohl (sid);
18356
18357   S (mp);
18358   W (ret);
18359   return ret;
18360 }
18361
18362 static int
18363 api_flow_classify_set_interface (vat_main_t * vam)
18364 {
18365   unformat_input_t *i = vam->input;
18366   vl_api_flow_classify_set_interface_t *mp;
18367   u32 sw_if_index;
18368   int sw_if_index_set;
18369   u32 ip4_table_index = ~0;
18370   u32 ip6_table_index = ~0;
18371   u8 is_add = 1;
18372   int ret;
18373
18374   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18375     {
18376       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18377         sw_if_index_set = 1;
18378       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18379         sw_if_index_set = 1;
18380       else if (unformat (i, "del"))
18381         is_add = 0;
18382       else if (unformat (i, "ip4-table %d", &ip4_table_index))
18383         ;
18384       else if (unformat (i, "ip6-table %d", &ip6_table_index))
18385         ;
18386       else
18387         {
18388           clib_warning ("parse error '%U'", format_unformat_error, i);
18389           return -99;
18390         }
18391     }
18392
18393   if (sw_if_index_set == 0)
18394     {
18395       errmsg ("missing interface name or sw_if_index");
18396       return -99;
18397     }
18398
18399   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
18400
18401   mp->sw_if_index = ntohl (sw_if_index);
18402   mp->ip4_table_index = ntohl (ip4_table_index);
18403   mp->ip6_table_index = ntohl (ip6_table_index);
18404   mp->is_add = is_add;
18405
18406   S (mp);
18407   W (ret);
18408   return ret;
18409 }
18410
18411 static int
18412 api_flow_classify_dump (vat_main_t * vam)
18413 {
18414   unformat_input_t *i = vam->input;
18415   vl_api_flow_classify_dump_t *mp;
18416   vl_api_control_ping_t *mp_ping;
18417   u8 type = FLOW_CLASSIFY_N_TABLES;
18418   int ret;
18419
18420   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
18421     ;
18422   else
18423     {
18424       errmsg ("classify table type must be specified");
18425       return -99;
18426     }
18427
18428   if (!vam->json_output)
18429     {
18430       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
18431     }
18432
18433   M (FLOW_CLASSIFY_DUMP, mp);
18434   mp->type = type;
18435   /* send it... */
18436   S (mp);
18437
18438   /* Use a control ping for synchronization */
18439   M (CONTROL_PING, mp_ping);
18440   S (mp_ping);
18441
18442   /* Wait for a reply... */
18443   W (ret);
18444   return ret;
18445 }
18446
18447 static int
18448 api_feature_enable_disable (vat_main_t * vam)
18449 {
18450   unformat_input_t *i = vam->input;
18451   vl_api_feature_enable_disable_t *mp;
18452   u8 *arc_name = 0;
18453   u8 *feature_name = 0;
18454   u32 sw_if_index = ~0;
18455   u8 enable = 1;
18456   int ret;
18457
18458   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18459     {
18460       if (unformat (i, "arc_name %s", &arc_name))
18461         ;
18462       else if (unformat (i, "feature_name %s", &feature_name))
18463         ;
18464       else
18465         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18466         ;
18467       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18468         ;
18469       else if (unformat (i, "disable"))
18470         enable = 0;
18471       else
18472         break;
18473     }
18474
18475   if (arc_name == 0)
18476     {
18477       errmsg ("missing arc name");
18478       return -99;
18479     }
18480   if (vec_len (arc_name) > 63)
18481     {
18482       errmsg ("arc name too long");
18483     }
18484
18485   if (feature_name == 0)
18486     {
18487       errmsg ("missing feature name");
18488       return -99;
18489     }
18490   if (vec_len (feature_name) > 63)
18491     {
18492       errmsg ("feature name too long");
18493     }
18494
18495   if (sw_if_index == ~0)
18496     {
18497       errmsg ("missing interface name or sw_if_index");
18498       return -99;
18499     }
18500
18501   /* Construct the API message */
18502   M (FEATURE_ENABLE_DISABLE, mp);
18503   mp->sw_if_index = ntohl (sw_if_index);
18504   mp->enable = enable;
18505   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
18506   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
18507   vec_free (arc_name);
18508   vec_free (feature_name);
18509
18510   S (mp);
18511   W (ret);
18512   return ret;
18513 }
18514
18515 static int
18516 api_sw_interface_tag_add_del (vat_main_t * vam)
18517 {
18518   unformat_input_t *i = vam->input;
18519   vl_api_sw_interface_tag_add_del_t *mp;
18520   u32 sw_if_index = ~0;
18521   u8 *tag = 0;
18522   u8 enable = 1;
18523   int ret;
18524
18525   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18526     {
18527       if (unformat (i, "tag %s", &tag))
18528         ;
18529       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18530         ;
18531       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18532         ;
18533       else if (unformat (i, "del"))
18534         enable = 0;
18535       else
18536         break;
18537     }
18538
18539   if (sw_if_index == ~0)
18540     {
18541       errmsg ("missing interface name or sw_if_index");
18542       return -99;
18543     }
18544
18545   if (enable && (tag == 0))
18546     {
18547       errmsg ("no tag specified");
18548       return -99;
18549     }
18550
18551   /* Construct the API message */
18552   M (SW_INTERFACE_TAG_ADD_DEL, mp);
18553   mp->sw_if_index = ntohl (sw_if_index);
18554   mp->is_add = enable;
18555   if (enable)
18556     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
18557   vec_free (tag);
18558
18559   S (mp);
18560   W (ret);
18561   return ret;
18562 }
18563
18564 static void vl_api_l2_xconnect_details_t_handler
18565   (vl_api_l2_xconnect_details_t * mp)
18566 {
18567   vat_main_t *vam = &vat_main;
18568
18569   print (vam->ofp, "%15d%15d",
18570          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
18571 }
18572
18573 static void vl_api_l2_xconnect_details_t_handler_json
18574   (vl_api_l2_xconnect_details_t * mp)
18575 {
18576   vat_main_t *vam = &vat_main;
18577   vat_json_node_t *node = NULL;
18578
18579   if (VAT_JSON_ARRAY != vam->json_tree.type)
18580     {
18581       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18582       vat_json_init_array (&vam->json_tree);
18583     }
18584   node = vat_json_array_add (&vam->json_tree);
18585
18586   vat_json_init_object (node);
18587   vat_json_object_add_uint (node, "rx_sw_if_index",
18588                             ntohl (mp->rx_sw_if_index));
18589   vat_json_object_add_uint (node, "tx_sw_if_index",
18590                             ntohl (mp->tx_sw_if_index));
18591 }
18592
18593 static int
18594 api_l2_xconnect_dump (vat_main_t * vam)
18595 {
18596   vl_api_l2_xconnect_dump_t *mp;
18597   vl_api_control_ping_t *mp_ping;
18598   int ret;
18599
18600   if (!vam->json_output)
18601     {
18602       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
18603     }
18604
18605   M (L2_XCONNECT_DUMP, mp);
18606
18607   S (mp);
18608
18609   /* Use a control ping for synchronization */
18610   M (CONTROL_PING, mp_ping);
18611   S (mp_ping);
18612
18613   W (ret);
18614   return ret;
18615 }
18616
18617 static int
18618 api_sw_interface_set_mtu (vat_main_t * vam)
18619 {
18620   unformat_input_t *i = vam->input;
18621   vl_api_sw_interface_set_mtu_t *mp;
18622   u32 sw_if_index = ~0;
18623   u32 mtu = 0;
18624   int ret;
18625
18626   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18627     {
18628       if (unformat (i, "mtu %d", &mtu))
18629         ;
18630       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18631         ;
18632       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18633         ;
18634       else
18635         break;
18636     }
18637
18638   if (sw_if_index == ~0)
18639     {
18640       errmsg ("missing interface name or sw_if_index");
18641       return -99;
18642     }
18643
18644   if (mtu == 0)
18645     {
18646       errmsg ("no mtu specified");
18647       return -99;
18648     }
18649
18650   /* Construct the API message */
18651   M (SW_INTERFACE_SET_MTU, mp);
18652   mp->sw_if_index = ntohl (sw_if_index);
18653   mp->mtu = ntohs ((u16) mtu);
18654
18655   S (mp);
18656   W (ret);
18657   return ret;
18658 }
18659
18660
18661 static int
18662 q_or_quit (vat_main_t * vam)
18663 {
18664 #if VPP_API_TEST_BUILTIN == 0
18665   longjmp (vam->jump_buf, 1);
18666 #endif
18667   return 0;                     /* not so much */
18668 }
18669
18670 static int
18671 q (vat_main_t * vam)
18672 {
18673   return q_or_quit (vam);
18674 }
18675
18676 static int
18677 quit (vat_main_t * vam)
18678 {
18679   return q_or_quit (vam);
18680 }
18681
18682 static int
18683 comment (vat_main_t * vam)
18684 {
18685   return 0;
18686 }
18687
18688 static int
18689 cmd_cmp (void *a1, void *a2)
18690 {
18691   u8 **c1 = a1;
18692   u8 **c2 = a2;
18693
18694   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
18695 }
18696
18697 static int
18698 help (vat_main_t * vam)
18699 {
18700   u8 **cmds = 0;
18701   u8 *name = 0;
18702   hash_pair_t *p;
18703   unformat_input_t *i = vam->input;
18704   int j;
18705
18706   if (unformat (i, "%s", &name))
18707     {
18708       uword *hs;
18709
18710       vec_add1 (name, 0);
18711
18712       hs = hash_get_mem (vam->help_by_name, name);
18713       if (hs)
18714         print (vam->ofp, "usage: %s %s", name, hs[0]);
18715       else
18716         print (vam->ofp, "No such msg / command '%s'", name);
18717       vec_free (name);
18718       return 0;
18719     }
18720
18721   print (vam->ofp, "Help is available for the following:");
18722
18723     /* *INDENT-OFF* */
18724     hash_foreach_pair (p, vam->function_by_name,
18725     ({
18726       vec_add1 (cmds, (u8 *)(p->key));
18727     }));
18728     /* *INDENT-ON* */
18729
18730   vec_sort_with_function (cmds, cmd_cmp);
18731
18732   for (j = 0; j < vec_len (cmds); j++)
18733     print (vam->ofp, "%s", cmds[j]);
18734
18735   vec_free (cmds);
18736   return 0;
18737 }
18738
18739 static int
18740 set (vat_main_t * vam)
18741 {
18742   u8 *name = 0, *value = 0;
18743   unformat_input_t *i = vam->input;
18744
18745   if (unformat (i, "%s", &name))
18746     {
18747       /* The input buffer is a vector, not a string. */
18748       value = vec_dup (i->buffer);
18749       vec_delete (value, i->index, 0);
18750       /* Almost certainly has a trailing newline */
18751       if (value[vec_len (value) - 1] == '\n')
18752         value[vec_len (value) - 1] = 0;
18753       /* Make sure it's a proper string, one way or the other */
18754       vec_add1 (value, 0);
18755       (void) clib_macro_set_value (&vam->macro_main,
18756                                    (char *) name, (char *) value);
18757     }
18758   else
18759     errmsg ("usage: set <name> <value>");
18760
18761   vec_free (name);
18762   vec_free (value);
18763   return 0;
18764 }
18765
18766 static int
18767 unset (vat_main_t * vam)
18768 {
18769   u8 *name = 0;
18770
18771   if (unformat (vam->input, "%s", &name))
18772     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
18773       errmsg ("unset: %s wasn't set", name);
18774   vec_free (name);
18775   return 0;
18776 }
18777
18778 typedef struct
18779 {
18780   u8 *name;
18781   u8 *value;
18782 } macro_sort_t;
18783
18784
18785 static int
18786 macro_sort_cmp (void *a1, void *a2)
18787 {
18788   macro_sort_t *s1 = a1;
18789   macro_sort_t *s2 = a2;
18790
18791   return strcmp ((char *) (s1->name), (char *) (s2->name));
18792 }
18793
18794 static int
18795 dump_macro_table (vat_main_t * vam)
18796 {
18797   macro_sort_t *sort_me = 0, *sm;
18798   int i;
18799   hash_pair_t *p;
18800
18801     /* *INDENT-OFF* */
18802     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
18803     ({
18804       vec_add2 (sort_me, sm, 1);
18805       sm->name = (u8 *)(p->key);
18806       sm->value = (u8 *) (p->value[0]);
18807     }));
18808     /* *INDENT-ON* */
18809
18810   vec_sort_with_function (sort_me, macro_sort_cmp);
18811
18812   if (vec_len (sort_me))
18813     print (vam->ofp, "%-15s%s", "Name", "Value");
18814   else
18815     print (vam->ofp, "The macro table is empty...");
18816
18817   for (i = 0; i < vec_len (sort_me); i++)
18818     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
18819   return 0;
18820 }
18821
18822 static int
18823 dump_node_table (vat_main_t * vam)
18824 {
18825   int i, j;
18826   vlib_node_t *node, *next_node;
18827
18828   if (vec_len (vam->graph_nodes) == 0)
18829     {
18830       print (vam->ofp, "Node table empty, issue get_node_graph...");
18831       return 0;
18832     }
18833
18834   for (i = 0; i < vec_len (vam->graph_nodes); i++)
18835     {
18836       node = vam->graph_nodes[i];
18837       print (vam->ofp, "[%d] %s", i, node->name);
18838       for (j = 0; j < vec_len (node->next_nodes); j++)
18839         {
18840           if (node->next_nodes[j] != ~0)
18841             {
18842               next_node = vam->graph_nodes[node->next_nodes[j]];
18843               print (vam->ofp, "  [%d] %s", j, next_node->name);
18844             }
18845         }
18846     }
18847   return 0;
18848 }
18849
18850 static int
18851 value_sort_cmp (void *a1, void *a2)
18852 {
18853   name_sort_t *n1 = a1;
18854   name_sort_t *n2 = a2;
18855
18856   if (n1->value < n2->value)
18857     return -1;
18858   if (n1->value > n2->value)
18859     return 1;
18860   return 0;
18861 }
18862
18863
18864 static int
18865 dump_msg_api_table (vat_main_t * vam)
18866 {
18867   api_main_t *am = &api_main;
18868   name_sort_t *nses = 0, *ns;
18869   hash_pair_t *hp;
18870   int i;
18871
18872   /* *INDENT-OFF* */
18873   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
18874   ({
18875     vec_add2 (nses, ns, 1);
18876     ns->name = (u8 *)(hp->key);
18877     ns->value = (u32) hp->value[0];
18878   }));
18879   /* *INDENT-ON* */
18880
18881   vec_sort_with_function (nses, value_sort_cmp);
18882
18883   for (i = 0; i < vec_len (nses); i++)
18884     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
18885   vec_free (nses);
18886   return 0;
18887 }
18888
18889 static int
18890 get_msg_id (vat_main_t * vam)
18891 {
18892   u8 *name_and_crc;
18893   u32 message_index;
18894
18895   if (unformat (vam->input, "%s", &name_and_crc))
18896     {
18897       message_index = vl_api_get_msg_index (name_and_crc);
18898       if (message_index == ~0)
18899         {
18900           print (vam->ofp, " '%s' not found", name_and_crc);
18901           return 0;
18902         }
18903       print (vam->ofp, " '%s' has message index %d",
18904              name_and_crc, message_index);
18905       return 0;
18906     }
18907   errmsg ("name_and_crc required...");
18908   return 0;
18909 }
18910
18911 static int
18912 search_node_table (vat_main_t * vam)
18913 {
18914   unformat_input_t *line_input = vam->input;
18915   u8 *node_to_find;
18916   int j;
18917   vlib_node_t *node, *next_node;
18918   uword *p;
18919
18920   if (vam->graph_node_index_by_name == 0)
18921     {
18922       print (vam->ofp, "Node table empty, issue get_node_graph...");
18923       return 0;
18924     }
18925
18926   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
18927     {
18928       if (unformat (line_input, "%s", &node_to_find))
18929         {
18930           vec_add1 (node_to_find, 0);
18931           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
18932           if (p == 0)
18933             {
18934               print (vam->ofp, "%s not found...", node_to_find);
18935               goto out;
18936             }
18937           node = vam->graph_nodes[p[0]];
18938           print (vam->ofp, "[%d] %s", p[0], node->name);
18939           for (j = 0; j < vec_len (node->next_nodes); j++)
18940             {
18941               if (node->next_nodes[j] != ~0)
18942                 {
18943                   next_node = vam->graph_nodes[node->next_nodes[j]];
18944                   print (vam->ofp, "  [%d] %s", j, next_node->name);
18945                 }
18946             }
18947         }
18948
18949       else
18950         {
18951           clib_warning ("parse error '%U'", format_unformat_error,
18952                         line_input);
18953           return -99;
18954         }
18955
18956     out:
18957       vec_free (node_to_find);
18958
18959     }
18960
18961   return 0;
18962 }
18963
18964
18965 static int
18966 script (vat_main_t * vam)
18967 {
18968 #if (VPP_API_TEST_BUILTIN==0)
18969   u8 *s = 0;
18970   char *save_current_file;
18971   unformat_input_t save_input;
18972   jmp_buf save_jump_buf;
18973   u32 save_line_number;
18974
18975   FILE *new_fp, *save_ifp;
18976
18977   if (unformat (vam->input, "%s", &s))
18978     {
18979       new_fp = fopen ((char *) s, "r");
18980       if (new_fp == 0)
18981         {
18982           errmsg ("Couldn't open script file %s", s);
18983           vec_free (s);
18984           return -99;
18985         }
18986     }
18987   else
18988     {
18989       errmsg ("Missing script name");
18990       return -99;
18991     }
18992
18993   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
18994   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
18995   save_ifp = vam->ifp;
18996   save_line_number = vam->input_line_number;
18997   save_current_file = (char *) vam->current_file;
18998
18999   vam->input_line_number = 0;
19000   vam->ifp = new_fp;
19001   vam->current_file = s;
19002   do_one_file (vam);
19003
19004   clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
19005   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
19006   vam->ifp = save_ifp;
19007   vam->input_line_number = save_line_number;
19008   vam->current_file = (u8 *) save_current_file;
19009   vec_free (s);
19010
19011   return 0;
19012 #else
19013   clib_warning ("use the exec command...");
19014   return -99;
19015 #endif
19016 }
19017
19018 static int
19019 echo (vat_main_t * vam)
19020 {
19021   print (vam->ofp, "%v", vam->input->buffer);
19022   return 0;
19023 }
19024
19025 /* List of API message constructors, CLI names map to api_xxx */
19026 #define foreach_vpe_api_msg                                             \
19027 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
19028 _(sw_interface_dump,"")                                                 \
19029 _(sw_interface_set_flags,                                               \
19030   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
19031 _(sw_interface_add_del_address,                                         \
19032   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
19033 _(sw_interface_set_table,                                               \
19034   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
19035 _(sw_interface_set_mpls_enable,                                         \
19036   "<intfc> | sw_if_index [disable | dis]")                              \
19037 _(sw_interface_set_vpath,                                               \
19038   "<intfc> | sw_if_index <id> enable | disable")                        \
19039 _(sw_interface_set_vxlan_bypass,                                        \
19040   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
19041 _(sw_interface_set_l2_xconnect,                                         \
19042   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
19043   "enable | disable")                                                   \
19044 _(sw_interface_set_l2_bridge,                                           \
19045   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
19046   "[shg <split-horizon-group>] [bvi]\n"                                 \
19047   "enable | disable")                                                   \
19048 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
19049 _(bridge_domain_add_del,                                                \
19050   "bd_id <bridge-domain-id> [flood 1|0] [uu-flood 1|0] [forward 1|0] [learn 1|0] [arp-term 1|0] [mac-age 0-255] [del]\n") \
19051 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
19052 _(l2fib_add_del,                                                        \
19053   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
19054 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
19055 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
19056 _(l2_flags,                                                             \
19057   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood]\n") \
19058 _(bridge_flags,                                                         \
19059   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
19060 _(tap_connect,                                                          \
19061   "tapname <name> mac <mac-addr> | random-mac [tag <string>]")          \
19062 _(tap_modify,                                                           \
19063   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
19064 _(tap_delete,                                                           \
19065   "<vpp-if-name> | sw_if_index <id>")                                   \
19066 _(sw_interface_tap_dump, "")                                            \
19067 _(ip_add_del_route,                                                     \
19068   "<addr>/<mask> via <addr> [table-id <n>]\n"                           \
19069   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
19070   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
19071   "[multipath] [count <n>]")                                            \
19072 _(ip_mroute_add_del,                                                    \
19073   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
19074   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
19075 _(mpls_route_add_del,                                                   \
19076   "<label> <eos> via <addr> [table-id <n>]\n"                           \
19077   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
19078   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
19079   "[multipath] [count <n>]")                                            \
19080 _(mpls_ip_bind_unbind,                                                  \
19081   "<label> <addr/len>")                                                 \
19082 _(mpls_tunnel_add_del,                                                  \
19083   " via <addr> [table-id <n>]\n"                                        \
19084   "sw_if_index <id>] [l2]  [del]")                                      \
19085 _(proxy_arp_add_del,                                                    \
19086   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
19087 _(proxy_arp_intfc_enable_disable,                                       \
19088   "<intfc> | sw_if_index <id> enable | disable")                        \
19089 _(sw_interface_set_unnumbered,                                          \
19090   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
19091 _(ip_neighbor_add_del,                                                  \
19092   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
19093   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
19094 _(reset_vrf, "vrf <id> [ipv6]")                                         \
19095 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
19096 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
19097   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
19098   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
19099   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
19100 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
19101 _(reset_fib, "vrf <n> [ipv6]")                                          \
19102 _(dhcp_proxy_config,                                                    \
19103   "svr <v46-address> src <v46-address>\n"                               \
19104    "rx_vrf_id <nn> server_vrf_id <nn>  [del]")                          \
19105 _(dhcp_proxy_set_vss,                                                   \
19106   "tbl_id <n> fib_id <n> oui <n> [ipv6] [del]")                         \
19107 _(dhcp_proxy_dump, "ip6")                                               \
19108 _(dhcp_client_config,                                                   \
19109   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
19110 _(set_ip_flow_hash,                                                     \
19111   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
19112 _(sw_interface_ip6_enable_disable,                                      \
19113   "<intfc> | sw_if_index <id> enable | disable")                        \
19114 _(sw_interface_ip6_set_link_local_address,                              \
19115   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
19116 _(ip6nd_proxy_add_del,                                                  \
19117   "<intfc> | sw_if_index <id> <ip6-address>")                           \
19118 _(ip6nd_proxy_dump, "")                                                 \
19119 _(sw_interface_ip6nd_ra_prefix,                                         \
19120   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
19121   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
19122   "[nolink] [isno]")                                                    \
19123 _(sw_interface_ip6nd_ra_config,                                         \
19124   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
19125   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
19126   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
19127 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
19128 _(l2_patch_add_del,                                                     \
19129   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
19130   "enable | disable")                                                   \
19131 _(sr_localsid_add_del,                                                  \
19132   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
19133   "fib-table <num> (end.psp) sw_if_index <num>")                        \
19134 _(classify_add_del_table,                                               \
19135   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
19136   " [del] [del-chain] mask <mask-value>\n"                              \
19137   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
19138   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
19139 _(classify_add_del_session,                                             \
19140   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
19141   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
19142   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
19143   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
19144 _(classify_set_interface_ip_table,                                      \
19145   "<intfc> | sw_if_index <nn> table <nn>")                              \
19146 _(classify_set_interface_l2_tables,                                     \
19147   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
19148   "  [other-table <nn>]")                                               \
19149 _(get_node_index, "node <node-name")                                    \
19150 _(add_node_next, "node <node-name> next <next-node-name>")              \
19151 _(l2tpv3_create_tunnel,                                                 \
19152   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
19153   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
19154   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
19155 _(l2tpv3_set_tunnel_cookies,                                            \
19156   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
19157   "[new_remote_cookie <nn>]\n")                                         \
19158 _(l2tpv3_interface_enable_disable,                                      \
19159   "<intfc> | sw_if_index <nn> enable | disable")                        \
19160 _(l2tpv3_set_lookup_key,                                                \
19161   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
19162 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
19163 _(vxlan_add_del_tunnel,                                                 \
19164   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
19165   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
19166   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
19167 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
19168 _(gre_add_del_tunnel,                                                   \
19169   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [teb] [del]\n")    \
19170 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
19171 _(l2_fib_clear_table, "")                                               \
19172 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
19173 _(l2_interface_vlan_tag_rewrite,                                        \
19174   "<intfc> | sw_if_index <nn> \n"                                       \
19175   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
19176   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
19177 _(create_vhost_user_if,                                                 \
19178         "socket <filename> [server] [renumber <dev_instance>] "         \
19179         "[mac <mac_address>]")                                          \
19180 _(modify_vhost_user_if,                                                 \
19181         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
19182         "[server] [renumber <dev_instance>]")                           \
19183 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
19184 _(sw_interface_vhost_user_dump, "")                                     \
19185 _(show_version, "")                                                     \
19186 _(vxlan_gpe_add_del_tunnel,                                             \
19187   "local <addr> remote <addr> vni <nn>\n"                               \
19188     "[encap-vrf-id <nn>] [decap-vrf-id <nn>] [next-ip4][next-ip6]"      \
19189   "[next-ethernet] [next-nsh]\n")                                       \
19190 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
19191 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
19192 _(interface_name_renumber,                                              \
19193   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
19194 _(input_acl_set_interface,                                              \
19195   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
19196   "  [l2-table <nn>] [del]")                                            \
19197 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
19198 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
19199 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
19200 _(ip_dump, "ipv4 | ipv6")                                               \
19201 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
19202 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
19203   "  spid_id <n> ")                                                     \
19204 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
19205   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
19206   "  integ_alg <alg> integ_key <hex>")                                  \
19207 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
19208   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
19209   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
19210   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
19211 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
19212 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
19213   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
19214   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
19215   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n")     \
19216 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
19217 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
19218   "(auth_data 0x<data> | auth_data <data>)")                            \
19219 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
19220   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
19221 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
19222   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
19223   "(local|remote)")                                                     \
19224 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
19225 _(ikev2_set_responder, "<profile_name> interface <interface> address <addr>") \
19226 _(ikev2_set_ike_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
19227 _(ikev2_set_esp_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
19228 _(ikev2_set_sa_lifetime, "<profile_name> <seconds> <jitter> <handover> <max bytes>") \
19229 _(ikev2_initiate_sa_init, "<profile_name>")                             \
19230 _(ikev2_initiate_del_ike_sa, "<ispi>")                                  \
19231 _(ikev2_initiate_del_child_sa, "<ispi>")                                \
19232 _(ikev2_initiate_rekey_child_sa, "<ispi>")                              \
19233 _(delete_loopback,"sw_if_index <nn>")                                   \
19234 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
19235 _(map_add_domain,                                                       \
19236   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
19237   "ip6-src <ip6addr> "                                                  \
19238   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
19239 _(map_del_domain, "index <n>")                                          \
19240 _(map_add_del_rule,                                                     \
19241   "index <n> psid <n> dst <ip6addr> [del]")                             \
19242 _(map_domain_dump, "")                                                  \
19243 _(map_rule_dump, "index <map-domain>")                                  \
19244 _(want_interface_events,  "enable|disable")                             \
19245 _(want_stats,"enable|disable")                                          \
19246 _(get_first_msg_id, "client <name>")                                    \
19247 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
19248 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
19249   "fib-id <nn> [ip4][ip6][default]")                                    \
19250 _(get_node_graph, " ")                                                  \
19251 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
19252 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
19253 _(ioam_disable, "")                                                     \
19254 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
19255                             " sw_if_index <sw_if_index> p <priority> "  \
19256                             "w <weight>] [del]")                        \
19257 _(one_add_del_locator, "locator-set <locator_name> "                    \
19258                         "iface <intf> | sw_if_index <sw_if_index> "     \
19259                         "p <priority> w <weight> [del]")                \
19260 _(one_add_del_local_eid,"vni <vni> eid "                                \
19261                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
19262                          "locator-set <locator_name> [del]"             \
19263                          "[key-id sha1|sha256 secret-key <secret-key>]")\
19264 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
19265 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
19266 _(one_enable_disable, "enable|disable")                                 \
19267 _(one_map_register_enable_disable, "enable|disable")                    \
19268 _(one_rloc_probe_enable_disable, "enable|disable")                      \
19269 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
19270                                "[seid <seid>] "                         \
19271                                "rloc <locator> p <prio> "               \
19272                                "w <weight> [rloc <loc> ... ] "          \
19273                                "action <action> [del-all]")             \
19274 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
19275                           "<local-eid>")                                \
19276 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
19277 _(one_use_petr, "ip-address> | disable")                                \
19278 _(one_map_request_mode, "src-dst|dst-only")                             \
19279 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
19280 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
19281 _(one_locator_set_dump, "[local | remote]")                             \
19282 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
19283 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
19284                        "[local] | [remote]")                            \
19285 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
19286 _(one_l2_arp_bd_get, "")                                                \
19287 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
19288 _(one_stats_enable_disable, "enable|disalbe")                           \
19289 _(show_one_stats_enable_disable, "")                                    \
19290 _(one_eid_table_vni_dump, "")                                           \
19291 _(one_eid_table_map_dump, "l2|l3")                                      \
19292 _(one_map_resolver_dump, "")                                            \
19293 _(one_map_server_dump, "")                                              \
19294 _(one_adjacencies_get, "vni <vni>")                                     \
19295 _(show_one_rloc_probe_state, "")                                        \
19296 _(show_one_map_register_state, "")                                      \
19297 _(show_one_status, "")                                                  \
19298 _(one_stats_dump, "")                                                   \
19299 _(one_stats_flush, "")                                                  \
19300 _(one_get_map_request_itr_rlocs, "")                                    \
19301 _(show_one_pitr, "")                                                    \
19302 _(show_one_use_petr, "")                                                \
19303 _(show_one_map_request_mode, "")                                        \
19304 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
19305                             " sw_if_index <sw_if_index> p <priority> "  \
19306                             "w <weight>] [del]")                        \
19307 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
19308                         "iface <intf> | sw_if_index <sw_if_index> "     \
19309                         "p <priority> w <weight> [del]")                \
19310 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
19311                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
19312                          "locator-set <locator_name> [del]"             \
19313                          "[key-id sha1|sha256 secret-key <secret-key>]") \
19314 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
19315 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
19316 _(lisp_enable_disable, "enable|disable")                                \
19317 _(lisp_map_register_enable_disable, "enable|disable")                   \
19318 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
19319 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
19320                                "[seid <seid>] "                         \
19321                                "rloc <locator> p <prio> "               \
19322                                "w <weight> [rloc <loc> ... ] "          \
19323                                "action <action> [del-all]")             \
19324 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
19325                           "<local-eid>")                                \
19326 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
19327 _(lisp_use_petr, "<ip-address> | disable")                              \
19328 _(lisp_map_request_mode, "src-dst|dst-only")                            \
19329 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
19330 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
19331 _(lisp_locator_set_dump, "[local | remote]")                            \
19332 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
19333 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
19334                        "[local] | [remote]")                            \
19335 _(lisp_eid_table_vni_dump, "")                                          \
19336 _(lisp_eid_table_map_dump, "l2|l3")                                     \
19337 _(lisp_map_resolver_dump, "")                                           \
19338 _(lisp_map_server_dump, "")                                             \
19339 _(lisp_adjacencies_get, "vni <vni>")                                    \
19340 _(gpe_fwd_entry_vnis_get, "")                                           \
19341 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
19342 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
19343 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
19344 _(gpe_get_encap_mode, "")                                               \
19345 _(lisp_gpe_add_del_iface, "up|down")                                    \
19346 _(lisp_gpe_enable_disable, "enable|disable")                            \
19347 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
19348   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
19349 _(show_lisp_rloc_probe_state, "")                                       \
19350 _(show_lisp_map_register_state, "")                                     \
19351 _(show_lisp_status, "")                                                 \
19352 _(lisp_get_map_request_itr_rlocs, "")                                   \
19353 _(show_lisp_pitr, "")                                                   \
19354 _(show_lisp_use_petr, "")                                               \
19355 _(show_lisp_map_request_mode, "")                                       \
19356 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
19357 _(af_packet_delete, "name <host interface name>")                       \
19358 _(policer_add_del, "name <policer name> <params> [del]")                \
19359 _(policer_dump, "[name <policer name>]")                                \
19360 _(policer_classify_set_interface,                                       \
19361   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
19362   "  [l2-table <nn>] [del]")                                            \
19363 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
19364 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
19365     "[master|slave]")                                                   \
19366 _(netmap_delete, "name <interface name>")                               \
19367 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
19368 _(mpls_fib_dump, "")                                                    \
19369 _(classify_table_ids, "")                                               \
19370 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
19371 _(classify_table_info, "table_id <nn>")                                 \
19372 _(classify_session_dump, "table_id <nn>")                               \
19373 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
19374     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
19375     "[template_interval <nn>] [udp_checksum]")                          \
19376 _(ipfix_exporter_dump, "")                                              \
19377 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
19378 _(ipfix_classify_stream_dump, "")                                       \
19379 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
19380 _(ipfix_classify_table_dump, "")                                        \
19381 _(sw_interface_span_enable_disable, "[src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
19382 _(sw_interface_span_dump, "")                                           \
19383 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
19384 _(pg_create_interface, "if_id <nn>")                                    \
19385 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
19386 _(pg_enable_disable, "[stream <id>] disable")                           \
19387 _(ip_source_and_port_range_check_add_del,                               \
19388   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
19389 _(ip_source_and_port_range_check_interface_add_del,                     \
19390   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
19391   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
19392 _(ipsec_gre_add_del_tunnel,                                             \
19393   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
19394 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
19395 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
19396 _(l2_interface_pbb_tag_rewrite,                                         \
19397   "<intfc> | sw_if_index <nn> \n"                                       \
19398   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
19399   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
19400 _(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
19401 _(flow_classify_set_interface,                                          \
19402   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
19403 _(flow_classify_dump, "type [ip4|ip6]")                                 \
19404 _(ip_fib_dump, "")                                                      \
19405 _(ip_mfib_dump, "")                                                     \
19406 _(ip6_fib_dump, "")                                                     \
19407 _(ip6_mfib_dump, "")                                                    \
19408 _(feature_enable_disable, "arc_name <arc_name> "                        \
19409   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
19410 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
19411 "[disable]")                                                            \
19412 _(l2_xconnect_dump, "")                                                 \
19413 _(sw_interface_set_mtu, "<intfc> | sw_if_index <nn> mtu <nn>")        \
19414 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
19415 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")
19416
19417 /* List of command functions, CLI names map directly to functions */
19418 #define foreach_cli_function                                    \
19419 _(comment, "usage: comment <ignore-rest-of-line>")              \
19420 _(dump_interface_table, "usage: dump_interface_table")          \
19421 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
19422 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
19423 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
19424 _(dump_stats_table, "usage: dump_stats_table")                  \
19425 _(dump_macro_table, "usage: dump_macro_table ")                 \
19426 _(dump_node_table, "usage: dump_node_table")                    \
19427 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
19428 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
19429 _(echo, "usage: echo <message>")                                \
19430 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
19431 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
19432 _(help, "usage: help")                                          \
19433 _(q, "usage: quit")                                             \
19434 _(quit, "usage: quit")                                          \
19435 _(search_node_table, "usage: search_node_table <name>...")      \
19436 _(set, "usage: set <variable-name> <value>")                    \
19437 _(script, "usage: script <file-name>")                          \
19438 _(unset, "usage: unset <variable-name>")
19439
19440 #define _(N,n)                                  \
19441     static void vl_api_##n##_t_handler_uni      \
19442     (vl_api_##n##_t * mp)                       \
19443     {                                           \
19444         vat_main_t * vam = &vat_main;           \
19445         if (vam->json_output) {                 \
19446             vl_api_##n##_t_handler_json(mp);    \
19447         } else {                                \
19448             vl_api_##n##_t_handler(mp);         \
19449         }                                       \
19450     }
19451 foreach_vpe_api_reply_msg;
19452 #if VPP_API_TEST_BUILTIN == 0
19453 foreach_standalone_reply_msg;
19454 #endif
19455 #undef _
19456
19457 void
19458 vat_api_hookup (vat_main_t * vam)
19459 {
19460 #define _(N,n)                                                  \
19461     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
19462                            vl_api_##n##_t_handler_uni,          \
19463                            vl_noop_handler,                     \
19464                            vl_api_##n##_t_endian,               \
19465                            vl_api_##n##_t_print,                \
19466                            sizeof(vl_api_##n##_t), 1);
19467   foreach_vpe_api_reply_msg;
19468 #if VPP_API_TEST_BUILTIN == 0
19469   foreach_standalone_reply_msg;
19470 #endif
19471 #undef _
19472
19473 #if (VPP_API_TEST_BUILTIN==0)
19474   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
19475
19476   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
19477
19478   vam->function_by_name = hash_create_string (0, sizeof (uword));
19479
19480   vam->help_by_name = hash_create_string (0, sizeof (uword));
19481 #endif
19482
19483   /* API messages we can send */
19484 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
19485   foreach_vpe_api_msg;
19486 #undef _
19487
19488   /* Help strings */
19489 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
19490   foreach_vpe_api_msg;
19491 #undef _
19492
19493   /* CLI functions */
19494 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
19495   foreach_cli_function;
19496 #undef _
19497
19498   /* Help strings */
19499 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
19500   foreach_cli_function;
19501 #undef _
19502 }
19503
19504 #if VPP_API_TEST_BUILTIN
19505 static clib_error_t *
19506 vat_api_hookup_shim (vlib_main_t * vm)
19507 {
19508   vat_api_hookup (&vat_main);
19509   return 0;
19510 }
19511
19512 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
19513 #endif
19514
19515 /*
19516  * fd.io coding-style-patch-verification: ON
19517  *
19518  * Local Variables:
19519  * eval: (c-set-style "gnu")
19520  * End:
19521  */