LISP: make statistics thread safe
[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 #define VHOST_USER_POLLING_MODE   0
407 #define VHOST_USER_INTERRUPT_MODE 1
408 #define VHOST_USER_ADAPTIVE_MODE  2
409
410 static u8 *
411 api_format_vhost_user_operation_mode (u8 * s, va_list * va)
412 {
413   int operation_mode = va_arg (*va, int);
414
415   switch (operation_mode)
416     {
417     case VHOST_USER_POLLING_MODE:
418       s = format (s, "%-9s", "polling");
419       break;
420     case VHOST_USER_INTERRUPT_MODE:
421       s = format (s, "%-9s", "interrupt");
422       break;
423     default:
424       s = format (s, "%-9s", "invalid");
425     }
426   return s;
427 }
428
429 static uword
430 api_unformat_vhost_user_operation_mode (unformat_input_t * input,
431                                         va_list * args)
432 {
433   u8 *operation_mode = va_arg (*args, u8 *);
434   uword rc = 1;
435
436   if (unformat (input, "interrupt"))
437     *operation_mode = VHOST_USER_INTERRUPT_MODE;
438   else if (unformat (input, "polling"))
439     *operation_mode = VHOST_USER_POLLING_MODE;
440   else
441     rc = 0;
442
443   return rc;
444 }
445
446 static uword
447 unformat_policer_rate_type (unformat_input_t * input, va_list * args)
448 {
449   u8 *r = va_arg (*args, u8 *);
450
451   if (unformat (input, "kbps"))
452     *r = SSE2_QOS_RATE_KBPS;
453   else if (unformat (input, "pps"))
454     *r = SSE2_QOS_RATE_PPS;
455   else
456     return 0;
457   return 1;
458 }
459
460 static uword
461 unformat_policer_round_type (unformat_input_t * input, va_list * args)
462 {
463   u8 *r = va_arg (*args, u8 *);
464
465   if (unformat (input, "closest"))
466     *r = SSE2_QOS_ROUND_TO_CLOSEST;
467   else if (unformat (input, "up"))
468     *r = SSE2_QOS_ROUND_TO_UP;
469   else if (unformat (input, "down"))
470     *r = SSE2_QOS_ROUND_TO_DOWN;
471   else
472     return 0;
473   return 1;
474 }
475
476 static uword
477 unformat_policer_type (unformat_input_t * input, va_list * args)
478 {
479   u8 *r = va_arg (*args, u8 *);
480
481   if (unformat (input, "1r2c"))
482     *r = SSE2_QOS_POLICER_TYPE_1R2C;
483   else if (unformat (input, "1r3c"))
484     *r = SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697;
485   else if (unformat (input, "2r3c-2698"))
486     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698;
487   else if (unformat (input, "2r3c-4115"))
488     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115;
489   else if (unformat (input, "2r3c-mef5cf1"))
490     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
491   else
492     return 0;
493   return 1;
494 }
495
496 static uword
497 unformat_dscp (unformat_input_t * input, va_list * va)
498 {
499   u8 *r = va_arg (*va, u8 *);
500
501   if (0);
502 #define _(v,f,str) else if (unformat (input, str)) *r = VNET_DSCP_##f;
503   foreach_vnet_dscp
504 #undef _
505     else
506     return 0;
507   return 1;
508 }
509
510 static uword
511 unformat_policer_action_type (unformat_input_t * input, va_list * va)
512 {
513   sse2_qos_pol_action_params_st *a
514     = va_arg (*va, sse2_qos_pol_action_params_st *);
515
516   if (unformat (input, "drop"))
517     a->action_type = SSE2_QOS_ACTION_DROP;
518   else if (unformat (input, "transmit"))
519     a->action_type = SSE2_QOS_ACTION_TRANSMIT;
520   else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp))
521     a->action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
522   else
523     return 0;
524   return 1;
525 }
526
527 static uword
528 unformat_policer_classify_table_type (unformat_input_t * input, va_list * va)
529 {
530   u32 *r = va_arg (*va, u32 *);
531   u32 tid;
532
533   if (unformat (input, "ip4"))
534     tid = POLICER_CLASSIFY_TABLE_IP4;
535   else if (unformat (input, "ip6"))
536     tid = POLICER_CLASSIFY_TABLE_IP6;
537   else if (unformat (input, "l2"))
538     tid = POLICER_CLASSIFY_TABLE_L2;
539   else
540     return 0;
541
542   *r = tid;
543   return 1;
544 }
545
546 static uword
547 unformat_flow_classify_table_type (unformat_input_t * input, va_list * va)
548 {
549   u32 *r = va_arg (*va, u32 *);
550   u32 tid;
551
552   if (unformat (input, "ip4"))
553     tid = FLOW_CLASSIFY_TABLE_IP4;
554   else if (unformat (input, "ip6"))
555     tid = FLOW_CLASSIFY_TABLE_IP6;
556   else
557     return 0;
558
559   *r = tid;
560   return 1;
561 }
562
563 static const char *mfib_flag_names[] = MFIB_ENTRY_NAMES_SHORT;
564 static const char *mfib_flag_long_names[] = MFIB_ENTRY_NAMES_LONG;
565 static const char *mfib_itf_flag_long_names[] = MFIB_ITF_NAMES_LONG;
566 static const char *mfib_itf_flag_names[] = MFIB_ITF_NAMES_SHORT;
567
568 #if (VPP_API_TEST_BUILTIN==0)
569 uword
570 unformat_mfib_itf_flags (unformat_input_t * input, va_list * args)
571 {
572   mfib_itf_flags_t old, *iflags = va_arg (*args, mfib_itf_flags_t *);
573   mfib_itf_attribute_t attr;
574
575   old = *iflags;
576   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
577   {
578     if (unformat (input, mfib_itf_flag_long_names[attr]))
579       *iflags |= (1 << attr);
580   }
581   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
582   {
583     if (unformat (input, mfib_itf_flag_names[attr]))
584       *iflags |= (1 << attr);
585   }
586
587   return (old == *iflags ? 0 : 1);
588 }
589
590 uword
591 unformat_mfib_entry_flags (unformat_input_t * input, va_list * args)
592 {
593   mfib_entry_flags_t old, *eflags = va_arg (*args, mfib_entry_flags_t *);
594   mfib_entry_attribute_t attr;
595
596   old = *eflags;
597   FOR_EACH_MFIB_ATTRIBUTE (attr)
598   {
599     if (unformat (input, mfib_flag_long_names[attr]))
600       *eflags |= (1 << attr);
601   }
602   FOR_EACH_MFIB_ATTRIBUTE (attr)
603   {
604     if (unformat (input, mfib_flag_names[attr]))
605       *eflags |= (1 << attr);
606   }
607
608   return (old == *eflags ? 0 : 1);
609 }
610
611 u8 *
612 format_ip4_address (u8 * s, va_list * args)
613 {
614   u8 *a = va_arg (*args, u8 *);
615   return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
616 }
617
618 u8 *
619 format_ip6_address (u8 * s, va_list * args)
620 {
621   ip6_address_t *a = va_arg (*args, ip6_address_t *);
622   u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
623
624   i_max_n_zero = ARRAY_LEN (a->as_u16);
625   max_n_zeros = 0;
626   i_first_zero = i_max_n_zero;
627   n_zeros = 0;
628   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
629     {
630       u32 is_zero = a->as_u16[i] == 0;
631       if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
632         {
633           i_first_zero = i;
634           n_zeros = 0;
635         }
636       n_zeros += is_zero;
637       if ((!is_zero && n_zeros > max_n_zeros)
638           || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
639         {
640           i_max_n_zero = i_first_zero;
641           max_n_zeros = n_zeros;
642           i_first_zero = ARRAY_LEN (a->as_u16);
643           n_zeros = 0;
644         }
645     }
646
647   last_double_colon = 0;
648   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
649     {
650       if (i == i_max_n_zero && max_n_zeros > 1)
651         {
652           s = format (s, "::");
653           i += max_n_zeros - 1;
654           last_double_colon = 1;
655         }
656       else
657         {
658           s = format (s, "%s%x",
659                       (last_double_colon || i == 0) ? "" : ":",
660                       clib_net_to_host_u16 (a->as_u16[i]));
661           last_double_colon = 0;
662         }
663     }
664
665   return s;
666 }
667
668 /* Format an IP46 address. */
669 u8 *
670 format_ip46_address (u8 * s, va_list * args)
671 {
672   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
673   ip46_type_t type = va_arg (*args, ip46_type_t);
674   int is_ip4 = 1;
675
676   switch (type)
677     {
678     case IP46_TYPE_ANY:
679       is_ip4 = ip46_address_is_ip4 (ip46);
680       break;
681     case IP46_TYPE_IP4:
682       is_ip4 = 1;
683       break;
684     case IP46_TYPE_IP6:
685       is_ip4 = 0;
686       break;
687     }
688
689   return is_ip4 ?
690     format (s, "%U", format_ip4_address, &ip46->ip4) :
691     format (s, "%U", format_ip6_address, &ip46->ip6);
692 }
693
694 u8 *
695 format_ethernet_address (u8 * s, va_list * args)
696 {
697   u8 *a = va_arg (*args, u8 *);
698
699   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
700                  a[0], a[1], a[2], a[3], a[4], a[5]);
701 }
702 #endif
703
704 static void
705 increment_v4_address (ip4_address_t * a)
706 {
707   u32 v;
708
709   v = ntohl (a->as_u32) + 1;
710   a->as_u32 = ntohl (v);
711 }
712
713 static void
714 increment_v6_address (ip6_address_t * a)
715 {
716   u64 v0, v1;
717
718   v0 = clib_net_to_host_u64 (a->as_u64[0]);
719   v1 = clib_net_to_host_u64 (a->as_u64[1]);
720
721   v1 += 1;
722   if (v1 == 0)
723     v0 += 1;
724   a->as_u64[0] = clib_net_to_host_u64 (v0);
725   a->as_u64[1] = clib_net_to_host_u64 (v1);
726 }
727
728 static void
729 increment_mac_address (u64 * mac)
730 {
731   u64 tmp = *mac;
732
733   tmp = clib_net_to_host_u64 (tmp);
734   tmp += 1 << 16;               /* skip unused (least significant) octets */
735   tmp = clib_host_to_net_u64 (tmp);
736   *mac = tmp;
737 }
738
739 static void vl_api_create_loopback_reply_t_handler
740   (vl_api_create_loopback_reply_t * mp)
741 {
742   vat_main_t *vam = &vat_main;
743   i32 retval = ntohl (mp->retval);
744
745   vam->retval = retval;
746   vam->regenerate_interface_table = 1;
747   vam->sw_if_index = ntohl (mp->sw_if_index);
748   vam->result_ready = 1;
749 }
750
751 static void vl_api_create_loopback_reply_t_handler_json
752   (vl_api_create_loopback_reply_t * mp)
753 {
754   vat_main_t *vam = &vat_main;
755   vat_json_node_t node;
756
757   vat_json_init_object (&node);
758   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
759   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
760
761   vat_json_print (vam->ofp, &node);
762   vat_json_free (&node);
763   vam->retval = ntohl (mp->retval);
764   vam->result_ready = 1;
765 }
766
767 static void vl_api_create_loopback_instance_reply_t_handler
768   (vl_api_create_loopback_instance_reply_t * mp)
769 {
770   vat_main_t *vam = &vat_main;
771   i32 retval = ntohl (mp->retval);
772
773   vam->retval = retval;
774   vam->regenerate_interface_table = 1;
775   vam->sw_if_index = ntohl (mp->sw_if_index);
776   vam->result_ready = 1;
777 }
778
779 static void vl_api_create_loopback_instance_reply_t_handler_json
780   (vl_api_create_loopback_instance_reply_t * mp)
781 {
782   vat_main_t *vam = &vat_main;
783   vat_json_node_t node;
784
785   vat_json_init_object (&node);
786   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
787   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
788
789   vat_json_print (vam->ofp, &node);
790   vat_json_free (&node);
791   vam->retval = ntohl (mp->retval);
792   vam->result_ready = 1;
793 }
794
795 static void vl_api_af_packet_create_reply_t_handler
796   (vl_api_af_packet_create_reply_t * mp)
797 {
798   vat_main_t *vam = &vat_main;
799   i32 retval = ntohl (mp->retval);
800
801   vam->retval = retval;
802   vam->regenerate_interface_table = 1;
803   vam->sw_if_index = ntohl (mp->sw_if_index);
804   vam->result_ready = 1;
805 }
806
807 static void vl_api_af_packet_create_reply_t_handler_json
808   (vl_api_af_packet_create_reply_t * mp)
809 {
810   vat_main_t *vam = &vat_main;
811   vat_json_node_t node;
812
813   vat_json_init_object (&node);
814   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
815   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
816
817   vat_json_print (vam->ofp, &node);
818   vat_json_free (&node);
819
820   vam->retval = ntohl (mp->retval);
821   vam->result_ready = 1;
822 }
823
824 static void vl_api_create_vlan_subif_reply_t_handler
825   (vl_api_create_vlan_subif_reply_t * mp)
826 {
827   vat_main_t *vam = &vat_main;
828   i32 retval = ntohl (mp->retval);
829
830   vam->retval = retval;
831   vam->regenerate_interface_table = 1;
832   vam->sw_if_index = ntohl (mp->sw_if_index);
833   vam->result_ready = 1;
834 }
835
836 static void vl_api_create_vlan_subif_reply_t_handler_json
837   (vl_api_create_vlan_subif_reply_t * mp)
838 {
839   vat_main_t *vam = &vat_main;
840   vat_json_node_t node;
841
842   vat_json_init_object (&node);
843   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
844   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
845
846   vat_json_print (vam->ofp, &node);
847   vat_json_free (&node);
848
849   vam->retval = ntohl (mp->retval);
850   vam->result_ready = 1;
851 }
852
853 static void vl_api_create_subif_reply_t_handler
854   (vl_api_create_subif_reply_t * mp)
855 {
856   vat_main_t *vam = &vat_main;
857   i32 retval = ntohl (mp->retval);
858
859   vam->retval = retval;
860   vam->regenerate_interface_table = 1;
861   vam->sw_if_index = ntohl (mp->sw_if_index);
862   vam->result_ready = 1;
863 }
864
865 static void vl_api_create_subif_reply_t_handler_json
866   (vl_api_create_subif_reply_t * mp)
867 {
868   vat_main_t *vam = &vat_main;
869   vat_json_node_t node;
870
871   vat_json_init_object (&node);
872   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
873   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
874
875   vat_json_print (vam->ofp, &node);
876   vat_json_free (&node);
877
878   vam->retval = ntohl (mp->retval);
879   vam->result_ready = 1;
880 }
881
882 static void vl_api_interface_name_renumber_reply_t_handler
883   (vl_api_interface_name_renumber_reply_t * mp)
884 {
885   vat_main_t *vam = &vat_main;
886   i32 retval = ntohl (mp->retval);
887
888   vam->retval = retval;
889   vam->regenerate_interface_table = 1;
890   vam->result_ready = 1;
891 }
892
893 static void vl_api_interface_name_renumber_reply_t_handler_json
894   (vl_api_interface_name_renumber_reply_t * mp)
895 {
896   vat_main_t *vam = &vat_main;
897   vat_json_node_t node;
898
899   vat_json_init_object (&node);
900   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
901
902   vat_json_print (vam->ofp, &node);
903   vat_json_free (&node);
904
905   vam->retval = ntohl (mp->retval);
906   vam->result_ready = 1;
907 }
908
909 /*
910  * Special-case: build the interface table, maintain
911  * the next loopback sw_if_index vbl.
912  */
913 static void vl_api_sw_interface_details_t_handler
914   (vl_api_sw_interface_details_t * mp)
915 {
916   vat_main_t *vam = &vat_main;
917   u8 *s = format (0, "%s%c", mp->interface_name, 0);
918
919   hash_set_mem (vam->sw_if_index_by_interface_name, s,
920                 ntohl (mp->sw_if_index));
921
922   /* In sub interface case, fill the sub interface table entry */
923   if (mp->sw_if_index != mp->sup_sw_if_index)
924     {
925       sw_interface_subif_t *sub = NULL;
926
927       vec_add2 (vam->sw_if_subif_table, sub, 1);
928
929       vec_validate (sub->interface_name, strlen ((char *) s) + 1);
930       strncpy ((char *) sub->interface_name, (char *) s,
931                vec_len (sub->interface_name));
932       sub->sw_if_index = ntohl (mp->sw_if_index);
933       sub->sub_id = ntohl (mp->sub_id);
934
935       sub->sub_dot1ad = mp->sub_dot1ad;
936       sub->sub_number_of_tags = mp->sub_number_of_tags;
937       sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
938       sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
939       sub->sub_exact_match = mp->sub_exact_match;
940       sub->sub_default = mp->sub_default;
941       sub->sub_outer_vlan_id_any = mp->sub_outer_vlan_id_any;
942       sub->sub_inner_vlan_id_any = mp->sub_inner_vlan_id_any;
943
944       /* vlan tag rewrite */
945       sub->vtr_op = ntohl (mp->vtr_op);
946       sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
947       sub->vtr_tag1 = ntohl (mp->vtr_tag1);
948       sub->vtr_tag2 = ntohl (mp->vtr_tag2);
949     }
950 }
951
952 static void vl_api_sw_interface_details_t_handler_json
953   (vl_api_sw_interface_details_t * mp)
954 {
955   vat_main_t *vam = &vat_main;
956   vat_json_node_t *node = NULL;
957
958   if (VAT_JSON_ARRAY != vam->json_tree.type)
959     {
960       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
961       vat_json_init_array (&vam->json_tree);
962     }
963   node = vat_json_array_add (&vam->json_tree);
964
965   vat_json_init_object (node);
966   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
967   vat_json_object_add_uint (node, "sup_sw_if_index",
968                             ntohl (mp->sup_sw_if_index));
969   vat_json_object_add_uint (node, "l2_address_length",
970                             ntohl (mp->l2_address_length));
971   vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
972                              sizeof (mp->l2_address));
973   vat_json_object_add_string_copy (node, "interface_name",
974                                    mp->interface_name);
975   vat_json_object_add_uint (node, "admin_up_down", mp->admin_up_down);
976   vat_json_object_add_uint (node, "link_up_down", mp->link_up_down);
977   vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
978   vat_json_object_add_uint (node, "link_speed", mp->link_speed);
979   vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
980   vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
981   vat_json_object_add_uint (node, "sub_dot1ad", mp->sub_dot1ad);
982   vat_json_object_add_uint (node, "sub_number_of_tags",
983                             mp->sub_number_of_tags);
984   vat_json_object_add_uint (node, "sub_outer_vlan_id",
985                             ntohs (mp->sub_outer_vlan_id));
986   vat_json_object_add_uint (node, "sub_inner_vlan_id",
987                             ntohs (mp->sub_inner_vlan_id));
988   vat_json_object_add_uint (node, "sub_exact_match", mp->sub_exact_match);
989   vat_json_object_add_uint (node, "sub_default", mp->sub_default);
990   vat_json_object_add_uint (node, "sub_outer_vlan_id_any",
991                             mp->sub_outer_vlan_id_any);
992   vat_json_object_add_uint (node, "sub_inner_vlan_id_any",
993                             mp->sub_inner_vlan_id_any);
994   vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
995   vat_json_object_add_uint (node, "vtr_push_dot1q",
996                             ntohl (mp->vtr_push_dot1q));
997   vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
998   vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
999   if (mp->sub_dot1ah)
1000     {
1001       vat_json_object_add_string_copy (node, "pbb_vtr_dmac",
1002                                        format (0, "%U",
1003                                                format_ethernet_address,
1004                                                &mp->b_dmac));
1005       vat_json_object_add_string_copy (node, "pbb_vtr_smac",
1006                                        format (0, "%U",
1007                                                format_ethernet_address,
1008                                                &mp->b_smac));
1009       vat_json_object_add_uint (node, "pbb_vtr_b_vlanid", mp->b_vlanid);
1010       vat_json_object_add_uint (node, "pbb_vtr_i_sid", mp->i_sid);
1011     }
1012 }
1013
1014 #if VPP_API_TEST_BUILTIN == 0
1015 static void vl_api_sw_interface_set_flags_t_handler
1016   (vl_api_sw_interface_set_flags_t * mp)
1017 {
1018   vat_main_t *vam = &vat_main;
1019   if (vam->interface_event_display)
1020     errmsg ("interface flags: sw_if_index %d %s %s",
1021             ntohl (mp->sw_if_index),
1022             mp->admin_up_down ? "admin-up" : "admin-down",
1023             mp->link_up_down ? "link-up" : "link-down");
1024 }
1025 #endif
1026
1027 static void vl_api_sw_interface_set_flags_t_handler_json
1028   (vl_api_sw_interface_set_flags_t * mp)
1029 {
1030   /* JSON output not supported */
1031 }
1032
1033 static void
1034 vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
1035 {
1036   vat_main_t *vam = &vat_main;
1037   i32 retval = ntohl (mp->retval);
1038
1039   vam->retval = retval;
1040   vam->shmem_result = (u8 *) mp->reply_in_shmem;
1041   vam->result_ready = 1;
1042 }
1043
1044 static void
1045 vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
1046 {
1047   vat_main_t *vam = &vat_main;
1048   vat_json_node_t node;
1049   api_main_t *am = &api_main;
1050   void *oldheap;
1051   u8 *reply;
1052
1053   vat_json_init_object (&node);
1054   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1055   vat_json_object_add_uint (&node, "reply_in_shmem",
1056                             ntohl (mp->reply_in_shmem));
1057   /* Toss the shared-memory original... */
1058   pthread_mutex_lock (&am->vlib_rp->mutex);
1059   oldheap = svm_push_data_heap (am->vlib_rp);
1060
1061   reply = (u8 *) (mp->reply_in_shmem);
1062   vec_free (reply);
1063
1064   svm_pop_heap (oldheap);
1065   pthread_mutex_unlock (&am->vlib_rp->mutex);
1066
1067   vat_json_print (vam->ofp, &node);
1068   vat_json_free (&node);
1069
1070   vam->retval = ntohl (mp->retval);
1071   vam->result_ready = 1;
1072 }
1073
1074 static void
1075 vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
1076 {
1077   vat_main_t *vam = &vat_main;
1078   i32 retval = ntohl (mp->retval);
1079
1080   vam->retval = retval;
1081   vam->cmd_reply = mp->reply;
1082   vam->result_ready = 1;
1083 }
1084
1085 static void
1086 vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
1087 {
1088   vat_main_t *vam = &vat_main;
1089   vat_json_node_t node;
1090
1091   vat_json_init_object (&node);
1092   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1093   vat_json_object_add_string_copy (&node, "reply", mp->reply);
1094
1095   vat_json_print (vam->ofp, &node);
1096   vat_json_free (&node);
1097
1098   vam->retval = ntohl (mp->retval);
1099   vam->result_ready = 1;
1100 }
1101
1102 static void vl_api_classify_add_del_table_reply_t_handler
1103   (vl_api_classify_add_del_table_reply_t * mp)
1104 {
1105   vat_main_t *vam = &vat_main;
1106   i32 retval = ntohl (mp->retval);
1107   if (vam->async_mode)
1108     {
1109       vam->async_errors += (retval < 0);
1110     }
1111   else
1112     {
1113       vam->retval = retval;
1114       if (retval == 0 &&
1115           ((mp->new_table_index != 0xFFFFFFFF) ||
1116            (mp->skip_n_vectors != 0xFFFFFFFF) ||
1117            (mp->match_n_vectors != 0xFFFFFFFF)))
1118         /*
1119          * Note: this is just barely thread-safe, depends on
1120          * the main thread spinning waiting for an answer...
1121          */
1122         errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d",
1123                 ntohl (mp->new_table_index),
1124                 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
1125       vam->result_ready = 1;
1126     }
1127 }
1128
1129 static void vl_api_classify_add_del_table_reply_t_handler_json
1130   (vl_api_classify_add_del_table_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, "new_table_index",
1138                             ntohl (mp->new_table_index));
1139   vat_json_object_add_uint (&node, "skip_n_vectors",
1140                             ntohl (mp->skip_n_vectors));
1141   vat_json_object_add_uint (&node, "match_n_vectors",
1142                             ntohl (mp->match_n_vectors));
1143
1144   vat_json_print (vam->ofp, &node);
1145   vat_json_free (&node);
1146
1147   vam->retval = ntohl (mp->retval);
1148   vam->result_ready = 1;
1149 }
1150
1151 static void vl_api_get_node_index_reply_t_handler
1152   (vl_api_get_node_index_reply_t * mp)
1153 {
1154   vat_main_t *vam = &vat_main;
1155   i32 retval = ntohl (mp->retval);
1156   if (vam->async_mode)
1157     {
1158       vam->async_errors += (retval < 0);
1159     }
1160   else
1161     {
1162       vam->retval = retval;
1163       if (retval == 0)
1164         errmsg ("node index %d", ntohl (mp->node_index));
1165       vam->result_ready = 1;
1166     }
1167 }
1168
1169 static void vl_api_get_node_index_reply_t_handler_json
1170   (vl_api_get_node_index_reply_t * mp)
1171 {
1172   vat_main_t *vam = &vat_main;
1173   vat_json_node_t node;
1174
1175   vat_json_init_object (&node);
1176   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1177   vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
1178
1179   vat_json_print (vam->ofp, &node);
1180   vat_json_free (&node);
1181
1182   vam->retval = ntohl (mp->retval);
1183   vam->result_ready = 1;
1184 }
1185
1186 static void vl_api_get_next_index_reply_t_handler
1187   (vl_api_get_next_index_reply_t * mp)
1188 {
1189   vat_main_t *vam = &vat_main;
1190   i32 retval = ntohl (mp->retval);
1191   if (vam->async_mode)
1192     {
1193       vam->async_errors += (retval < 0);
1194     }
1195   else
1196     {
1197       vam->retval = retval;
1198       if (retval == 0)
1199         errmsg ("next node index %d", ntohl (mp->next_index));
1200       vam->result_ready = 1;
1201     }
1202 }
1203
1204 static void vl_api_get_next_index_reply_t_handler_json
1205   (vl_api_get_next_index_reply_t * mp)
1206 {
1207   vat_main_t *vam = &vat_main;
1208   vat_json_node_t node;
1209
1210   vat_json_init_object (&node);
1211   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1212   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1213
1214   vat_json_print (vam->ofp, &node);
1215   vat_json_free (&node);
1216
1217   vam->retval = ntohl (mp->retval);
1218   vam->result_ready = 1;
1219 }
1220
1221 static void vl_api_add_node_next_reply_t_handler
1222   (vl_api_add_node_next_reply_t * mp)
1223 {
1224   vat_main_t *vam = &vat_main;
1225   i32 retval = ntohl (mp->retval);
1226   if (vam->async_mode)
1227     {
1228       vam->async_errors += (retval < 0);
1229     }
1230   else
1231     {
1232       vam->retval = retval;
1233       if (retval == 0)
1234         errmsg ("next index %d", ntohl (mp->next_index));
1235       vam->result_ready = 1;
1236     }
1237 }
1238
1239 static void vl_api_add_node_next_reply_t_handler_json
1240   (vl_api_add_node_next_reply_t * mp)
1241 {
1242   vat_main_t *vam = &vat_main;
1243   vat_json_node_t node;
1244
1245   vat_json_init_object (&node);
1246   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1247   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1248
1249   vat_json_print (vam->ofp, &node);
1250   vat_json_free (&node);
1251
1252   vam->retval = ntohl (mp->retval);
1253   vam->result_ready = 1;
1254 }
1255
1256 static void vl_api_show_version_reply_t_handler
1257   (vl_api_show_version_reply_t * mp)
1258 {
1259   vat_main_t *vam = &vat_main;
1260   i32 retval = ntohl (mp->retval);
1261
1262   if (retval >= 0)
1263     {
1264       errmsg ("        program: %s", mp->program);
1265       errmsg ("        version: %s", mp->version);
1266       errmsg ("     build date: %s", mp->build_date);
1267       errmsg ("build directory: %s", mp->build_directory);
1268     }
1269   vam->retval = retval;
1270   vam->result_ready = 1;
1271 }
1272
1273 static void vl_api_show_version_reply_t_handler_json
1274   (vl_api_show_version_reply_t * mp)
1275 {
1276   vat_main_t *vam = &vat_main;
1277   vat_json_node_t node;
1278
1279   vat_json_init_object (&node);
1280   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1281   vat_json_object_add_string_copy (&node, "program", mp->program);
1282   vat_json_object_add_string_copy (&node, "version", mp->version);
1283   vat_json_object_add_string_copy (&node, "build_date", mp->build_date);
1284   vat_json_object_add_string_copy (&node, "build_directory",
1285                                    mp->build_directory);
1286
1287   vat_json_print (vam->ofp, &node);
1288   vat_json_free (&node);
1289
1290   vam->retval = ntohl (mp->retval);
1291   vam->result_ready = 1;
1292 }
1293
1294 static void
1295 vl_api_ip4_arp_event_t_handler (vl_api_ip4_arp_event_t * mp)
1296 {
1297   u32 sw_if_index = ntohl (mp->sw_if_index);
1298   errmsg ("arp %s event: pid %d address %U new mac %U sw_if_index %d\n",
1299           mp->mac_ip ? "mac/ip binding" : "address resolution",
1300           ntohl (mp->pid), format_ip4_address, &mp->address,
1301           format_ethernet_address, mp->new_mac, sw_if_index);
1302 }
1303
1304 static void
1305 vl_api_ip4_arp_event_t_handler_json (vl_api_ip4_arp_event_t * mp)
1306 {
1307   /* JSON output not supported */
1308 }
1309
1310 static void
1311 vl_api_ip6_nd_event_t_handler (vl_api_ip6_nd_event_t * mp)
1312 {
1313   u32 sw_if_index = ntohl (mp->sw_if_index);
1314   errmsg ("ip6 nd %s event: pid %d address %U new mac %U sw_if_index %d\n",
1315           mp->mac_ip ? "mac/ip binding" : "address resolution",
1316           ntohl (mp->pid), format_ip6_address, mp->address,
1317           format_ethernet_address, mp->new_mac, sw_if_index);
1318 }
1319
1320 static void
1321 vl_api_ip6_nd_event_t_handler_json (vl_api_ip6_nd_event_t * mp)
1322 {
1323   /* JSON output not supported */
1324 }
1325
1326 /*
1327  * Special-case: build the bridge domain table, maintain
1328  * the next bd id vbl.
1329  */
1330 static void vl_api_bridge_domain_details_t_handler
1331   (vl_api_bridge_domain_details_t * mp)
1332 {
1333   vat_main_t *vam = &vat_main;
1334   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1335
1336   print (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-3s",
1337          " ID", "LRN", "FWD", "FLD", "BVI", "#IF");
1338
1339   print (vam->ofp, "%3d %3d %3d %3d %3d %3d",
1340          ntohl (mp->bd_id), mp->learn, mp->forward,
1341          mp->flood, ntohl (mp->bvi_sw_if_index), n_sw_ifs);
1342
1343   if (n_sw_ifs)
1344     print (vam->ofp, "\n\n%s %s  %s", "sw_if_index", "SHG", "Interface Name");
1345 }
1346
1347 static void vl_api_bridge_domain_details_t_handler_json
1348   (vl_api_bridge_domain_details_t * mp)
1349 {
1350   vat_main_t *vam = &vat_main;
1351   vat_json_node_t *node, *array = NULL;
1352
1353   if (VAT_JSON_ARRAY != vam->json_tree.type)
1354     {
1355       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1356       vat_json_init_array (&vam->json_tree);
1357     }
1358   node = vat_json_array_add (&vam->json_tree);
1359
1360   vat_json_init_object (node);
1361   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1362   vat_json_object_add_uint (node, "flood", mp->flood);
1363   vat_json_object_add_uint (node, "forward", mp->forward);
1364   vat_json_object_add_uint (node, "learn", mp->learn);
1365   vat_json_object_add_uint (node, "bvi_sw_if_index",
1366                             ntohl (mp->bvi_sw_if_index));
1367   vat_json_object_add_uint (node, "n_sw_ifs", ntohl (mp->n_sw_ifs));
1368   array = vat_json_object_add (node, "sw_if");
1369   vat_json_init_array (array);
1370 }
1371
1372 /*
1373  * Special-case: build the bridge domain sw if table.
1374  */
1375 static void vl_api_bridge_domain_sw_if_details_t_handler
1376   (vl_api_bridge_domain_sw_if_details_t * mp)
1377 {
1378   vat_main_t *vam = &vat_main;
1379   hash_pair_t *p;
1380   u8 *sw_if_name = 0;
1381   u32 sw_if_index;
1382
1383   sw_if_index = ntohl (mp->sw_if_index);
1384   /* *INDENT-OFF* */
1385   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1386   ({
1387     if ((u32) p->value[0] == sw_if_index)
1388       {
1389         sw_if_name = (u8 *)(p->key);
1390         break;
1391       }
1392   }));
1393   /* *INDENT-ON* */
1394
1395   print (vam->ofp, "%7d     %3d  %s", sw_if_index,
1396          mp->shg, sw_if_name ? (char *) sw_if_name :
1397          "sw_if_index not found!");
1398 }
1399
1400 static void vl_api_bridge_domain_sw_if_details_t_handler_json
1401   (vl_api_bridge_domain_sw_if_details_t * mp)
1402 {
1403   vat_main_t *vam = &vat_main;
1404   vat_json_node_t *node = NULL;
1405   uword last_index = 0;
1406
1407   ASSERT (VAT_JSON_ARRAY == vam->json_tree.type);
1408   ASSERT (vec_len (vam->json_tree.array) >= 1);
1409   last_index = vec_len (vam->json_tree.array) - 1;
1410   node = &vam->json_tree.array[last_index];
1411   node = vat_json_object_get_element (node, "sw_if");
1412   ASSERT (NULL != node);
1413   node = vat_json_array_add (node);
1414
1415   vat_json_init_object (node);
1416   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1417   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
1418   vat_json_object_add_uint (node, "shg", mp->shg);
1419 }
1420
1421 static void vl_api_control_ping_reply_t_handler
1422   (vl_api_control_ping_reply_t * mp)
1423 {
1424   vat_main_t *vam = &vat_main;
1425   i32 retval = ntohl (mp->retval);
1426   if (vam->async_mode)
1427     {
1428       vam->async_errors += (retval < 0);
1429     }
1430   else
1431     {
1432       vam->retval = retval;
1433       vam->result_ready = 1;
1434     }
1435 }
1436
1437 static void vl_api_control_ping_reply_t_handler_json
1438   (vl_api_control_ping_reply_t * mp)
1439 {
1440   vat_main_t *vam = &vat_main;
1441   i32 retval = ntohl (mp->retval);
1442
1443   if (VAT_JSON_NONE != vam->json_tree.type)
1444     {
1445       vat_json_print (vam->ofp, &vam->json_tree);
1446       vat_json_free (&vam->json_tree);
1447       vam->json_tree.type = VAT_JSON_NONE;
1448     }
1449   else
1450     {
1451       /* just print [] */
1452       vat_json_init_array (&vam->json_tree);
1453       vat_json_print (vam->ofp, &vam->json_tree);
1454       vam->json_tree.type = VAT_JSON_NONE;
1455     }
1456
1457   vam->retval = retval;
1458   vam->result_ready = 1;
1459 }
1460
1461 static void
1462   vl_api_bridge_domain_set_mac_age_reply_t_handler
1463   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1464 {
1465   vat_main_t *vam = &vat_main;
1466   i32 retval = ntohl (mp->retval);
1467   if (vam->async_mode)
1468     {
1469       vam->async_errors += (retval < 0);
1470     }
1471   else
1472     {
1473       vam->retval = retval;
1474       vam->result_ready = 1;
1475     }
1476 }
1477
1478 static void vl_api_bridge_domain_set_mac_age_reply_t_handler_json
1479   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1480 {
1481   vat_main_t *vam = &vat_main;
1482   vat_json_node_t node;
1483
1484   vat_json_init_object (&node);
1485   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1486
1487   vat_json_print (vam->ofp, &node);
1488   vat_json_free (&node);
1489
1490   vam->retval = ntohl (mp->retval);
1491   vam->result_ready = 1;
1492 }
1493
1494 static void
1495 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1496 {
1497   vat_main_t *vam = &vat_main;
1498   i32 retval = ntohl (mp->retval);
1499   if (vam->async_mode)
1500     {
1501       vam->async_errors += (retval < 0);
1502     }
1503   else
1504     {
1505       vam->retval = retval;
1506       vam->result_ready = 1;
1507     }
1508 }
1509
1510 static void vl_api_l2_flags_reply_t_handler_json
1511   (vl_api_l2_flags_reply_t * mp)
1512 {
1513   vat_main_t *vam = &vat_main;
1514   vat_json_node_t node;
1515
1516   vat_json_init_object (&node);
1517   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1518   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1519                             ntohl (mp->resulting_feature_bitmap));
1520
1521   vat_json_print (vam->ofp, &node);
1522   vat_json_free (&node);
1523
1524   vam->retval = ntohl (mp->retval);
1525   vam->result_ready = 1;
1526 }
1527
1528 static void vl_api_bridge_flags_reply_t_handler
1529   (vl_api_bridge_flags_reply_t * mp)
1530 {
1531   vat_main_t *vam = &vat_main;
1532   i32 retval = ntohl (mp->retval);
1533   if (vam->async_mode)
1534     {
1535       vam->async_errors += (retval < 0);
1536     }
1537   else
1538     {
1539       vam->retval = retval;
1540       vam->result_ready = 1;
1541     }
1542 }
1543
1544 static void vl_api_bridge_flags_reply_t_handler_json
1545   (vl_api_bridge_flags_reply_t * mp)
1546 {
1547   vat_main_t *vam = &vat_main;
1548   vat_json_node_t node;
1549
1550   vat_json_init_object (&node);
1551   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1552   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1553                             ntohl (mp->resulting_feature_bitmap));
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 static void vl_api_tap_connect_reply_t_handler
1563   (vl_api_tap_connect_reply_t * mp)
1564 {
1565   vat_main_t *vam = &vat_main;
1566   i32 retval = ntohl (mp->retval);
1567   if (vam->async_mode)
1568     {
1569       vam->async_errors += (retval < 0);
1570     }
1571   else
1572     {
1573       vam->retval = retval;
1574       vam->sw_if_index = ntohl (mp->sw_if_index);
1575       vam->result_ready = 1;
1576     }
1577
1578 }
1579
1580 static void vl_api_tap_connect_reply_t_handler_json
1581   (vl_api_tap_connect_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
1598 static void
1599 vl_api_tap_modify_reply_t_handler (vl_api_tap_modify_reply_t * mp)
1600 {
1601   vat_main_t *vam = &vat_main;
1602   i32 retval = ntohl (mp->retval);
1603   if (vam->async_mode)
1604     {
1605       vam->async_errors += (retval < 0);
1606     }
1607   else
1608     {
1609       vam->retval = retval;
1610       vam->sw_if_index = ntohl (mp->sw_if_index);
1611       vam->result_ready = 1;
1612     }
1613 }
1614
1615 static void vl_api_tap_modify_reply_t_handler_json
1616   (vl_api_tap_modify_reply_t * mp)
1617 {
1618   vat_main_t *vam = &vat_main;
1619   vat_json_node_t node;
1620
1621   vat_json_init_object (&node);
1622   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1623   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1624
1625   vat_json_print (vam->ofp, &node);
1626   vat_json_free (&node);
1627
1628   vam->retval = ntohl (mp->retval);
1629   vam->result_ready = 1;
1630 }
1631
1632 static void
1633 vl_api_tap_delete_reply_t_handler (vl_api_tap_delete_reply_t * mp)
1634 {
1635   vat_main_t *vam = &vat_main;
1636   i32 retval = ntohl (mp->retval);
1637   if (vam->async_mode)
1638     {
1639       vam->async_errors += (retval < 0);
1640     }
1641   else
1642     {
1643       vam->retval = retval;
1644       vam->result_ready = 1;
1645     }
1646 }
1647
1648 static void vl_api_tap_delete_reply_t_handler_json
1649   (vl_api_tap_delete_reply_t * mp)
1650 {
1651   vat_main_t *vam = &vat_main;
1652   vat_json_node_t node;
1653
1654   vat_json_init_object (&node);
1655   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1656
1657   vat_json_print (vam->ofp, &node);
1658   vat_json_free (&node);
1659
1660   vam->retval = ntohl (mp->retval);
1661   vam->result_ready = 1;
1662 }
1663
1664 static void vl_api_mpls_tunnel_add_del_reply_t_handler
1665   (vl_api_mpls_tunnel_add_del_reply_t * mp)
1666 {
1667   vat_main_t *vam = &vat_main;
1668   i32 retval = ntohl (mp->retval);
1669   if (vam->async_mode)
1670     {
1671       vam->async_errors += (retval < 0);
1672     }
1673   else
1674     {
1675       vam->retval = retval;
1676       vam->result_ready = 1;
1677     }
1678 }
1679
1680 static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
1681   (vl_api_mpls_tunnel_add_del_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, "tunnel_sw_if_index",
1689                             ntohl (mp->sw_if_index));
1690
1691   vat_json_print (vam->ofp, &node);
1692   vat_json_free (&node);
1693
1694   vam->retval = ntohl (mp->retval);
1695   vam->result_ready = 1;
1696 }
1697
1698 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
1699   (vl_api_l2tpv3_create_tunnel_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->sw_if_index = ntohl (mp->sw_if_index);
1711       vam->result_ready = 1;
1712     }
1713 }
1714
1715 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
1716   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1717 {
1718   vat_main_t *vam = &vat_main;
1719   vat_json_node_t node;
1720
1721   vat_json_init_object (&node);
1722   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1723   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1724
1725   vat_json_print (vam->ofp, &node);
1726   vat_json_free (&node);
1727
1728   vam->retval = ntohl (mp->retval);
1729   vam->result_ready = 1;
1730 }
1731
1732
1733 static void vl_api_one_add_del_locator_set_reply_t_handler
1734   (vl_api_one_add_del_locator_set_reply_t * mp)
1735 {
1736   vat_main_t *vam = &vat_main;
1737   i32 retval = ntohl (mp->retval);
1738   if (vam->async_mode)
1739     {
1740       vam->async_errors += (retval < 0);
1741     }
1742   else
1743     {
1744       vam->retval = retval;
1745       vam->result_ready = 1;
1746     }
1747 }
1748
1749 static void vl_api_one_add_del_locator_set_reply_t_handler_json
1750   (vl_api_one_add_del_locator_set_reply_t * mp)
1751 {
1752   vat_main_t *vam = &vat_main;
1753   vat_json_node_t node;
1754
1755   vat_json_init_object (&node);
1756   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1757   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
1758
1759   vat_json_print (vam->ofp, &node);
1760   vat_json_free (&node);
1761
1762   vam->retval = ntohl (mp->retval);
1763   vam->result_ready = 1;
1764 }
1765
1766 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
1767   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1768 {
1769   vat_main_t *vam = &vat_main;
1770   i32 retval = ntohl (mp->retval);
1771   if (vam->async_mode)
1772     {
1773       vam->async_errors += (retval < 0);
1774     }
1775   else
1776     {
1777       vam->retval = retval;
1778       vam->sw_if_index = ntohl (mp->sw_if_index);
1779       vam->result_ready = 1;
1780     }
1781 }
1782
1783 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
1784   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1785 {
1786   vat_main_t *vam = &vat_main;
1787   vat_json_node_t node;
1788
1789   vat_json_init_object (&node);
1790   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1791   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1792
1793   vat_json_print (vam->ofp, &node);
1794   vat_json_free (&node);
1795
1796   vam->retval = ntohl (mp->retval);
1797   vam->result_ready = 1;
1798 }
1799
1800 static void vl_api_gre_add_del_tunnel_reply_t_handler
1801   (vl_api_gre_add_del_tunnel_reply_t * mp)
1802 {
1803   vat_main_t *vam = &vat_main;
1804   i32 retval = ntohl (mp->retval);
1805   if (vam->async_mode)
1806     {
1807       vam->async_errors += (retval < 0);
1808     }
1809   else
1810     {
1811       vam->retval = retval;
1812       vam->sw_if_index = ntohl (mp->sw_if_index);
1813       vam->result_ready = 1;
1814     }
1815 }
1816
1817 static void vl_api_gre_add_del_tunnel_reply_t_handler_json
1818   (vl_api_gre_add_del_tunnel_reply_t * mp)
1819 {
1820   vat_main_t *vam = &vat_main;
1821   vat_json_node_t node;
1822
1823   vat_json_init_object (&node);
1824   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1825   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1826
1827   vat_json_print (vam->ofp, &node);
1828   vat_json_free (&node);
1829
1830   vam->retval = ntohl (mp->retval);
1831   vam->result_ready = 1;
1832 }
1833
1834 static void vl_api_create_vhost_user_if_reply_t_handler
1835   (vl_api_create_vhost_user_if_reply_t * mp)
1836 {
1837   vat_main_t *vam = &vat_main;
1838   i32 retval = ntohl (mp->retval);
1839   if (vam->async_mode)
1840     {
1841       vam->async_errors += (retval < 0);
1842     }
1843   else
1844     {
1845       vam->retval = retval;
1846       vam->sw_if_index = ntohl (mp->sw_if_index);
1847       vam->result_ready = 1;
1848     }
1849 }
1850
1851 static void vl_api_create_vhost_user_if_reply_t_handler_json
1852   (vl_api_create_vhost_user_if_reply_t * mp)
1853 {
1854   vat_main_t *vam = &vat_main;
1855   vat_json_node_t node;
1856
1857   vat_json_init_object (&node);
1858   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1859   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1860
1861   vat_json_print (vam->ofp, &node);
1862   vat_json_free (&node);
1863
1864   vam->retval = ntohl (mp->retval);
1865   vam->result_ready = 1;
1866 }
1867
1868 static void vl_api_ip_address_details_t_handler
1869   (vl_api_ip_address_details_t * mp)
1870 {
1871   vat_main_t *vam = &vat_main;
1872   static ip_address_details_t empty_ip_address_details = { {0} };
1873   ip_address_details_t *address = NULL;
1874   ip_details_t *current_ip_details = NULL;
1875   ip_details_t *details = NULL;
1876
1877   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
1878
1879   if (!details || vam->current_sw_if_index >= vec_len (details)
1880       || !details[vam->current_sw_if_index].present)
1881     {
1882       errmsg ("ip address details arrived but not stored");
1883       errmsg ("ip_dump should be called first");
1884       return;
1885     }
1886
1887   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
1888
1889 #define addresses (current_ip_details->addr)
1890
1891   vec_validate_init_empty (addresses, vec_len (addresses),
1892                            empty_ip_address_details);
1893
1894   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
1895
1896   clib_memcpy (&address->ip, &mp->ip, sizeof (address->ip));
1897   address->prefix_length = mp->prefix_length;
1898 #undef addresses
1899 }
1900
1901 static void vl_api_ip_address_details_t_handler_json
1902   (vl_api_ip_address_details_t * mp)
1903 {
1904   vat_main_t *vam = &vat_main;
1905   vat_json_node_t *node = NULL;
1906   struct in6_addr ip6;
1907   struct in_addr ip4;
1908
1909   if (VAT_JSON_ARRAY != vam->json_tree.type)
1910     {
1911       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1912       vat_json_init_array (&vam->json_tree);
1913     }
1914   node = vat_json_array_add (&vam->json_tree);
1915
1916   vat_json_init_object (node);
1917   if (vam->is_ipv6)
1918     {
1919       clib_memcpy (&ip6, mp->ip, sizeof (ip6));
1920       vat_json_object_add_ip6 (node, "ip", ip6);
1921     }
1922   else
1923     {
1924       clib_memcpy (&ip4, mp->ip, sizeof (ip4));
1925       vat_json_object_add_ip4 (node, "ip", ip4);
1926     }
1927   vat_json_object_add_uint (node, "prefix_length", mp->prefix_length);
1928 }
1929
1930 static void
1931 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
1932 {
1933   vat_main_t *vam = &vat_main;
1934   static ip_details_t empty_ip_details = { 0 };
1935   ip_details_t *ip = NULL;
1936   u32 sw_if_index = ~0;
1937
1938   sw_if_index = ntohl (mp->sw_if_index);
1939
1940   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1941                            sw_if_index, empty_ip_details);
1942
1943   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1944                          sw_if_index);
1945
1946   ip->present = 1;
1947 }
1948
1949 static void
1950 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
1951 {
1952   vat_main_t *vam = &vat_main;
1953
1954   if (VAT_JSON_ARRAY != vam->json_tree.type)
1955     {
1956       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1957       vat_json_init_array (&vam->json_tree);
1958     }
1959   vat_json_array_add_uint (&vam->json_tree,
1960                            clib_net_to_host_u32 (mp->sw_if_index));
1961 }
1962
1963 static void vl_api_map_domain_details_t_handler_json
1964   (vl_api_map_domain_details_t * mp)
1965 {
1966   vat_json_node_t *node = NULL;
1967   vat_main_t *vam = &vat_main;
1968   struct in6_addr ip6;
1969   struct in_addr ip4;
1970
1971   if (VAT_JSON_ARRAY != vam->json_tree.type)
1972     {
1973       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1974       vat_json_init_array (&vam->json_tree);
1975     }
1976
1977   node = vat_json_array_add (&vam->json_tree);
1978   vat_json_init_object (node);
1979
1980   vat_json_object_add_uint (node, "domain_index",
1981                             clib_net_to_host_u32 (mp->domain_index));
1982   clib_memcpy (&ip6, mp->ip6_prefix, sizeof (ip6));
1983   vat_json_object_add_ip6 (node, "ip6_prefix", ip6);
1984   clib_memcpy (&ip4, mp->ip4_prefix, sizeof (ip4));
1985   vat_json_object_add_ip4 (node, "ip4_prefix", ip4);
1986   clib_memcpy (&ip6, mp->ip6_src, sizeof (ip6));
1987   vat_json_object_add_ip6 (node, "ip6_src", ip6);
1988   vat_json_object_add_int (node, "ip6_prefix_len", mp->ip6_prefix_len);
1989   vat_json_object_add_int (node, "ip4_prefix_len", mp->ip4_prefix_len);
1990   vat_json_object_add_int (node, "ip6_src_len", mp->ip6_src_len);
1991   vat_json_object_add_int (node, "ea_bits_len", mp->ea_bits_len);
1992   vat_json_object_add_int (node, "psid_offset", mp->psid_offset);
1993   vat_json_object_add_int (node, "psid_length", mp->psid_length);
1994   vat_json_object_add_uint (node, "flags", mp->flags);
1995   vat_json_object_add_uint (node, "mtu", clib_net_to_host_u16 (mp->mtu));
1996   vat_json_object_add_int (node, "is_translation", mp->is_translation);
1997 }
1998
1999 static void vl_api_map_domain_details_t_handler
2000   (vl_api_map_domain_details_t * mp)
2001 {
2002   vat_main_t *vam = &vat_main;
2003
2004   if (mp->is_translation)
2005     {
2006       print (vam->ofp,
2007              "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U/%d (ip6-src) index: %u",
2008              format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
2009              format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
2010              format_ip6_address, mp->ip6_src, mp->ip6_src_len,
2011              clib_net_to_host_u32 (mp->domain_index));
2012     }
2013   else
2014     {
2015       print (vam->ofp,
2016              "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U (ip6-src) index: %u",
2017              format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
2018              format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
2019              format_ip6_address, mp->ip6_src,
2020              clib_net_to_host_u32 (mp->domain_index));
2021     }
2022   print (vam->ofp, "  ea-len %d psid-offset %d psid-len %d mtu %d %s",
2023          mp->ea_bits_len, mp->psid_offset, mp->psid_length, mp->mtu,
2024          mp->is_translation ? "map-t" : "");
2025 }
2026
2027 static void vl_api_map_rule_details_t_handler_json
2028   (vl_api_map_rule_details_t * mp)
2029 {
2030   struct in6_addr ip6;
2031   vat_json_node_t *node = NULL;
2032   vat_main_t *vam = &vat_main;
2033
2034   if (VAT_JSON_ARRAY != vam->json_tree.type)
2035     {
2036       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2037       vat_json_init_array (&vam->json_tree);
2038     }
2039
2040   node = vat_json_array_add (&vam->json_tree);
2041   vat_json_init_object (node);
2042
2043   vat_json_object_add_uint (node, "psid", clib_net_to_host_u16 (mp->psid));
2044   clib_memcpy (&ip6, mp->ip6_dst, sizeof (ip6));
2045   vat_json_object_add_ip6 (node, "ip6_dst", ip6);
2046 }
2047
2048 static void
2049 vl_api_map_rule_details_t_handler (vl_api_map_rule_details_t * mp)
2050 {
2051   vat_main_t *vam = &vat_main;
2052   print (vam->ofp, " %d (psid) %U (ip6-dst)",
2053          clib_net_to_host_u16 (mp->psid), format_ip6_address, mp->ip6_dst);
2054 }
2055
2056 static void
2057 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
2058 {
2059   errmsg ("DHCP compl event: pid %d %s hostname %s host_addr %U "
2060           "router_addr %U host_mac %U",
2061           ntohl (mp->pid), mp->is_ipv6 ? "ipv6" : "ipv4", mp->hostname,
2062           format_ip4_address, &mp->host_address,
2063           format_ip4_address, &mp->router_address,
2064           format_ethernet_address, mp->host_mac);
2065 }
2066
2067 static void vl_api_dhcp_compl_event_t_handler_json
2068   (vl_api_dhcp_compl_event_t * mp)
2069 {
2070   /* JSON output not supported */
2071 }
2072
2073 static void
2074 set_simple_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
2075                               u32 counter)
2076 {
2077   vat_main_t *vam = &vat_main;
2078   static u64 default_counter = 0;
2079
2080   vec_validate_init_empty (vam->simple_interface_counters, vnet_counter_type,
2081                            NULL);
2082   vec_validate_init_empty (vam->simple_interface_counters[vnet_counter_type],
2083                            sw_if_index, default_counter);
2084   vam->simple_interface_counters[vnet_counter_type][sw_if_index] = counter;
2085 }
2086
2087 static void
2088 set_combined_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
2089                                 interface_counter_t counter)
2090 {
2091   vat_main_t *vam = &vat_main;
2092   static interface_counter_t default_counter = { 0, };
2093
2094   vec_validate_init_empty (vam->combined_interface_counters,
2095                            vnet_counter_type, NULL);
2096   vec_validate_init_empty (vam->combined_interface_counters
2097                            [vnet_counter_type], sw_if_index, default_counter);
2098   vam->combined_interface_counters[vnet_counter_type][sw_if_index] = counter;
2099 }
2100
2101 static void vl_api_vnet_interface_counters_t_handler
2102   (vl_api_vnet_interface_counters_t * mp)
2103 {
2104   /* not supported */
2105 }
2106
2107 static void vl_api_vnet_interface_counters_t_handler_json
2108   (vl_api_vnet_interface_counters_t * mp)
2109 {
2110   interface_counter_t counter;
2111   vlib_counter_t *v;
2112   u64 *v_packets;
2113   u64 packets;
2114   u32 count;
2115   u32 first_sw_if_index;
2116   int i;
2117
2118   count = ntohl (mp->count);
2119   first_sw_if_index = ntohl (mp->first_sw_if_index);
2120
2121   if (!mp->is_combined)
2122     {
2123       v_packets = (u64 *) & mp->data;
2124       for (i = 0; i < count; i++)
2125         {
2126           packets =
2127             clib_net_to_host_u64 (clib_mem_unaligned (v_packets, u64));
2128           set_simple_interface_counter (mp->vnet_counter_type,
2129                                         first_sw_if_index + i, packets);
2130           v_packets++;
2131         }
2132     }
2133   else
2134     {
2135       v = (vlib_counter_t *) & mp->data;
2136       for (i = 0; i < count; i++)
2137         {
2138           counter.packets =
2139             clib_net_to_host_u64 (clib_mem_unaligned (&v->packets, u64));
2140           counter.bytes =
2141             clib_net_to_host_u64 (clib_mem_unaligned (&v->bytes, u64));
2142           set_combined_interface_counter (mp->vnet_counter_type,
2143                                           first_sw_if_index + i, counter);
2144           v++;
2145         }
2146     }
2147 }
2148
2149 static u32
2150 ip4_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2151 {
2152   vat_main_t *vam = &vat_main;
2153   u32 i;
2154
2155   for (i = 0; i < vec_len (vam->ip4_fib_counters_vrf_id_by_index); i++)
2156     {
2157       if (vam->ip4_fib_counters_vrf_id_by_index[i] == vrf_id)
2158         {
2159           return i;
2160         }
2161     }
2162   return ~0;
2163 }
2164
2165 static u32
2166 ip6_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2167 {
2168   vat_main_t *vam = &vat_main;
2169   u32 i;
2170
2171   for (i = 0; i < vec_len (vam->ip6_fib_counters_vrf_id_by_index); i++)
2172     {
2173       if (vam->ip6_fib_counters_vrf_id_by_index[i] == vrf_id)
2174         {
2175           return i;
2176         }
2177     }
2178   return ~0;
2179 }
2180
2181 static void vl_api_vnet_ip4_fib_counters_t_handler
2182   (vl_api_vnet_ip4_fib_counters_t * mp)
2183 {
2184   /* not supported */
2185 }
2186
2187 static void vl_api_vnet_ip4_fib_counters_t_handler_json
2188   (vl_api_vnet_ip4_fib_counters_t * mp)
2189 {
2190   vat_main_t *vam = &vat_main;
2191   vl_api_ip4_fib_counter_t *v;
2192   ip4_fib_counter_t *counter;
2193   struct in_addr ip4;
2194   u32 vrf_id;
2195   u32 vrf_index;
2196   u32 count;
2197   int i;
2198
2199   vrf_id = ntohl (mp->vrf_id);
2200   vrf_index = ip4_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2201   if (~0 == vrf_index)
2202     {
2203       vrf_index = vec_len (vam->ip4_fib_counters_vrf_id_by_index);
2204       vec_validate (vam->ip4_fib_counters_vrf_id_by_index, vrf_index);
2205       vam->ip4_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2206       vec_validate (vam->ip4_fib_counters, vrf_index);
2207       vam->ip4_fib_counters[vrf_index] = NULL;
2208     }
2209
2210   vec_free (vam->ip4_fib_counters[vrf_index]);
2211   v = (vl_api_ip4_fib_counter_t *) & mp->c;
2212   count = ntohl (mp->count);
2213   for (i = 0; i < count; i++)
2214     {
2215       vec_validate (vam->ip4_fib_counters[vrf_index], i);
2216       counter = &vam->ip4_fib_counters[vrf_index][i];
2217       clib_memcpy (&ip4, &v->address, sizeof (ip4));
2218       counter->address = ip4;
2219       counter->address_length = v->address_length;
2220       counter->packets = clib_net_to_host_u64 (v->packets);
2221       counter->bytes = clib_net_to_host_u64 (v->bytes);
2222       v++;
2223     }
2224 }
2225
2226 static void vl_api_vnet_ip4_nbr_counters_t_handler
2227   (vl_api_vnet_ip4_nbr_counters_t * mp)
2228 {
2229   /* not supported */
2230 }
2231
2232 static void vl_api_vnet_ip4_nbr_counters_t_handler_json
2233   (vl_api_vnet_ip4_nbr_counters_t * mp)
2234 {
2235   vat_main_t *vam = &vat_main;
2236   vl_api_ip4_nbr_counter_t *v;
2237   ip4_nbr_counter_t *counter;
2238   u32 sw_if_index;
2239   u32 count;
2240   int i;
2241
2242   sw_if_index = ntohl (mp->sw_if_index);
2243   count = ntohl (mp->count);
2244   vec_validate (vam->ip4_nbr_counters, sw_if_index);
2245
2246   if (mp->begin)
2247     vec_free (vam->ip4_nbr_counters[sw_if_index]);
2248
2249   v = (vl_api_ip4_nbr_counter_t *) & mp->c;
2250   for (i = 0; i < count; i++)
2251     {
2252       vec_validate (vam->ip4_nbr_counters[sw_if_index], i);
2253       counter = &vam->ip4_nbr_counters[sw_if_index][i];
2254       counter->address.s_addr = v->address;
2255       counter->packets = clib_net_to_host_u64 (v->packets);
2256       counter->bytes = clib_net_to_host_u64 (v->bytes);
2257       counter->linkt = v->link_type;
2258       v++;
2259     }
2260 }
2261
2262 static void vl_api_vnet_ip6_fib_counters_t_handler
2263   (vl_api_vnet_ip6_fib_counters_t * mp)
2264 {
2265   /* not supported */
2266 }
2267
2268 static void vl_api_vnet_ip6_fib_counters_t_handler_json
2269   (vl_api_vnet_ip6_fib_counters_t * mp)
2270 {
2271   vat_main_t *vam = &vat_main;
2272   vl_api_ip6_fib_counter_t *v;
2273   ip6_fib_counter_t *counter;
2274   struct in6_addr ip6;
2275   u32 vrf_id;
2276   u32 vrf_index;
2277   u32 count;
2278   int i;
2279
2280   vrf_id = ntohl (mp->vrf_id);
2281   vrf_index = ip6_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2282   if (~0 == vrf_index)
2283     {
2284       vrf_index = vec_len (vam->ip6_fib_counters_vrf_id_by_index);
2285       vec_validate (vam->ip6_fib_counters_vrf_id_by_index, vrf_index);
2286       vam->ip6_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2287       vec_validate (vam->ip6_fib_counters, vrf_index);
2288       vam->ip6_fib_counters[vrf_index] = NULL;
2289     }
2290
2291   vec_free (vam->ip6_fib_counters[vrf_index]);
2292   v = (vl_api_ip6_fib_counter_t *) & mp->c;
2293   count = ntohl (mp->count);
2294   for (i = 0; i < count; i++)
2295     {
2296       vec_validate (vam->ip6_fib_counters[vrf_index], i);
2297       counter = &vam->ip6_fib_counters[vrf_index][i];
2298       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2299       counter->address = ip6;
2300       counter->address_length = v->address_length;
2301       counter->packets = clib_net_to_host_u64 (v->packets);
2302       counter->bytes = clib_net_to_host_u64 (v->bytes);
2303       v++;
2304     }
2305 }
2306
2307 static void vl_api_vnet_ip6_nbr_counters_t_handler
2308   (vl_api_vnet_ip6_nbr_counters_t * mp)
2309 {
2310   /* not supported */
2311 }
2312
2313 static void vl_api_vnet_ip6_nbr_counters_t_handler_json
2314   (vl_api_vnet_ip6_nbr_counters_t * mp)
2315 {
2316   vat_main_t *vam = &vat_main;
2317   vl_api_ip6_nbr_counter_t *v;
2318   ip6_nbr_counter_t *counter;
2319   struct in6_addr ip6;
2320   u32 sw_if_index;
2321   u32 count;
2322   int i;
2323
2324   sw_if_index = ntohl (mp->sw_if_index);
2325   count = ntohl (mp->count);
2326   vec_validate (vam->ip6_nbr_counters, sw_if_index);
2327
2328   if (mp->begin)
2329     vec_free (vam->ip6_nbr_counters[sw_if_index]);
2330
2331   v = (vl_api_ip6_nbr_counter_t *) & mp->c;
2332   for (i = 0; i < count; i++)
2333     {
2334       vec_validate (vam->ip6_nbr_counters[sw_if_index], i);
2335       counter = &vam->ip6_nbr_counters[sw_if_index][i];
2336       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2337       counter->address = ip6;
2338       counter->packets = clib_net_to_host_u64 (v->packets);
2339       counter->bytes = clib_net_to_host_u64 (v->bytes);
2340       v++;
2341     }
2342 }
2343
2344 static void vl_api_get_first_msg_id_reply_t_handler
2345   (vl_api_get_first_msg_id_reply_t * mp)
2346 {
2347   vat_main_t *vam = &vat_main;
2348   i32 retval = ntohl (mp->retval);
2349
2350   if (vam->async_mode)
2351     {
2352       vam->async_errors += (retval < 0);
2353     }
2354   else
2355     {
2356       vam->retval = retval;
2357       vam->result_ready = 1;
2358     }
2359   if (retval >= 0)
2360     {
2361       errmsg ("first message id %d", ntohs (mp->first_msg_id));
2362     }
2363 }
2364
2365 static void vl_api_get_first_msg_id_reply_t_handler_json
2366   (vl_api_get_first_msg_id_reply_t * mp)
2367 {
2368   vat_main_t *vam = &vat_main;
2369   vat_json_node_t node;
2370
2371   vat_json_init_object (&node);
2372   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2373   vat_json_object_add_uint (&node, "first_msg_id",
2374                             (uint) ntohs (mp->first_msg_id));
2375
2376   vat_json_print (vam->ofp, &node);
2377   vat_json_free (&node);
2378
2379   vam->retval = ntohl (mp->retval);
2380   vam->result_ready = 1;
2381 }
2382
2383 static void vl_api_get_node_graph_reply_t_handler
2384   (vl_api_get_node_graph_reply_t * mp)
2385 {
2386   vat_main_t *vam = &vat_main;
2387   api_main_t *am = &api_main;
2388   i32 retval = ntohl (mp->retval);
2389   u8 *pvt_copy, *reply;
2390   void *oldheap;
2391   vlib_node_t *node;
2392   int i;
2393
2394   if (vam->async_mode)
2395     {
2396       vam->async_errors += (retval < 0);
2397     }
2398   else
2399     {
2400       vam->retval = retval;
2401       vam->result_ready = 1;
2402     }
2403
2404   /* "Should never happen..." */
2405   if (retval != 0)
2406     return;
2407
2408   reply = (u8 *) (mp->reply_in_shmem);
2409   pvt_copy = vec_dup (reply);
2410
2411   /* Toss the shared-memory original... */
2412   pthread_mutex_lock (&am->vlib_rp->mutex);
2413   oldheap = svm_push_data_heap (am->vlib_rp);
2414
2415   vec_free (reply);
2416
2417   svm_pop_heap (oldheap);
2418   pthread_mutex_unlock (&am->vlib_rp->mutex);
2419
2420   if (vam->graph_nodes)
2421     {
2422       hash_free (vam->graph_node_index_by_name);
2423
2424       for (i = 0; i < vec_len (vam->graph_nodes); i++)
2425         {
2426           node = vam->graph_nodes[i];
2427           vec_free (node->name);
2428           vec_free (node->next_nodes);
2429           vec_free (node);
2430         }
2431       vec_free (vam->graph_nodes);
2432     }
2433
2434   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2435   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2436   vec_free (pvt_copy);
2437
2438   for (i = 0; i < vec_len (vam->graph_nodes); i++)
2439     {
2440       node = vam->graph_nodes[i];
2441       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2442     }
2443 }
2444
2445 static void vl_api_get_node_graph_reply_t_handler_json
2446   (vl_api_get_node_graph_reply_t * mp)
2447 {
2448   vat_main_t *vam = &vat_main;
2449   api_main_t *am = &api_main;
2450   void *oldheap;
2451   vat_json_node_t node;
2452   u8 *reply;
2453
2454   /* $$$$ make this real? */
2455   vat_json_init_object (&node);
2456   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2457   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2458
2459   reply = (u8 *) (mp->reply_in_shmem);
2460
2461   /* Toss the shared-memory original... */
2462   pthread_mutex_lock (&am->vlib_rp->mutex);
2463   oldheap = svm_push_data_heap (am->vlib_rp);
2464
2465   vec_free (reply);
2466
2467   svm_pop_heap (oldheap);
2468   pthread_mutex_unlock (&am->vlib_rp->mutex);
2469
2470   vat_json_print (vam->ofp, &node);
2471   vat_json_free (&node);
2472
2473   vam->retval = ntohl (mp->retval);
2474   vam->result_ready = 1;
2475 }
2476
2477 static void
2478 vl_api_one_locator_details_t_handler (vl_api_one_locator_details_t * mp)
2479 {
2480   vat_main_t *vam = &vat_main;
2481   u8 *s = 0;
2482
2483   if (mp->local)
2484     {
2485       s = format (s, "%=16d%=16d%=16d",
2486                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
2487     }
2488   else
2489     {
2490       s = format (s, "%=16U%=16d%=16d",
2491                   mp->is_ipv6 ? format_ip6_address :
2492                   format_ip4_address,
2493                   mp->ip_address, mp->priority, mp->weight);
2494     }
2495
2496   print (vam->ofp, "%v", s);
2497   vec_free (s);
2498 }
2499
2500 static void
2501 vl_api_one_locator_details_t_handler_json (vl_api_one_locator_details_t * mp)
2502 {
2503   vat_main_t *vam = &vat_main;
2504   vat_json_node_t *node = NULL;
2505   struct in6_addr ip6;
2506   struct in_addr ip4;
2507
2508   if (VAT_JSON_ARRAY != vam->json_tree.type)
2509     {
2510       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2511       vat_json_init_array (&vam->json_tree);
2512     }
2513   node = vat_json_array_add (&vam->json_tree);
2514   vat_json_init_object (node);
2515
2516   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2517   vat_json_object_add_uint (node, "priority", mp->priority);
2518   vat_json_object_add_uint (node, "weight", mp->weight);
2519
2520   if (mp->local)
2521     vat_json_object_add_uint (node, "sw_if_index",
2522                               clib_net_to_host_u32 (mp->sw_if_index));
2523   else
2524     {
2525       if (mp->is_ipv6)
2526         {
2527           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2528           vat_json_object_add_ip6 (node, "address", ip6);
2529         }
2530       else
2531         {
2532           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2533           vat_json_object_add_ip4 (node, "address", ip4);
2534         }
2535     }
2536 }
2537
2538 static void
2539 vl_api_one_locator_set_details_t_handler (vl_api_one_locator_set_details_t *
2540                                           mp)
2541 {
2542   vat_main_t *vam = &vat_main;
2543   u8 *ls_name = 0;
2544
2545   ls_name = format (0, "%s", mp->ls_name);
2546
2547   print (vam->ofp, "%=10d%=15v", clib_net_to_host_u32 (mp->ls_index),
2548          ls_name);
2549   vec_free (ls_name);
2550 }
2551
2552 static void
2553   vl_api_one_locator_set_details_t_handler_json
2554   (vl_api_one_locator_set_details_t * mp)
2555 {
2556   vat_main_t *vam = &vat_main;
2557   vat_json_node_t *node = 0;
2558   u8 *ls_name = 0;
2559
2560   ls_name = format (0, "%s", mp->ls_name);
2561   vec_add1 (ls_name, 0);
2562
2563   if (VAT_JSON_ARRAY != vam->json_tree.type)
2564     {
2565       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2566       vat_json_init_array (&vam->json_tree);
2567     }
2568   node = vat_json_array_add (&vam->json_tree);
2569
2570   vat_json_init_object (node);
2571   vat_json_object_add_string_copy (node, "ls_name", ls_name);
2572   vat_json_object_add_uint (node, "ls_index",
2573                             clib_net_to_host_u32 (mp->ls_index));
2574   vec_free (ls_name);
2575 }
2576
2577 static u8 *
2578 format_lisp_flat_eid (u8 * s, va_list * args)
2579 {
2580   u32 type = va_arg (*args, u32);
2581   u8 *eid = va_arg (*args, u8 *);
2582   u32 eid_len = va_arg (*args, u32);
2583
2584   switch (type)
2585     {
2586     case 0:
2587       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
2588     case 1:
2589       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
2590     case 2:
2591       return format (s, "%U", format_ethernet_address, eid);
2592     }
2593   return 0;
2594 }
2595
2596 static u8 *
2597 format_lisp_eid_vat (u8 * s, va_list * args)
2598 {
2599   u32 type = va_arg (*args, u32);
2600   u8 *eid = va_arg (*args, u8 *);
2601   u32 eid_len = va_arg (*args, u32);
2602   u8 *seid = va_arg (*args, u8 *);
2603   u32 seid_len = va_arg (*args, u32);
2604   u32 is_src_dst = va_arg (*args, u32);
2605
2606   if (is_src_dst)
2607     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
2608
2609   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
2610
2611   return s;
2612 }
2613
2614 static void
2615 vl_api_one_eid_table_details_t_handler (vl_api_one_eid_table_details_t * mp)
2616 {
2617   vat_main_t *vam = &vat_main;
2618   u8 *s = 0, *eid = 0;
2619
2620   if (~0 == mp->locator_set_index)
2621     s = format (0, "action: %d", mp->action);
2622   else
2623     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
2624
2625   eid = format (0, "%U", format_lisp_eid_vat,
2626                 mp->eid_type,
2627                 mp->eid,
2628                 mp->eid_prefix_len,
2629                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2630   vec_add1 (eid, 0);
2631
2632   print (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s",
2633          clib_net_to_host_u32 (mp->vni),
2634          eid,
2635          mp->is_local ? "local" : "remote",
2636          s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
2637          clib_net_to_host_u16 (mp->key_id), mp->key);
2638
2639   vec_free (s);
2640   vec_free (eid);
2641 }
2642
2643 static void
2644 vl_api_one_eid_table_details_t_handler_json (vl_api_one_eid_table_details_t
2645                                              * mp)
2646 {
2647   vat_main_t *vam = &vat_main;
2648   vat_json_node_t *node = 0;
2649   u8 *eid = 0;
2650
2651   if (VAT_JSON_ARRAY != vam->json_tree.type)
2652     {
2653       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2654       vat_json_init_array (&vam->json_tree);
2655     }
2656   node = vat_json_array_add (&vam->json_tree);
2657
2658   vat_json_init_object (node);
2659   if (~0 == mp->locator_set_index)
2660     vat_json_object_add_uint (node, "action", mp->action);
2661   else
2662     vat_json_object_add_uint (node, "locator_set_index",
2663                               clib_net_to_host_u32 (mp->locator_set_index));
2664
2665   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
2666   eid = format (0, "%U", format_lisp_eid_vat,
2667                 mp->eid_type,
2668                 mp->eid,
2669                 mp->eid_prefix_len,
2670                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2671   vec_add1 (eid, 0);
2672   vat_json_object_add_string_copy (node, "eid", eid);
2673   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2674   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
2675   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
2676
2677   if (mp->key_id)
2678     {
2679       vat_json_object_add_uint (node, "key_id",
2680                                 clib_net_to_host_u16 (mp->key_id));
2681       vat_json_object_add_string_copy (node, "key", mp->key);
2682     }
2683   vec_free (eid);
2684 }
2685
2686 static void
2687 vl_api_one_stats_details_t_handler (vl_api_one_stats_details_t * mp)
2688 {
2689   vat_main_t *vam = &vat_main;
2690   u8 *seid = 0, *deid = 0;
2691   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
2692
2693   deid = format (0, "%U", format_lisp_eid_vat,
2694                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
2695
2696   seid = format (0, "%U", format_lisp_eid_vat,
2697                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
2698
2699   vec_add1 (deid, 0);
2700   vec_add1 (seid, 0);
2701
2702   if (mp->is_ip4)
2703     format_ip_address_fcn = format_ip4_address;
2704   else
2705     format_ip_address_fcn = format_ip6_address;
2706
2707
2708   print (vam->ofp, "([%d] %s %s) (%U %U) %u %u",
2709          clib_net_to_host_u32 (mp->vni),
2710          seid, deid,
2711          format_ip_address_fcn, mp->lloc,
2712          format_ip_address_fcn, mp->rloc,
2713          clib_net_to_host_u32 (mp->pkt_count),
2714          clib_net_to_host_u32 (mp->bytes));
2715
2716   vec_free (deid);
2717   vec_free (seid);
2718 }
2719
2720 static void
2721 vl_api_one_stats_details_t_handler_json (vl_api_one_stats_details_t * mp)
2722 {
2723   struct in6_addr ip6;
2724   struct in_addr ip4;
2725   vat_main_t *vam = &vat_main;
2726   vat_json_node_t *node = 0;
2727   u8 *deid = 0, *seid = 0;
2728
2729   if (VAT_JSON_ARRAY != vam->json_tree.type)
2730     {
2731       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2732       vat_json_init_array (&vam->json_tree);
2733     }
2734   node = vat_json_array_add (&vam->json_tree);
2735
2736   vat_json_init_object (node);
2737   deid = format (0, "%U", format_lisp_eid_vat,
2738                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
2739
2740   seid = format (0, "%U", format_lisp_eid_vat,
2741                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
2742
2743   vec_add1 (deid, 0);
2744   vec_add1 (seid, 0);
2745
2746   vat_json_object_add_string_copy (node, "seid", seid);
2747   vat_json_object_add_string_copy (node, "deid", deid);
2748   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2749
2750   if (mp->is_ip4)
2751     {
2752       clib_memcpy (&ip4, mp->lloc, sizeof (ip4));
2753       vat_json_object_add_ip4 (node, "lloc", ip4);
2754       clib_memcpy (&ip4, mp->rloc, sizeof (ip4));
2755       vat_json_object_add_ip4 (node, "rloc", ip4);
2756     }
2757   else
2758     {
2759       clib_memcpy (&ip6, mp->lloc, sizeof (ip6));
2760       vat_json_object_add_ip6 (node, "lloc", ip6);
2761       clib_memcpy (&ip6, mp->rloc, sizeof (ip6));
2762       vat_json_object_add_ip6 (node, "rloc", ip6);
2763     }
2764   vat_json_object_add_uint (node, "pkt_count",
2765                             clib_net_to_host_u32 (mp->pkt_count));
2766   vat_json_object_add_uint (node, "bytes", clib_net_to_host_u32 (mp->bytes));
2767
2768   vec_free (deid);
2769   vec_free (seid);
2770 }
2771
2772 static void
2773   vl_api_one_eid_table_map_details_t_handler
2774   (vl_api_one_eid_table_map_details_t * mp)
2775 {
2776   vat_main_t *vam = &vat_main;
2777
2778   u8 *line = format (0, "%=10d%=10d",
2779                      clib_net_to_host_u32 (mp->vni),
2780                      clib_net_to_host_u32 (mp->dp_table));
2781   print (vam->ofp, "%v", line);
2782   vec_free (line);
2783 }
2784
2785 static void
2786   vl_api_one_eid_table_map_details_t_handler_json
2787   (vl_api_one_eid_table_map_details_t * mp)
2788 {
2789   vat_main_t *vam = &vat_main;
2790   vat_json_node_t *node = NULL;
2791
2792   if (VAT_JSON_ARRAY != vam->json_tree.type)
2793     {
2794       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2795       vat_json_init_array (&vam->json_tree);
2796     }
2797   node = vat_json_array_add (&vam->json_tree);
2798   vat_json_init_object (node);
2799   vat_json_object_add_uint (node, "dp_table",
2800                             clib_net_to_host_u32 (mp->dp_table));
2801   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2802 }
2803
2804 static void
2805   vl_api_one_eid_table_vni_details_t_handler
2806   (vl_api_one_eid_table_vni_details_t * mp)
2807 {
2808   vat_main_t *vam = &vat_main;
2809
2810   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
2811   print (vam->ofp, "%v", line);
2812   vec_free (line);
2813 }
2814
2815 static void
2816   vl_api_one_eid_table_vni_details_t_handler_json
2817   (vl_api_one_eid_table_vni_details_t * mp)
2818 {
2819   vat_main_t *vam = &vat_main;
2820   vat_json_node_t *node = NULL;
2821
2822   if (VAT_JSON_ARRAY != vam->json_tree.type)
2823     {
2824       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2825       vat_json_init_array (&vam->json_tree);
2826     }
2827   node = vat_json_array_add (&vam->json_tree);
2828   vat_json_init_object (node);
2829   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2830 }
2831
2832 static void
2833   vl_api_show_one_map_register_state_reply_t_handler
2834   (vl_api_show_one_map_register_state_reply_t * mp)
2835 {
2836   vat_main_t *vam = &vat_main;
2837   int retval = clib_net_to_host_u32 (mp->retval);
2838
2839   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
2840
2841   vam->retval = retval;
2842   vam->result_ready = 1;
2843 }
2844
2845 static void
2846   vl_api_show_one_map_register_state_reply_t_handler_json
2847   (vl_api_show_one_map_register_state_reply_t * mp)
2848 {
2849   vat_main_t *vam = &vat_main;
2850   vat_json_node_t _node, *node = &_node;
2851   int retval = clib_net_to_host_u32 (mp->retval);
2852
2853   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
2854
2855   vat_json_init_object (node);
2856   vat_json_object_add_string_copy (node, "state", s);
2857
2858   vat_json_print (vam->ofp, node);
2859   vat_json_free (node);
2860
2861   vam->retval = retval;
2862   vam->result_ready = 1;
2863   vec_free (s);
2864 }
2865
2866 static void
2867   vl_api_show_one_rloc_probe_state_reply_t_handler
2868   (vl_api_show_one_rloc_probe_state_reply_t * mp)
2869 {
2870   vat_main_t *vam = &vat_main;
2871   int retval = clib_net_to_host_u32 (mp->retval);
2872
2873   if (retval)
2874     goto end;
2875
2876   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
2877 end:
2878   vam->retval = retval;
2879   vam->result_ready = 1;
2880 }
2881
2882 static void
2883   vl_api_show_one_rloc_probe_state_reply_t_handler_json
2884   (vl_api_show_one_rloc_probe_state_reply_t * mp)
2885 {
2886   vat_main_t *vam = &vat_main;
2887   vat_json_node_t _node, *node = &_node;
2888   int retval = clib_net_to_host_u32 (mp->retval);
2889
2890   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
2891   vat_json_init_object (node);
2892   vat_json_object_add_string_copy (node, "state", s);
2893
2894   vat_json_print (vam->ofp, node);
2895   vat_json_free (node);
2896
2897   vam->retval = retval;
2898   vam->result_ready = 1;
2899   vec_free (s);
2900 }
2901
2902 static void
2903   vl_api_show_one_stats_enable_disable_reply_t_handler
2904   (vl_api_show_one_stats_enable_disable_reply_t * mp)
2905 {
2906   vat_main_t *vam = &vat_main;
2907   int retval = clib_net_to_host_u32 (mp->retval);
2908
2909   if (retval)
2910     goto end;
2911
2912   print (vam->ofp, "%s", mp->is_en ? "enabled" : "disabled");
2913 end:
2914   vam->retval = retval;
2915   vam->result_ready = 1;
2916 }
2917
2918 static void
2919   vl_api_show_one_stats_enable_disable_reply_t_handler_json
2920   (vl_api_show_one_stats_enable_disable_reply_t * mp)
2921 {
2922   vat_main_t *vam = &vat_main;
2923   vat_json_node_t _node, *node = &_node;
2924   int retval = clib_net_to_host_u32 (mp->retval);
2925
2926   u8 *s = format (0, "%s", mp->is_en ? "enabled" : "disabled");
2927   vat_json_init_object (node);
2928   vat_json_object_add_string_copy (node, "state", s);
2929
2930   vat_json_print (vam->ofp, node);
2931   vat_json_free (node);
2932
2933   vam->retval = retval;
2934   vam->result_ready = 1;
2935   vec_free (s);
2936 }
2937
2938 static void
2939 api_gpe_fwd_entry_net_to_host (vl_api_gpe_fwd_entry_t * e)
2940 {
2941   e->dp_table = clib_net_to_host_u32 (e->dp_table);
2942   e->fwd_entry_index = clib_net_to_host_u32 (e->fwd_entry_index);
2943 }
2944
2945 static void
2946   gpe_fwd_entries_get_reply_t_net_to_host
2947   (vl_api_gpe_fwd_entries_get_reply_t * mp)
2948 {
2949   u32 i;
2950
2951   mp->count = clib_net_to_host_u32 (mp->count);
2952   for (i = 0; i < mp->count; i++)
2953     {
2954       api_gpe_fwd_entry_net_to_host (&mp->entries[i]);
2955     }
2956 }
2957
2958 static u8 *
2959 format_gpe_encap_mode (u8 * s, va_list * args)
2960 {
2961   u32 mode = va_arg (*args, u32);
2962
2963   switch (mode)
2964     {
2965     case 0:
2966       return format (s, "lisp");
2967     case 1:
2968       return format (s, "vxlan");
2969     }
2970   return 0;
2971 }
2972
2973 static void
2974   vl_api_gpe_get_encap_mode_reply_t_handler
2975   (vl_api_gpe_get_encap_mode_reply_t * mp)
2976 {
2977   vat_main_t *vam = &vat_main;
2978
2979   print (vam->ofp, "gpe mode: %U", format_gpe_encap_mode, mp->encap_mode);
2980   vam->retval = ntohl (mp->retval);
2981   vam->result_ready = 1;
2982 }
2983
2984 static void
2985   vl_api_gpe_get_encap_mode_reply_t_handler_json
2986   (vl_api_gpe_get_encap_mode_reply_t * mp)
2987 {
2988   vat_main_t *vam = &vat_main;
2989   vat_json_node_t node;
2990
2991   u8 *encap_mode = format (0, "%U", format_gpe_encap_mode, mp->encap_mode);
2992   vec_add1 (encap_mode, 0);
2993
2994   vat_json_init_object (&node);
2995   vat_json_object_add_string_copy (&node, "gpe_mode", encap_mode);
2996
2997   vec_free (encap_mode);
2998   vat_json_print (vam->ofp, &node);
2999   vat_json_free (&node);
3000
3001   vam->retval = ntohl (mp->retval);
3002   vam->result_ready = 1;
3003 }
3004
3005 static void
3006   vl_api_gpe_fwd_entry_path_details_t_handler
3007   (vl_api_gpe_fwd_entry_path_details_t * mp)
3008 {
3009   vat_main_t *vam = &vat_main;
3010   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3011
3012   if (mp->lcl_loc.is_ip4)
3013     format_ip_address_fcn = format_ip4_address;
3014   else
3015     format_ip_address_fcn = format_ip6_address;
3016
3017   print (vam->ofp, "w:%d %30U %30U", mp->rmt_loc.weight,
3018          format_ip_address_fcn, &mp->lcl_loc,
3019          format_ip_address_fcn, &mp->rmt_loc);
3020 }
3021
3022 static void
3023 lisp_fill_locator_node (vat_json_node_t * n, vl_api_gpe_locator_t * loc)
3024 {
3025   struct in6_addr ip6;
3026   struct in_addr ip4;
3027
3028   if (loc->is_ip4)
3029     {
3030       clib_memcpy (&ip4, loc->addr, sizeof (ip4));
3031       vat_json_object_add_ip4 (n, "address", ip4);
3032     }
3033   else
3034     {
3035       clib_memcpy (&ip6, loc->addr, sizeof (ip6));
3036       vat_json_object_add_ip6 (n, "address", ip6);
3037     }
3038   vat_json_object_add_uint (n, "weight", loc->weight);
3039 }
3040
3041 static void
3042   vl_api_gpe_fwd_entry_path_details_t_handler_json
3043   (vl_api_gpe_fwd_entry_path_details_t * mp)
3044 {
3045   vat_main_t *vam = &vat_main;
3046   vat_json_node_t *node = NULL;
3047   vat_json_node_t *loc_node;
3048
3049   if (VAT_JSON_ARRAY != vam->json_tree.type)
3050     {
3051       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3052       vat_json_init_array (&vam->json_tree);
3053     }
3054   node = vat_json_array_add (&vam->json_tree);
3055   vat_json_init_object (node);
3056
3057   loc_node = vat_json_object_add (node, "local_locator");
3058   vat_json_init_object (loc_node);
3059   lisp_fill_locator_node (loc_node, &mp->lcl_loc);
3060
3061   loc_node = vat_json_object_add (node, "remote_locator");
3062   vat_json_init_object (loc_node);
3063   lisp_fill_locator_node (loc_node, &mp->rmt_loc);
3064 }
3065
3066 static void
3067   vl_api_gpe_fwd_entries_get_reply_t_handler
3068   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3069 {
3070   vat_main_t *vam = &vat_main;
3071   u32 i;
3072   int retval = clib_net_to_host_u32 (mp->retval);
3073   vl_api_gpe_fwd_entry_t *e;
3074
3075   if (retval)
3076     goto end;
3077
3078   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3079
3080   for (i = 0; i < mp->count; i++)
3081     {
3082       e = &mp->entries[i];
3083       print (vam->ofp, "%10d %10d %U %40U", e->fwd_entry_index, e->dp_table,
3084              format_lisp_flat_eid, e->eid_type, e->leid, e->leid_prefix_len,
3085              format_lisp_flat_eid, e->eid_type, e->reid, e->reid_prefix_len);
3086     }
3087
3088 end:
3089   vam->retval = retval;
3090   vam->result_ready = 1;
3091 }
3092
3093 static void
3094   vl_api_gpe_fwd_entries_get_reply_t_handler_json
3095   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3096 {
3097   u8 *s = 0;
3098   vat_main_t *vam = &vat_main;
3099   vat_json_node_t *e = 0, root;
3100   u32 i;
3101   int retval = clib_net_to_host_u32 (mp->retval);
3102   vl_api_gpe_fwd_entry_t *fwd;
3103
3104   if (retval)
3105     goto end;
3106
3107   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3108   vat_json_init_array (&root);
3109
3110   for (i = 0; i < mp->count; i++)
3111     {
3112       e = vat_json_array_add (&root);
3113       fwd = &mp->entries[i];
3114
3115       vat_json_init_object (e);
3116       vat_json_object_add_int (e, "fwd_entry_index", fwd->fwd_entry_index);
3117       vat_json_object_add_int (e, "dp_table", fwd->dp_table);
3118
3119       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->leid,
3120                   fwd->leid_prefix_len);
3121       vec_add1 (s, 0);
3122       vat_json_object_add_string_copy (e, "leid", s);
3123       vec_free (s);
3124
3125       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->reid,
3126                   fwd->reid_prefix_len);
3127       vec_add1 (s, 0);
3128       vat_json_object_add_string_copy (e, "reid", s);
3129       vec_free (s);
3130     }
3131
3132   vat_json_print (vam->ofp, &root);
3133   vat_json_free (&root);
3134
3135 end:
3136   vam->retval = retval;
3137   vam->result_ready = 1;
3138 }
3139
3140 static void
3141   vl_api_one_adjacencies_get_reply_t_handler
3142   (vl_api_one_adjacencies_get_reply_t * mp)
3143 {
3144   vat_main_t *vam = &vat_main;
3145   u32 i, n;
3146   int retval = clib_net_to_host_u32 (mp->retval);
3147   vl_api_one_adjacency_t *a;
3148
3149   if (retval)
3150     goto end;
3151
3152   n = clib_net_to_host_u32 (mp->count);
3153
3154   for (i = 0; i < n; i++)
3155     {
3156       a = &mp->adjacencies[i];
3157       print (vam->ofp, "%U %40U",
3158              format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
3159              format_lisp_flat_eid, a->eid_type, a->reid, a->reid_prefix_len);
3160     }
3161
3162 end:
3163   vam->retval = retval;
3164   vam->result_ready = 1;
3165 }
3166
3167 static void
3168   vl_api_one_adjacencies_get_reply_t_handler_json
3169   (vl_api_one_adjacencies_get_reply_t * mp)
3170 {
3171   u8 *s = 0;
3172   vat_main_t *vam = &vat_main;
3173   vat_json_node_t *e = 0, root;
3174   u32 i, n;
3175   int retval = clib_net_to_host_u32 (mp->retval);
3176   vl_api_one_adjacency_t *a;
3177
3178   if (retval)
3179     goto end;
3180
3181   n = clib_net_to_host_u32 (mp->count);
3182   vat_json_init_array (&root);
3183
3184   for (i = 0; i < n; i++)
3185     {
3186       e = vat_json_array_add (&root);
3187       a = &mp->adjacencies[i];
3188
3189       vat_json_init_object (e);
3190       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
3191                   a->leid_prefix_len);
3192       vec_add1 (s, 0);
3193       vat_json_object_add_string_copy (e, "leid", s);
3194       vec_free (s);
3195
3196       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
3197                   a->reid_prefix_len);
3198       vec_add1 (s, 0);
3199       vat_json_object_add_string_copy (e, "reid", s);
3200       vec_free (s);
3201     }
3202
3203   vat_json_print (vam->ofp, &root);
3204   vat_json_free (&root);
3205
3206 end:
3207   vam->retval = retval;
3208   vam->result_ready = 1;
3209 }
3210
3211 static void
3212 vl_api_one_map_server_details_t_handler (vl_api_one_map_server_details_t * mp)
3213 {
3214   vat_main_t *vam = &vat_main;
3215
3216   print (vam->ofp, "%=20U",
3217          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
3218          mp->ip_address);
3219 }
3220
3221 static void
3222   vl_api_one_map_server_details_t_handler_json
3223   (vl_api_one_map_server_details_t * mp)
3224 {
3225   vat_main_t *vam = &vat_main;
3226   vat_json_node_t *node = NULL;
3227   struct in6_addr ip6;
3228   struct in_addr ip4;
3229
3230   if (VAT_JSON_ARRAY != vam->json_tree.type)
3231     {
3232       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3233       vat_json_init_array (&vam->json_tree);
3234     }
3235   node = vat_json_array_add (&vam->json_tree);
3236
3237   vat_json_init_object (node);
3238   if (mp->is_ipv6)
3239     {
3240       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
3241       vat_json_object_add_ip6 (node, "map-server", ip6);
3242     }
3243   else
3244     {
3245       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
3246       vat_json_object_add_ip4 (node, "map-server", ip4);
3247     }
3248 }
3249
3250 static void
3251 vl_api_one_map_resolver_details_t_handler (vl_api_one_map_resolver_details_t
3252                                            * mp)
3253 {
3254   vat_main_t *vam = &vat_main;
3255
3256   print (vam->ofp, "%=20U",
3257          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
3258          mp->ip_address);
3259 }
3260
3261 static void
3262   vl_api_one_map_resolver_details_t_handler_json
3263   (vl_api_one_map_resolver_details_t * mp)
3264 {
3265   vat_main_t *vam = &vat_main;
3266   vat_json_node_t *node = NULL;
3267   struct in6_addr ip6;
3268   struct in_addr ip4;
3269
3270   if (VAT_JSON_ARRAY != vam->json_tree.type)
3271     {
3272       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3273       vat_json_init_array (&vam->json_tree);
3274     }
3275   node = vat_json_array_add (&vam->json_tree);
3276
3277   vat_json_init_object (node);
3278   if (mp->is_ipv6)
3279     {
3280       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
3281       vat_json_object_add_ip6 (node, "map resolver", ip6);
3282     }
3283   else
3284     {
3285       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
3286       vat_json_object_add_ip4 (node, "map resolver", ip4);
3287     }
3288 }
3289
3290 static void
3291 vl_api_show_one_status_reply_t_handler (vl_api_show_one_status_reply_t * mp)
3292 {
3293   vat_main_t *vam = &vat_main;
3294   i32 retval = ntohl (mp->retval);
3295
3296   if (0 <= retval)
3297     {
3298       print (vam->ofp, "feature: %s\ngpe: %s",
3299              mp->feature_status ? "enabled" : "disabled",
3300              mp->gpe_status ? "enabled" : "disabled");
3301     }
3302
3303   vam->retval = retval;
3304   vam->result_ready = 1;
3305 }
3306
3307 static void
3308   vl_api_show_one_status_reply_t_handler_json
3309   (vl_api_show_one_status_reply_t * mp)
3310 {
3311   vat_main_t *vam = &vat_main;
3312   vat_json_node_t node;
3313   u8 *gpe_status = NULL;
3314   u8 *feature_status = NULL;
3315
3316   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
3317   feature_status = format (0, "%s",
3318                            mp->feature_status ? "enabled" : "disabled");
3319   vec_add1 (gpe_status, 0);
3320   vec_add1 (feature_status, 0);
3321
3322   vat_json_init_object (&node);
3323   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
3324   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
3325
3326   vec_free (gpe_status);
3327   vec_free (feature_status);
3328
3329   vat_json_print (vam->ofp, &node);
3330   vat_json_free (&node);
3331
3332   vam->retval = ntohl (mp->retval);
3333   vam->result_ready = 1;
3334 }
3335
3336 static void
3337   vl_api_one_get_map_request_itr_rlocs_reply_t_handler
3338   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
3339 {
3340   vat_main_t *vam = &vat_main;
3341   i32 retval = ntohl (mp->retval);
3342
3343   if (retval >= 0)
3344     {
3345       print (vam->ofp, "%=20s", mp->locator_set_name);
3346     }
3347
3348   vam->retval = retval;
3349   vam->result_ready = 1;
3350 }
3351
3352 static void
3353   vl_api_one_get_map_request_itr_rlocs_reply_t_handler_json
3354   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
3355 {
3356   vat_main_t *vam = &vat_main;
3357   vat_json_node_t *node = NULL;
3358
3359   if (VAT_JSON_ARRAY != vam->json_tree.type)
3360     {
3361       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3362       vat_json_init_array (&vam->json_tree);
3363     }
3364   node = vat_json_array_add (&vam->json_tree);
3365
3366   vat_json_init_object (node);
3367   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
3368
3369   vat_json_print (vam->ofp, node);
3370   vat_json_free (node);
3371
3372   vam->retval = ntohl (mp->retval);
3373   vam->result_ready = 1;
3374 }
3375
3376 static u8 *
3377 format_lisp_map_request_mode (u8 * s, va_list * args)
3378 {
3379   u32 mode = va_arg (*args, u32);
3380
3381   switch (mode)
3382     {
3383     case 0:
3384       return format (0, "dst-only");
3385     case 1:
3386       return format (0, "src-dst");
3387     }
3388   return 0;
3389 }
3390
3391 static void
3392   vl_api_show_one_map_request_mode_reply_t_handler
3393   (vl_api_show_one_map_request_mode_reply_t * mp)
3394 {
3395   vat_main_t *vam = &vat_main;
3396   i32 retval = ntohl (mp->retval);
3397
3398   if (0 <= retval)
3399     {
3400       u32 mode = mp->mode;
3401       print (vam->ofp, "map_request_mode: %U",
3402              format_lisp_map_request_mode, mode);
3403     }
3404
3405   vam->retval = retval;
3406   vam->result_ready = 1;
3407 }
3408
3409 static void
3410   vl_api_show_one_map_request_mode_reply_t_handler_json
3411   (vl_api_show_one_map_request_mode_reply_t * mp)
3412 {
3413   vat_main_t *vam = &vat_main;
3414   vat_json_node_t node;
3415   u8 *s = 0;
3416   u32 mode;
3417
3418   mode = mp->mode;
3419   s = format (0, "%U", format_lisp_map_request_mode, mode);
3420   vec_add1 (s, 0);
3421
3422   vat_json_init_object (&node);
3423   vat_json_object_add_string_copy (&node, "map_request_mode", s);
3424   vat_json_print (vam->ofp, &node);
3425   vat_json_free (&node);
3426
3427   vec_free (s);
3428   vam->retval = ntohl (mp->retval);
3429   vam->result_ready = 1;
3430 }
3431
3432 static void
3433   vl_api_show_one_use_petr_reply_t_handler
3434   (vl_api_show_one_use_petr_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, "%s\n", mp->status ? "enabled" : "disabled");
3442       if (mp->status)
3443         {
3444           print (vam->ofp, "Proxy-ETR address; %U",
3445                  mp->is_ip4 ? format_ip4_address : format_ip6_address,
3446                  mp->address);
3447         }
3448     }
3449
3450   vam->retval = retval;
3451   vam->result_ready = 1;
3452 }
3453
3454 static void
3455   vl_api_show_one_use_petr_reply_t_handler_json
3456   (vl_api_show_one_use_petr_reply_t * mp)
3457 {
3458   vat_main_t *vam = &vat_main;
3459   vat_json_node_t node;
3460   u8 *status = 0;
3461   struct in_addr ip4;
3462   struct in6_addr ip6;
3463
3464   status = format (0, "%s", mp->status ? "enabled" : "disabled");
3465   vec_add1 (status, 0);
3466
3467   vat_json_init_object (&node);
3468   vat_json_object_add_string_copy (&node, "status", status);
3469   if (mp->status)
3470     {
3471       if (mp->is_ip4)
3472         {
3473           clib_memcpy (&ip6, mp->address, sizeof (ip6));
3474           vat_json_object_add_ip6 (&node, "address", ip6);
3475         }
3476       else
3477         {
3478           clib_memcpy (&ip4, mp->address, sizeof (ip4));
3479           vat_json_object_add_ip4 (&node, "address", ip4);
3480         }
3481     }
3482
3483   vec_free (status);
3484
3485   vat_json_print (vam->ofp, &node);
3486   vat_json_free (&node);
3487
3488   vam->retval = ntohl (mp->retval);
3489   vam->result_ready = 1;
3490 }
3491
3492 static void
3493 vl_api_show_one_pitr_reply_t_handler (vl_api_show_one_pitr_reply_t * mp)
3494 {
3495   vat_main_t *vam = &vat_main;
3496   i32 retval = ntohl (mp->retval);
3497
3498   if (0 <= retval)
3499     {
3500       print (vam->ofp, "%-20s%-16s",
3501              mp->status ? "enabled" : "disabled",
3502              mp->status ? (char *) mp->locator_set_name : "");
3503     }
3504
3505   vam->retval = retval;
3506   vam->result_ready = 1;
3507 }
3508
3509 static void
3510 vl_api_show_one_pitr_reply_t_handler_json (vl_api_show_one_pitr_reply_t * mp)
3511 {
3512   vat_main_t *vam = &vat_main;
3513   vat_json_node_t node;
3514   u8 *status = 0;
3515
3516   status = format (0, "%s", mp->status ? "enabled" : "disabled");
3517   vec_add1 (status, 0);
3518
3519   vat_json_init_object (&node);
3520   vat_json_object_add_string_copy (&node, "status", status);
3521   if (mp->status)
3522     {
3523       vat_json_object_add_string_copy (&node, "locator_set",
3524                                        mp->locator_set_name);
3525     }
3526
3527   vec_free (status);
3528
3529   vat_json_print (vam->ofp, &node);
3530   vat_json_free (&node);
3531
3532   vam->retval = ntohl (mp->retval);
3533   vam->result_ready = 1;
3534 }
3535
3536 static u8 *
3537 format_policer_type (u8 * s, va_list * va)
3538 {
3539   u32 i = va_arg (*va, u32);
3540
3541   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
3542     s = format (s, "1r2c");
3543   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
3544     s = format (s, "1r3c");
3545   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
3546     s = format (s, "2r3c-2698");
3547   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
3548     s = format (s, "2r3c-4115");
3549   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
3550     s = format (s, "2r3c-mef5cf1");
3551   else
3552     s = format (s, "ILLEGAL");
3553   return s;
3554 }
3555
3556 static u8 *
3557 format_policer_rate_type (u8 * s, va_list * va)
3558 {
3559   u32 i = va_arg (*va, u32);
3560
3561   if (i == SSE2_QOS_RATE_KBPS)
3562     s = format (s, "kbps");
3563   else if (i == SSE2_QOS_RATE_PPS)
3564     s = format (s, "pps");
3565   else
3566     s = format (s, "ILLEGAL");
3567   return s;
3568 }
3569
3570 static u8 *
3571 format_policer_round_type (u8 * s, va_list * va)
3572 {
3573   u32 i = va_arg (*va, u32);
3574
3575   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
3576     s = format (s, "closest");
3577   else if (i == SSE2_QOS_ROUND_TO_UP)
3578     s = format (s, "up");
3579   else if (i == SSE2_QOS_ROUND_TO_DOWN)
3580     s = format (s, "down");
3581   else
3582     s = format (s, "ILLEGAL");
3583   return s;
3584 }
3585
3586 static u8 *
3587 format_policer_action_type (u8 * s, va_list * va)
3588 {
3589   u32 i = va_arg (*va, u32);
3590
3591   if (i == SSE2_QOS_ACTION_DROP)
3592     s = format (s, "drop");
3593   else if (i == SSE2_QOS_ACTION_TRANSMIT)
3594     s = format (s, "transmit");
3595   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3596     s = format (s, "mark-and-transmit");
3597   else
3598     s = format (s, "ILLEGAL");
3599   return s;
3600 }
3601
3602 static u8 *
3603 format_dscp (u8 * s, va_list * va)
3604 {
3605   u32 i = va_arg (*va, u32);
3606   char *t = 0;
3607
3608   switch (i)
3609     {
3610 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
3611       foreach_vnet_dscp
3612 #undef _
3613     default:
3614       return format (s, "ILLEGAL");
3615     }
3616   s = format (s, "%s", t);
3617   return s;
3618 }
3619
3620 static void
3621 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
3622 {
3623   vat_main_t *vam = &vat_main;
3624   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
3625
3626   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3627     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
3628   else
3629     conform_dscp_str = format (0, "");
3630
3631   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3632     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
3633   else
3634     exceed_dscp_str = format (0, "");
3635
3636   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3637     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
3638   else
3639     violate_dscp_str = format (0, "");
3640
3641   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
3642          "rate type %U, round type %U, %s rate, %s color-aware, "
3643          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
3644          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
3645          "conform action %U%s, exceed action %U%s, violate action %U%s",
3646          mp->name,
3647          format_policer_type, mp->type,
3648          ntohl (mp->cir),
3649          ntohl (mp->eir),
3650          clib_net_to_host_u64 (mp->cb),
3651          clib_net_to_host_u64 (mp->eb),
3652          format_policer_rate_type, mp->rate_type,
3653          format_policer_round_type, mp->round_type,
3654          mp->single_rate ? "single" : "dual",
3655          mp->color_aware ? "is" : "not",
3656          ntohl (mp->cir_tokens_per_period),
3657          ntohl (mp->pir_tokens_per_period),
3658          ntohl (mp->scale),
3659          ntohl (mp->current_limit),
3660          ntohl (mp->current_bucket),
3661          ntohl (mp->extended_limit),
3662          ntohl (mp->extended_bucket),
3663          clib_net_to_host_u64 (mp->last_update_time),
3664          format_policer_action_type, mp->conform_action_type,
3665          conform_dscp_str,
3666          format_policer_action_type, mp->exceed_action_type,
3667          exceed_dscp_str,
3668          format_policer_action_type, mp->violate_action_type,
3669          violate_dscp_str);
3670
3671   vec_free (conform_dscp_str);
3672   vec_free (exceed_dscp_str);
3673   vec_free (violate_dscp_str);
3674 }
3675
3676 static void vl_api_policer_details_t_handler_json
3677   (vl_api_policer_details_t * mp)
3678 {
3679   vat_main_t *vam = &vat_main;
3680   vat_json_node_t *node;
3681   u8 *rate_type_str, *round_type_str, *type_str;
3682   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
3683
3684   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
3685   round_type_str =
3686     format (0, "%U", format_policer_round_type, mp->round_type);
3687   type_str = format (0, "%U", format_policer_type, mp->type);
3688   conform_action_str = format (0, "%U", format_policer_action_type,
3689                                mp->conform_action_type);
3690   exceed_action_str = format (0, "%U", format_policer_action_type,
3691                               mp->exceed_action_type);
3692   violate_action_str = format (0, "%U", format_policer_action_type,
3693                                mp->violate_action_type);
3694
3695   if (VAT_JSON_ARRAY != vam->json_tree.type)
3696     {
3697       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3698       vat_json_init_array (&vam->json_tree);
3699     }
3700   node = vat_json_array_add (&vam->json_tree);
3701
3702   vat_json_init_object (node);
3703   vat_json_object_add_string_copy (node, "name", mp->name);
3704   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
3705   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
3706   vat_json_object_add_uint (node, "cb", clib_net_to_host_u64 (mp->cb));
3707   vat_json_object_add_uint (node, "eb", clib_net_to_host_u64 (mp->eb));
3708   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
3709   vat_json_object_add_string_copy (node, "round_type", round_type_str);
3710   vat_json_object_add_string_copy (node, "type", type_str);
3711   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
3712   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
3713   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
3714   vat_json_object_add_uint (node, "cir_tokens_per_period",
3715                             ntohl (mp->cir_tokens_per_period));
3716   vat_json_object_add_uint (node, "eir_tokens_per_period",
3717                             ntohl (mp->pir_tokens_per_period));
3718   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
3719   vat_json_object_add_uint (node, "current_bucket",
3720                             ntohl (mp->current_bucket));
3721   vat_json_object_add_uint (node, "extended_limit",
3722                             ntohl (mp->extended_limit));
3723   vat_json_object_add_uint (node, "extended_bucket",
3724                             ntohl (mp->extended_bucket));
3725   vat_json_object_add_uint (node, "last_update_time",
3726                             ntohl (mp->last_update_time));
3727   vat_json_object_add_string_copy (node, "conform_action",
3728                                    conform_action_str);
3729   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3730     {
3731       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
3732       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
3733       vec_free (dscp_str);
3734     }
3735   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
3736   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3737     {
3738       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
3739       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
3740       vec_free (dscp_str);
3741     }
3742   vat_json_object_add_string_copy (node, "violate_action",
3743                                    violate_action_str);
3744   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3745     {
3746       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
3747       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
3748       vec_free (dscp_str);
3749     }
3750
3751   vec_free (rate_type_str);
3752   vec_free (round_type_str);
3753   vec_free (type_str);
3754   vec_free (conform_action_str);
3755   vec_free (exceed_action_str);
3756   vec_free (violate_action_str);
3757 }
3758
3759 static void
3760 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
3761                                            mp)
3762 {
3763   vat_main_t *vam = &vat_main;
3764   int i, count = ntohl (mp->count);
3765
3766   if (count > 0)
3767     print (vam->ofp, "classify table ids (%d) : ", count);
3768   for (i = 0; i < count; i++)
3769     {
3770       print (vam->ofp, "%d", ntohl (mp->ids[i]));
3771       print (vam->ofp, (i < count - 1) ? "," : "");
3772     }
3773   vam->retval = ntohl (mp->retval);
3774   vam->result_ready = 1;
3775 }
3776
3777 static void
3778   vl_api_classify_table_ids_reply_t_handler_json
3779   (vl_api_classify_table_ids_reply_t * mp)
3780 {
3781   vat_main_t *vam = &vat_main;
3782   int i, count = ntohl (mp->count);
3783
3784   if (count > 0)
3785     {
3786       vat_json_node_t node;
3787
3788       vat_json_init_object (&node);
3789       for (i = 0; i < count; i++)
3790         {
3791           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
3792         }
3793       vat_json_print (vam->ofp, &node);
3794       vat_json_free (&node);
3795     }
3796   vam->retval = ntohl (mp->retval);
3797   vam->result_ready = 1;
3798 }
3799
3800 static void
3801   vl_api_classify_table_by_interface_reply_t_handler
3802   (vl_api_classify_table_by_interface_reply_t * mp)
3803 {
3804   vat_main_t *vam = &vat_main;
3805   u32 table_id;
3806
3807   table_id = ntohl (mp->l2_table_id);
3808   if (table_id != ~0)
3809     print (vam->ofp, "l2 table id : %d", table_id);
3810   else
3811     print (vam->ofp, "l2 table id : No input ACL tables configured");
3812   table_id = ntohl (mp->ip4_table_id);
3813   if (table_id != ~0)
3814     print (vam->ofp, "ip4 table id : %d", table_id);
3815   else
3816     print (vam->ofp, "ip4 table id : No input ACL tables configured");
3817   table_id = ntohl (mp->ip6_table_id);
3818   if (table_id != ~0)
3819     print (vam->ofp, "ip6 table id : %d", table_id);
3820   else
3821     print (vam->ofp, "ip6 table id : No input ACL tables configured");
3822   vam->retval = ntohl (mp->retval);
3823   vam->result_ready = 1;
3824 }
3825
3826 static void
3827   vl_api_classify_table_by_interface_reply_t_handler_json
3828   (vl_api_classify_table_by_interface_reply_t * mp)
3829 {
3830   vat_main_t *vam = &vat_main;
3831   vat_json_node_t node;
3832
3833   vat_json_init_object (&node);
3834
3835   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
3836   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
3837   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
3838
3839   vat_json_print (vam->ofp, &node);
3840   vat_json_free (&node);
3841
3842   vam->retval = ntohl (mp->retval);
3843   vam->result_ready = 1;
3844 }
3845
3846 static void vl_api_policer_add_del_reply_t_handler
3847   (vl_api_policer_add_del_reply_t * mp)
3848 {
3849   vat_main_t *vam = &vat_main;
3850   i32 retval = ntohl (mp->retval);
3851   if (vam->async_mode)
3852     {
3853       vam->async_errors += (retval < 0);
3854     }
3855   else
3856     {
3857       vam->retval = retval;
3858       vam->result_ready = 1;
3859       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
3860         /*
3861          * Note: this is just barely thread-safe, depends on
3862          * the main thread spinning waiting for an answer...
3863          */
3864         errmsg ("policer index %d", ntohl (mp->policer_index));
3865     }
3866 }
3867
3868 static void vl_api_policer_add_del_reply_t_handler_json
3869   (vl_api_policer_add_del_reply_t * mp)
3870 {
3871   vat_main_t *vam = &vat_main;
3872   vat_json_node_t node;
3873
3874   vat_json_init_object (&node);
3875   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3876   vat_json_object_add_uint (&node, "policer_index",
3877                             ntohl (mp->policer_index));
3878
3879   vat_json_print (vam->ofp, &node);
3880   vat_json_free (&node);
3881
3882   vam->retval = ntohl (mp->retval);
3883   vam->result_ready = 1;
3884 }
3885
3886 /* Format hex dump. */
3887 u8 *
3888 format_hex_bytes (u8 * s, va_list * va)
3889 {
3890   u8 *bytes = va_arg (*va, u8 *);
3891   int n_bytes = va_arg (*va, int);
3892   uword i;
3893
3894   /* Print short or long form depending on byte count. */
3895   uword short_form = n_bytes <= 32;
3896   uword indent = format_get_indent (s);
3897
3898   if (n_bytes == 0)
3899     return s;
3900
3901   for (i = 0; i < n_bytes; i++)
3902     {
3903       if (!short_form && (i % 32) == 0)
3904         s = format (s, "%08x: ", i);
3905       s = format (s, "%02x", bytes[i]);
3906       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
3907         s = format (s, "\n%U", format_white_space, indent);
3908     }
3909
3910   return s;
3911 }
3912
3913 static void
3914 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
3915                                             * mp)
3916 {
3917   vat_main_t *vam = &vat_main;
3918   i32 retval = ntohl (mp->retval);
3919   if (retval == 0)
3920     {
3921       print (vam->ofp, "classify table info :");
3922       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
3923              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
3924              ntohl (mp->miss_next_index));
3925       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
3926              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
3927              ntohl (mp->match_n_vectors));
3928       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
3929              ntohl (mp->mask_length));
3930     }
3931   vam->retval = retval;
3932   vam->result_ready = 1;
3933 }
3934
3935 static void
3936   vl_api_classify_table_info_reply_t_handler_json
3937   (vl_api_classify_table_info_reply_t * mp)
3938 {
3939   vat_main_t *vam = &vat_main;
3940   vat_json_node_t node;
3941
3942   i32 retval = ntohl (mp->retval);
3943   if (retval == 0)
3944     {
3945       vat_json_init_object (&node);
3946
3947       vat_json_object_add_int (&node, "sessions",
3948                                ntohl (mp->active_sessions));
3949       vat_json_object_add_int (&node, "nexttbl",
3950                                ntohl (mp->next_table_index));
3951       vat_json_object_add_int (&node, "nextnode",
3952                                ntohl (mp->miss_next_index));
3953       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
3954       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
3955       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
3956       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
3957                       ntohl (mp->mask_length), 0);
3958       vat_json_object_add_string_copy (&node, "mask", s);
3959
3960       vat_json_print (vam->ofp, &node);
3961       vat_json_free (&node);
3962     }
3963   vam->retval = ntohl (mp->retval);
3964   vam->result_ready = 1;
3965 }
3966
3967 static void
3968 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
3969                                            mp)
3970 {
3971   vat_main_t *vam = &vat_main;
3972
3973   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
3974          ntohl (mp->hit_next_index), ntohl (mp->advance),
3975          ntohl (mp->opaque_index));
3976   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
3977          ntohl (mp->match_length));
3978 }
3979
3980 static void
3981   vl_api_classify_session_details_t_handler_json
3982   (vl_api_classify_session_details_t * mp)
3983 {
3984   vat_main_t *vam = &vat_main;
3985   vat_json_node_t *node = NULL;
3986
3987   if (VAT_JSON_ARRAY != vam->json_tree.type)
3988     {
3989       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3990       vat_json_init_array (&vam->json_tree);
3991     }
3992   node = vat_json_array_add (&vam->json_tree);
3993
3994   vat_json_init_object (node);
3995   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
3996   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
3997   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
3998   u8 *s =
3999     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
4000             0);
4001   vat_json_object_add_string_copy (node, "match", s);
4002 }
4003
4004 static void vl_api_pg_create_interface_reply_t_handler
4005   (vl_api_pg_create_interface_reply_t * mp)
4006 {
4007   vat_main_t *vam = &vat_main;
4008
4009   vam->retval = ntohl (mp->retval);
4010   vam->result_ready = 1;
4011 }
4012
4013 static void vl_api_pg_create_interface_reply_t_handler_json
4014   (vl_api_pg_create_interface_reply_t * mp)
4015 {
4016   vat_main_t *vam = &vat_main;
4017   vat_json_node_t node;
4018
4019   i32 retval = ntohl (mp->retval);
4020   if (retval == 0)
4021     {
4022       vat_json_init_object (&node);
4023
4024       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
4025
4026       vat_json_print (vam->ofp, &node);
4027       vat_json_free (&node);
4028     }
4029   vam->retval = ntohl (mp->retval);
4030   vam->result_ready = 1;
4031 }
4032
4033 static void vl_api_policer_classify_details_t_handler
4034   (vl_api_policer_classify_details_t * mp)
4035 {
4036   vat_main_t *vam = &vat_main;
4037
4038   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
4039          ntohl (mp->table_index));
4040 }
4041
4042 static void vl_api_policer_classify_details_t_handler_json
4043   (vl_api_policer_classify_details_t * mp)
4044 {
4045   vat_main_t *vam = &vat_main;
4046   vat_json_node_t *node;
4047
4048   if (VAT_JSON_ARRAY != vam->json_tree.type)
4049     {
4050       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4051       vat_json_init_array (&vam->json_tree);
4052     }
4053   node = vat_json_array_add (&vam->json_tree);
4054
4055   vat_json_init_object (node);
4056   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
4057   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
4058 }
4059
4060 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler
4061   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
4062 {
4063   vat_main_t *vam = &vat_main;
4064   i32 retval = ntohl (mp->retval);
4065   if (vam->async_mode)
4066     {
4067       vam->async_errors += (retval < 0);
4068     }
4069   else
4070     {
4071       vam->retval = retval;
4072       vam->sw_if_index = ntohl (mp->sw_if_index);
4073       vam->result_ready = 1;
4074     }
4075 }
4076
4077 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler_json
4078   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
4079 {
4080   vat_main_t *vam = &vat_main;
4081   vat_json_node_t node;
4082
4083   vat_json_init_object (&node);
4084   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
4085   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
4086
4087   vat_json_print (vam->ofp, &node);
4088   vat_json_free (&node);
4089
4090   vam->retval = ntohl (mp->retval);
4091   vam->result_ready = 1;
4092 }
4093
4094 static void vl_api_flow_classify_details_t_handler
4095   (vl_api_flow_classify_details_t * mp)
4096 {
4097   vat_main_t *vam = &vat_main;
4098
4099   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
4100          ntohl (mp->table_index));
4101 }
4102
4103 static void vl_api_flow_classify_details_t_handler_json
4104   (vl_api_flow_classify_details_t * mp)
4105 {
4106   vat_main_t *vam = &vat_main;
4107   vat_json_node_t *node;
4108
4109   if (VAT_JSON_ARRAY != vam->json_tree.type)
4110     {
4111       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4112       vat_json_init_array (&vam->json_tree);
4113     }
4114   node = vat_json_array_add (&vam->json_tree);
4115
4116   vat_json_init_object (node);
4117   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
4118   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
4119 }
4120
4121
4122
4123 #define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
4124 #define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler
4125 #define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler
4126 #define vl_api_vnet_ip6_fib_counters_t_print vl_noop_handler
4127 #define vl_api_vnet_ip4_nbr_counters_t_endian vl_noop_handler
4128 #define vl_api_vnet_ip4_nbr_counters_t_print vl_noop_handler
4129 #define vl_api_vnet_ip6_nbr_counters_t_endian vl_noop_handler
4130 #define vl_api_vnet_ip6_nbr_counters_t_print vl_noop_handler
4131 #define vl_api_one_adjacencies_get_reply_t_endian vl_noop_handler
4132 #define vl_api_one_adjacencies_get_reply_t_print vl_noop_handler
4133
4134 /*
4135  * Generate boilerplate reply handlers, which
4136  * dig the return value out of the xxx_reply_t API message,
4137  * stick it into vam->retval, and set vam->result_ready
4138  *
4139  * Could also do this by pointing N message decode slots at
4140  * a single function, but that could break in subtle ways.
4141  */
4142
4143 #define foreach_standard_reply_retval_handler           \
4144 _(sw_interface_set_flags_reply)                         \
4145 _(sw_interface_add_del_address_reply)                   \
4146 _(sw_interface_set_table_reply)                         \
4147 _(sw_interface_set_mpls_enable_reply)                   \
4148 _(sw_interface_set_vpath_reply)                         \
4149 _(sw_interface_set_vxlan_bypass_reply)                  \
4150 _(sw_interface_set_l2_bridge_reply)                     \
4151 _(bridge_domain_add_del_reply)                          \
4152 _(sw_interface_set_l2_xconnect_reply)                   \
4153 _(l2fib_add_del_reply)                                  \
4154 _(l2fib_flush_int_reply)                                \
4155 _(l2fib_flush_bd_reply)                                 \
4156 _(ip_add_del_route_reply)                               \
4157 _(ip_mroute_add_del_reply)                              \
4158 _(mpls_route_add_del_reply)                             \
4159 _(mpls_ip_bind_unbind_reply)                            \
4160 _(proxy_arp_add_del_reply)                              \
4161 _(proxy_arp_intfc_enable_disable_reply)                 \
4162 _(sw_interface_set_unnumbered_reply)                    \
4163 _(ip_neighbor_add_del_reply)                            \
4164 _(reset_vrf_reply)                                      \
4165 _(oam_add_del_reply)                                    \
4166 _(reset_fib_reply)                                      \
4167 _(dhcp_proxy_config_reply)                              \
4168 _(dhcp_proxy_set_vss_reply)                             \
4169 _(dhcp_client_config_reply)                             \
4170 _(set_ip_flow_hash_reply)                               \
4171 _(sw_interface_ip6_enable_disable_reply)                \
4172 _(sw_interface_ip6_set_link_local_address_reply)        \
4173 _(ip6nd_proxy_add_del_reply)                            \
4174 _(sw_interface_ip6nd_ra_prefix_reply)                   \
4175 _(sw_interface_ip6nd_ra_config_reply)                   \
4176 _(set_arp_neighbor_limit_reply)                         \
4177 _(l2_patch_add_del_reply)                               \
4178 _(sr_policy_add_reply)                                  \
4179 _(sr_policy_mod_reply)                                  \
4180 _(sr_policy_del_reply)                                  \
4181 _(sr_localsid_add_del_reply)                            \
4182 _(sr_steering_add_del_reply)                            \
4183 _(classify_add_del_session_reply)                       \
4184 _(classify_set_interface_ip_table_reply)                \
4185 _(classify_set_interface_l2_tables_reply)               \
4186 _(l2tpv3_set_tunnel_cookies_reply)                      \
4187 _(l2tpv3_interface_enable_disable_reply)                \
4188 _(l2tpv3_set_lookup_key_reply)                          \
4189 _(l2_fib_clear_table_reply)                             \
4190 _(l2_interface_efp_filter_reply)                        \
4191 _(l2_interface_vlan_tag_rewrite_reply)                  \
4192 _(modify_vhost_user_if_reply)                           \
4193 _(delete_vhost_user_if_reply)                           \
4194 _(want_ip4_arp_events_reply)                            \
4195 _(want_ip6_nd_events_reply)                             \
4196 _(input_acl_set_interface_reply)                        \
4197 _(ipsec_spd_add_del_reply)                              \
4198 _(ipsec_interface_add_del_spd_reply)                    \
4199 _(ipsec_spd_add_del_entry_reply)                        \
4200 _(ipsec_sad_add_del_entry_reply)                        \
4201 _(ipsec_sa_set_key_reply)                               \
4202 _(ikev2_profile_add_del_reply)                          \
4203 _(ikev2_profile_set_auth_reply)                         \
4204 _(ikev2_profile_set_id_reply)                           \
4205 _(ikev2_profile_set_ts_reply)                           \
4206 _(ikev2_set_local_key_reply)                            \
4207 _(ikev2_set_responder_reply)                            \
4208 _(ikev2_set_ike_transforms_reply)                       \
4209 _(ikev2_set_esp_transforms_reply)                       \
4210 _(ikev2_set_sa_lifetime_reply)                          \
4211 _(ikev2_initiate_sa_init_reply)                         \
4212 _(ikev2_initiate_del_ike_sa_reply)                      \
4213 _(ikev2_initiate_del_child_sa_reply)                    \
4214 _(ikev2_initiate_rekey_child_sa_reply)                  \
4215 _(delete_loopback_reply)                                \
4216 _(bd_ip_mac_add_del_reply)                              \
4217 _(map_del_domain_reply)                                 \
4218 _(map_add_del_rule_reply)                               \
4219 _(want_interface_events_reply)                          \
4220 _(want_stats_reply)                                     \
4221 _(cop_interface_enable_disable_reply)                   \
4222 _(cop_whitelist_enable_disable_reply)                   \
4223 _(sw_interface_clear_stats_reply)                       \
4224 _(ioam_enable_reply)                              \
4225 _(ioam_disable_reply)                              \
4226 _(one_add_del_locator_reply)                            \
4227 _(one_add_del_local_eid_reply)                          \
4228 _(one_add_del_remote_mapping_reply)                     \
4229 _(one_add_del_adjacency_reply)                          \
4230 _(one_add_del_map_resolver_reply)                       \
4231 _(one_add_del_map_server_reply)                         \
4232 _(one_enable_disable_reply)                             \
4233 _(one_rloc_probe_enable_disable_reply)                  \
4234 _(one_map_register_enable_disable_reply)                \
4235 _(one_pitr_set_locator_set_reply)                       \
4236 _(one_map_request_mode_reply)                           \
4237 _(one_add_del_map_request_itr_rlocs_reply)              \
4238 _(one_eid_table_add_del_map_reply)                      \
4239 _(one_use_petr_reply)                                   \
4240 _(one_stats_enable_disable_reply)                       \
4241 _(one_stats_flush_reply)                                \
4242 _(gpe_add_del_fwd_entry_reply)                          \
4243 _(gpe_enable_disable_reply)                             \
4244 _(gpe_set_encap_mode_reply)                             \
4245 _(gpe_add_del_iface_reply)                              \
4246 _(vxlan_gpe_add_del_tunnel_reply)                       \
4247 _(af_packet_delete_reply)                               \
4248 _(policer_classify_set_interface_reply)                 \
4249 _(netmap_create_reply)                                  \
4250 _(netmap_delete_reply)                                  \
4251 _(set_ipfix_exporter_reply)                             \
4252 _(set_ipfix_classify_stream_reply)                      \
4253 _(ipfix_classify_table_add_del_reply)                   \
4254 _(flow_classify_set_interface_reply)                    \
4255 _(sw_interface_span_enable_disable_reply)               \
4256 _(pg_capture_reply)                                     \
4257 _(pg_enable_disable_reply)                              \
4258 _(ip_source_and_port_range_check_add_del_reply)         \
4259 _(ip_source_and_port_range_check_interface_add_del_reply)\
4260 _(delete_subif_reply)                                   \
4261 _(l2_interface_pbb_tag_rewrite_reply)                   \
4262 _(punt_reply)                                           \
4263 _(feature_enable_disable_reply)                         \
4264 _(sw_interface_tag_add_del_reply)                       \
4265 _(sw_interface_set_mtu_reply)
4266
4267 #define _(n)                                    \
4268     static void vl_api_##n##_t_handler          \
4269     (vl_api_##n##_t * mp)                       \
4270     {                                           \
4271         vat_main_t * vam = &vat_main;           \
4272         i32 retval = ntohl(mp->retval);         \
4273         if (vam->async_mode) {                  \
4274             vam->async_errors += (retval < 0);  \
4275         } else {                                \
4276             vam->retval = retval;               \
4277             vam->result_ready = 1;              \
4278         }                                       \
4279     }
4280 foreach_standard_reply_retval_handler;
4281 #undef _
4282
4283 #define _(n)                                    \
4284     static void vl_api_##n##_t_handler_json     \
4285     (vl_api_##n##_t * mp)                       \
4286     {                                           \
4287         vat_main_t * vam = &vat_main;           \
4288         vat_json_node_t node;                   \
4289         vat_json_init_object(&node);            \
4290         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
4291         vat_json_print(vam->ofp, &node);        \
4292         vam->retval = ntohl(mp->retval);        \
4293         vam->result_ready = 1;                  \
4294     }
4295 foreach_standard_reply_retval_handler;
4296 #undef _
4297
4298 /*
4299  * Table of message reply handlers, must include boilerplate handlers
4300  * we just generated
4301  */
4302
4303 #define foreach_vpe_api_reply_msg                                       \
4304 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
4305 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
4306 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
4307 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
4308 _(CONTROL_PING_REPLY, control_ping_reply)                               \
4309 _(CLI_REPLY, cli_reply)                                                 \
4310 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
4311 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
4312   sw_interface_add_del_address_reply)                                   \
4313 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
4314 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
4315 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
4316 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
4317 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
4318   sw_interface_set_l2_xconnect_reply)                                   \
4319 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
4320   sw_interface_set_l2_bridge_reply)                                     \
4321 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
4322 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
4323 _(BRIDGE_DOMAIN_SW_IF_DETAILS, bridge_domain_sw_if_details)             \
4324 _(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply)     \
4325 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
4326 _(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply)                         \
4327 _(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply)                           \
4328 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
4329 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
4330 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
4331 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
4332 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
4333 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
4334 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
4335 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
4336 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
4337 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
4338 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
4339 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
4340   proxy_arp_intfc_enable_disable_reply)                                 \
4341 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
4342 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
4343   sw_interface_set_unnumbered_reply)                                    \
4344 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
4345 _(RESET_VRF_REPLY, reset_vrf_reply)                                     \
4346 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
4347 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
4348 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
4349 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
4350 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
4351 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
4352 _(DHCP_PROXY_DETAILS, dhcp_proxy_details)                               \
4353 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
4354 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
4355 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
4356   sw_interface_ip6_enable_disable_reply)                                \
4357 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY,                        \
4358   sw_interface_ip6_set_link_local_address_reply)                        \
4359 _(IP6ND_PROXY_ADD_DEL_REPLY, ip6nd_proxy_add_del_reply)                 \
4360 _(IP6ND_PROXY_DETAILS, ip6nd_proxy_details)                             \
4361 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
4362   sw_interface_ip6nd_ra_prefix_reply)                                   \
4363 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
4364   sw_interface_ip6nd_ra_config_reply)                                   \
4365 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
4366 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
4367 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
4368 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
4369 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
4370 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
4371 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
4372 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
4373 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
4374 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
4375 classify_set_interface_ip_table_reply)                                  \
4376 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
4377   classify_set_interface_l2_tables_reply)                               \
4378 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
4379 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
4380 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
4381 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
4382 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
4383   l2tpv3_interface_enable_disable_reply)                                \
4384 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
4385 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
4386 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
4387 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
4388 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
4389 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
4390 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
4391 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
4392 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
4393 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
4394 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
4395 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
4396 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
4397 _(SHOW_VERSION_REPLY, show_version_reply)                               \
4398 _(L2_FIB_TABLE_ENTRY, l2_fib_table_entry)                               \
4399 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)           \
4400 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
4401 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
4402 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
4403 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
4404 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
4405 _(IP6_ND_EVENT, ip6_nd_event)                                           \
4406 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
4407 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
4408 _(IP_DETAILS, ip_details)                                               \
4409 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
4410 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
4411 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
4412 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
4413 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
4414 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
4415 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
4416 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
4417 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
4418 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
4419 _(IKEV2_SET_RESPONDER_REPLY, ikev2_set_responder_reply)                 \
4420 _(IKEV2_SET_IKE_TRANSFORMS_REPLY, ikev2_set_ike_transforms_reply)       \
4421 _(IKEV2_SET_ESP_TRANSFORMS_REPLY, ikev2_set_esp_transforms_reply)       \
4422 _(IKEV2_SET_SA_LIFETIME_REPLY, ikev2_set_sa_lifetime_reply)             \
4423 _(IKEV2_INITIATE_SA_INIT_REPLY, ikev2_initiate_sa_init_reply)           \
4424 _(IKEV2_INITIATE_DEL_IKE_SA_REPLY, ikev2_initiate_del_ike_sa_reply)     \
4425 _(IKEV2_INITIATE_DEL_CHILD_SA_REPLY, ikev2_initiate_del_child_sa_reply) \
4426 _(IKEV2_INITIATE_REKEY_CHILD_SA_REPLY, ikev2_initiate_rekey_child_sa_reply) \
4427 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
4428 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
4429 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
4430 _(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply)                           \
4431 _(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply)                           \
4432 _(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply)                       \
4433 _(MAP_DOMAIN_DETAILS, map_domain_details)                               \
4434 _(MAP_RULE_DETAILS, map_rule_details)                                   \
4435 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
4436 _(WANT_STATS_REPLY, want_stats_reply)                                   \
4437 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
4438 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
4439 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
4440 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
4441 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
4442 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
4443 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
4444 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
4445 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
4446 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
4447 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
4448 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
4449 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
4450 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
4451 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
4452 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
4453   one_map_register_enable_disable_reply)                                \
4454 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
4455   one_rloc_probe_enable_disable_reply)                                  \
4456 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
4457 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
4458 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
4459 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
4460 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
4461 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
4462 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
4463 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
4464 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
4465 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
4466 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
4467 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
4468 _(ONE_STATS_DETAILS, one_stats_details)                                 \
4469 _(ONE_STATS_FLUSH_REPLY, one_stats_flush_reply)                         \
4470 _(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply)       \
4471 _(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,                                  \
4472   show_one_stats_enable_disable_reply)                                  \
4473 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
4474 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
4475 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
4476 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
4477 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
4478 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
4479 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
4480   gpe_fwd_entry_path_details)                                           \
4481 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
4482 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
4483   one_add_del_map_request_itr_rlocs_reply)                              \
4484 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
4485   one_get_map_request_itr_rlocs_reply)                                  \
4486 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
4487 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
4488 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
4489 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
4490 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
4491   show_one_map_register_state_reply)                                    \
4492 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
4493 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
4494 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
4495 _(POLICER_DETAILS, policer_details)                                     \
4496 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
4497 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
4498 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
4499 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
4500 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
4501 _(MPLS_FIB_DETAILS, mpls_fib_details)                                   \
4502 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
4503 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
4504 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
4505 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
4506 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
4507 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
4508 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
4509 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
4510 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
4511 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
4512 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
4513 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
4514 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
4515 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
4516 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
4517 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
4518 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
4519 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
4520 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
4521  ip_source_and_port_range_check_add_del_reply)                          \
4522 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
4523  ip_source_and_port_range_check_interface_add_del_reply)                \
4524 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
4525 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
4526 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
4527 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
4528 _(PUNT_REPLY, punt_reply)                                               \
4529 _(IP_FIB_DETAILS, ip_fib_details)                                       \
4530 _(IP6_FIB_DETAILS, ip6_fib_details)                                     \
4531 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
4532 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
4533 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
4534 _(SW_INTERFACE_SET_MTU_REPLY, sw_interface_set_mtu_reply)               \
4535 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
4536 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)
4537
4538 #define foreach_standalone_reply_msg                                    \
4539 _(SW_INTERFACE_SET_FLAGS, sw_interface_set_flags)                       \
4540 _(VNET_INTERFACE_COUNTERS, vnet_interface_counters)                     \
4541 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
4542 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
4543 _(VNET_IP4_NBR_COUNTERS, vnet_ip4_nbr_counters)                         \
4544 _(VNET_IP6_NBR_COUNTERS, vnet_ip6_nbr_counters)
4545
4546 typedef struct
4547 {
4548   u8 *name;
4549   u32 value;
4550 } name_sort_t;
4551
4552
4553 #define STR_VTR_OP_CASE(op)     \
4554     case L2_VTR_ ## op:         \
4555         return "" # op;
4556
4557 static const char *
4558 str_vtr_op (u32 vtr_op)
4559 {
4560   switch (vtr_op)
4561     {
4562       STR_VTR_OP_CASE (DISABLED);
4563       STR_VTR_OP_CASE (PUSH_1);
4564       STR_VTR_OP_CASE (PUSH_2);
4565       STR_VTR_OP_CASE (POP_1);
4566       STR_VTR_OP_CASE (POP_2);
4567       STR_VTR_OP_CASE (TRANSLATE_1_1);
4568       STR_VTR_OP_CASE (TRANSLATE_1_2);
4569       STR_VTR_OP_CASE (TRANSLATE_2_1);
4570       STR_VTR_OP_CASE (TRANSLATE_2_2);
4571     }
4572
4573   return "UNKNOWN";
4574 }
4575
4576 static int
4577 dump_sub_interface_table (vat_main_t * vam)
4578 {
4579   const sw_interface_subif_t *sub = NULL;
4580
4581   if (vam->json_output)
4582     {
4583       clib_warning
4584         ("JSON output supported only for VPE API calls and dump_stats_table");
4585       return -99;
4586     }
4587
4588   print (vam->ofp,
4589          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
4590          "Interface", "sw_if_index",
4591          "sub id", "dot1ad", "tags", "outer id",
4592          "inner id", "exact", "default", "outer any", "inner any");
4593
4594   vec_foreach (sub, vam->sw_if_subif_table)
4595   {
4596     print (vam->ofp,
4597            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
4598            sub->interface_name,
4599            sub->sw_if_index,
4600            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
4601            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
4602            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
4603            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
4604     if (sub->vtr_op != L2_VTR_DISABLED)
4605       {
4606         print (vam->ofp,
4607                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
4608                "tag1: %d tag2: %d ]",
4609                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
4610                sub->vtr_tag1, sub->vtr_tag2);
4611       }
4612   }
4613
4614   return 0;
4615 }
4616
4617 static int
4618 name_sort_cmp (void *a1, void *a2)
4619 {
4620   name_sort_t *n1 = a1;
4621   name_sort_t *n2 = a2;
4622
4623   return strcmp ((char *) n1->name, (char *) n2->name);
4624 }
4625
4626 static int
4627 dump_interface_table (vat_main_t * vam)
4628 {
4629   hash_pair_t *p;
4630   name_sort_t *nses = 0, *ns;
4631
4632   if (vam->json_output)
4633     {
4634       clib_warning
4635         ("JSON output supported only for VPE API calls and dump_stats_table");
4636       return -99;
4637     }
4638
4639   /* *INDENT-OFF* */
4640   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
4641   ({
4642     vec_add2 (nses, ns, 1);
4643     ns->name = (u8 *)(p->key);
4644     ns->value = (u32) p->value[0];
4645   }));
4646   /* *INDENT-ON* */
4647
4648   vec_sort_with_function (nses, name_sort_cmp);
4649
4650   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
4651   vec_foreach (ns, nses)
4652   {
4653     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
4654   }
4655   vec_free (nses);
4656   return 0;
4657 }
4658
4659 static int
4660 dump_ip_table (vat_main_t * vam, int is_ipv6)
4661 {
4662   const ip_details_t *det = NULL;
4663   const ip_address_details_t *address = NULL;
4664   u32 i = ~0;
4665
4666   print (vam->ofp, "%-12s", "sw_if_index");
4667
4668   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
4669   {
4670     i++;
4671     if (!det->present)
4672       {
4673         continue;
4674       }
4675     print (vam->ofp, "%-12d", i);
4676     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
4677     if (!det->addr)
4678       {
4679         continue;
4680       }
4681     vec_foreach (address, det->addr)
4682     {
4683       print (vam->ofp,
4684              "            %-30U%-13d",
4685              is_ipv6 ? format_ip6_address : format_ip4_address,
4686              address->ip, address->prefix_length);
4687     }
4688   }
4689
4690   return 0;
4691 }
4692
4693 static int
4694 dump_ipv4_table (vat_main_t * vam)
4695 {
4696   if (vam->json_output)
4697     {
4698       clib_warning
4699         ("JSON output supported only for VPE API calls and dump_stats_table");
4700       return -99;
4701     }
4702
4703   return dump_ip_table (vam, 0);
4704 }
4705
4706 static int
4707 dump_ipv6_table (vat_main_t * vam)
4708 {
4709   if (vam->json_output)
4710     {
4711       clib_warning
4712         ("JSON output supported only for VPE API calls and dump_stats_table");
4713       return -99;
4714     }
4715
4716   return dump_ip_table (vam, 1);
4717 }
4718
4719 static char *
4720 counter_type_to_str (u8 counter_type, u8 is_combined)
4721 {
4722   if (!is_combined)
4723     {
4724       switch (counter_type)
4725         {
4726         case VNET_INTERFACE_COUNTER_DROP:
4727           return "drop";
4728         case VNET_INTERFACE_COUNTER_PUNT:
4729           return "punt";
4730         case VNET_INTERFACE_COUNTER_IP4:
4731           return "ip4";
4732         case VNET_INTERFACE_COUNTER_IP6:
4733           return "ip6";
4734         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
4735           return "rx-no-buf";
4736         case VNET_INTERFACE_COUNTER_RX_MISS:
4737           return "rx-miss";
4738         case VNET_INTERFACE_COUNTER_RX_ERROR:
4739           return "rx-error";
4740         case VNET_INTERFACE_COUNTER_TX_ERROR:
4741           return "tx-error";
4742         default:
4743           return "INVALID-COUNTER-TYPE";
4744         }
4745     }
4746   else
4747     {
4748       switch (counter_type)
4749         {
4750         case VNET_INTERFACE_COUNTER_RX:
4751           return "rx";
4752         case VNET_INTERFACE_COUNTER_TX:
4753           return "tx";
4754         default:
4755           return "INVALID-COUNTER-TYPE";
4756         }
4757     }
4758 }
4759
4760 static int
4761 dump_stats_table (vat_main_t * vam)
4762 {
4763   vat_json_node_t node;
4764   vat_json_node_t *msg_array;
4765   vat_json_node_t *msg;
4766   vat_json_node_t *counter_array;
4767   vat_json_node_t *counter;
4768   interface_counter_t c;
4769   u64 packets;
4770   ip4_fib_counter_t *c4;
4771   ip6_fib_counter_t *c6;
4772   ip4_nbr_counter_t *n4;
4773   ip6_nbr_counter_t *n6;
4774   int i, j;
4775
4776   if (!vam->json_output)
4777     {
4778       clib_warning ("dump_stats_table supported only in JSON format");
4779       return -99;
4780     }
4781
4782   vat_json_init_object (&node);
4783
4784   /* interface counters */
4785   msg_array = vat_json_object_add (&node, "interface_counters");
4786   vat_json_init_array (msg_array);
4787   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
4788     {
4789       msg = vat_json_array_add (msg_array);
4790       vat_json_init_object (msg);
4791       vat_json_object_add_string_copy (msg, "vnet_counter_type",
4792                                        (u8 *) counter_type_to_str (i, 0));
4793       vat_json_object_add_int (msg, "is_combined", 0);
4794       counter_array = vat_json_object_add (msg, "data");
4795       vat_json_init_array (counter_array);
4796       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
4797         {
4798           packets = vam->simple_interface_counters[i][j];
4799           vat_json_array_add_uint (counter_array, packets);
4800         }
4801     }
4802   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
4803     {
4804       msg = vat_json_array_add (msg_array);
4805       vat_json_init_object (msg);
4806       vat_json_object_add_string_copy (msg, "vnet_counter_type",
4807                                        (u8 *) counter_type_to_str (i, 1));
4808       vat_json_object_add_int (msg, "is_combined", 1);
4809       counter_array = vat_json_object_add (msg, "data");
4810       vat_json_init_array (counter_array);
4811       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
4812         {
4813           c = vam->combined_interface_counters[i][j];
4814           counter = vat_json_array_add (counter_array);
4815           vat_json_init_object (counter);
4816           vat_json_object_add_uint (counter, "packets", c.packets);
4817           vat_json_object_add_uint (counter, "bytes", c.bytes);
4818         }
4819     }
4820
4821   /* ip4 fib counters */
4822   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
4823   vat_json_init_array (msg_array);
4824   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
4825     {
4826       msg = vat_json_array_add (msg_array);
4827       vat_json_init_object (msg);
4828       vat_json_object_add_uint (msg, "vrf_id",
4829                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
4830       counter_array = vat_json_object_add (msg, "c");
4831       vat_json_init_array (counter_array);
4832       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
4833         {
4834           counter = vat_json_array_add (counter_array);
4835           vat_json_init_object (counter);
4836           c4 = &vam->ip4_fib_counters[i][j];
4837           vat_json_object_add_ip4 (counter, "address", c4->address);
4838           vat_json_object_add_uint (counter, "address_length",
4839                                     c4->address_length);
4840           vat_json_object_add_uint (counter, "packets", c4->packets);
4841           vat_json_object_add_uint (counter, "bytes", c4->bytes);
4842         }
4843     }
4844
4845   /* ip6 fib counters */
4846   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
4847   vat_json_init_array (msg_array);
4848   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
4849     {
4850       msg = vat_json_array_add (msg_array);
4851       vat_json_init_object (msg);
4852       vat_json_object_add_uint (msg, "vrf_id",
4853                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
4854       counter_array = vat_json_object_add (msg, "c");
4855       vat_json_init_array (counter_array);
4856       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
4857         {
4858           counter = vat_json_array_add (counter_array);
4859           vat_json_init_object (counter);
4860           c6 = &vam->ip6_fib_counters[i][j];
4861           vat_json_object_add_ip6 (counter, "address", c6->address);
4862           vat_json_object_add_uint (counter, "address_length",
4863                                     c6->address_length);
4864           vat_json_object_add_uint (counter, "packets", c6->packets);
4865           vat_json_object_add_uint (counter, "bytes", c6->bytes);
4866         }
4867     }
4868
4869   /* ip4 nbr counters */
4870   msg_array = vat_json_object_add (&node, "ip4_nbr_counters");
4871   vat_json_init_array (msg_array);
4872   for (i = 0; i < vec_len (vam->ip4_nbr_counters); i++)
4873     {
4874       msg = vat_json_array_add (msg_array);
4875       vat_json_init_object (msg);
4876       vat_json_object_add_uint (msg, "sw_if_index", i);
4877       counter_array = vat_json_object_add (msg, "c");
4878       vat_json_init_array (counter_array);
4879       for (j = 0; j < vec_len (vam->ip4_nbr_counters[i]); j++)
4880         {
4881           counter = vat_json_array_add (counter_array);
4882           vat_json_init_object (counter);
4883           n4 = &vam->ip4_nbr_counters[i][j];
4884           vat_json_object_add_ip4 (counter, "address", n4->address);
4885           vat_json_object_add_uint (counter, "link-type", n4->linkt);
4886           vat_json_object_add_uint (counter, "packets", n4->packets);
4887           vat_json_object_add_uint (counter, "bytes", n4->bytes);
4888         }
4889     }
4890
4891   /* ip6 nbr counters */
4892   msg_array = vat_json_object_add (&node, "ip6_nbr_counters");
4893   vat_json_init_array (msg_array);
4894   for (i = 0; i < vec_len (vam->ip6_nbr_counters); i++)
4895     {
4896       msg = vat_json_array_add (msg_array);
4897       vat_json_init_object (msg);
4898       vat_json_object_add_uint (msg, "sw_if_index", i);
4899       counter_array = vat_json_object_add (msg, "c");
4900       vat_json_init_array (counter_array);
4901       for (j = 0; j < vec_len (vam->ip6_nbr_counters[i]); j++)
4902         {
4903           counter = vat_json_array_add (counter_array);
4904           vat_json_init_object (counter);
4905           n6 = &vam->ip6_nbr_counters[i][j];
4906           vat_json_object_add_ip6 (counter, "address", n6->address);
4907           vat_json_object_add_uint (counter, "packets", n6->packets);
4908           vat_json_object_add_uint (counter, "bytes", n6->bytes);
4909         }
4910     }
4911
4912   vat_json_print (vam->ofp, &node);
4913   vat_json_free (&node);
4914
4915   return 0;
4916 }
4917
4918 int
4919 exec (vat_main_t * vam)
4920 {
4921   api_main_t *am = &api_main;
4922   vl_api_cli_request_t *mp;
4923   f64 timeout;
4924   void *oldheap;
4925   u8 *cmd = 0;
4926   unformat_input_t *i = vam->input;
4927
4928   if (vec_len (i->buffer) == 0)
4929     return -1;
4930
4931   if (vam->exec_mode == 0 && unformat (i, "mode"))
4932     {
4933       vam->exec_mode = 1;
4934       return 0;
4935     }
4936   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4937     {
4938       vam->exec_mode = 0;
4939       return 0;
4940     }
4941
4942
4943   M (CLI_REQUEST, mp);
4944
4945   /*
4946    * Copy cmd into shared memory.
4947    * In order for the CLI command to work, it
4948    * must be a vector ending in \n, not a C-string ending
4949    * in \n\0.
4950    */
4951   pthread_mutex_lock (&am->vlib_rp->mutex);
4952   oldheap = svm_push_data_heap (am->vlib_rp);
4953
4954   vec_validate (cmd, vec_len (vam->input->buffer) - 1);
4955   clib_memcpy (cmd, vam->input->buffer, vec_len (vam->input->buffer));
4956
4957   svm_pop_heap (oldheap);
4958   pthread_mutex_unlock (&am->vlib_rp->mutex);
4959
4960   mp->cmd_in_shmem = (u64) cmd;
4961   S (mp);
4962   timeout = vat_time_now (vam) + 10.0;
4963
4964   while (vat_time_now (vam) < timeout)
4965     {
4966       if (vam->result_ready == 1)
4967         {
4968           u8 *free_me;
4969           if (vam->shmem_result != NULL)
4970             print (vam->ofp, "%s", vam->shmem_result);
4971           pthread_mutex_lock (&am->vlib_rp->mutex);
4972           oldheap = svm_push_data_heap (am->vlib_rp);
4973
4974           free_me = (u8 *) vam->shmem_result;
4975           vec_free (free_me);
4976
4977           svm_pop_heap (oldheap);
4978           pthread_mutex_unlock (&am->vlib_rp->mutex);
4979           return 0;
4980         }
4981     }
4982   return -99;
4983 }
4984
4985 /*
4986  * Future replacement of exec() that passes CLI buffers directly in
4987  * the API messages instead of an additional shared memory area.
4988  */
4989 static int
4990 exec_inband (vat_main_t * vam)
4991 {
4992   vl_api_cli_inband_t *mp;
4993   unformat_input_t *i = vam->input;
4994   int ret;
4995
4996   if (vec_len (i->buffer) == 0)
4997     return -1;
4998
4999   if (vam->exec_mode == 0 && unformat (i, "mode"))
5000     {
5001       vam->exec_mode = 1;
5002       return 0;
5003     }
5004   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
5005     {
5006       vam->exec_mode = 0;
5007       return 0;
5008     }
5009
5010   /*
5011    * In order for the CLI command to work, it
5012    * must be a vector ending in \n, not a C-string ending
5013    * in \n\0.
5014    */
5015   u32 len = vec_len (vam->input->buffer);
5016   M2 (CLI_INBAND, mp, len);
5017   clib_memcpy (mp->cmd, vam->input->buffer, len);
5018   mp->length = htonl (len);
5019
5020   S (mp);
5021   W2 (ret, print (vam->ofp, "%s", vam->cmd_reply));
5022   return ret;
5023 }
5024
5025 static int
5026 api_create_loopback (vat_main_t * vam)
5027 {
5028   unformat_input_t *i = vam->input;
5029   vl_api_create_loopback_t *mp;
5030   vl_api_create_loopback_instance_t *mp_lbi;
5031   u8 mac_address[6];
5032   u8 mac_set = 0;
5033   u8 is_specified = 0;
5034   u32 user_instance = 0;
5035   int ret;
5036
5037   memset (mac_address, 0, sizeof (mac_address));
5038
5039   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5040     {
5041       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5042         mac_set = 1;
5043       if (unformat (i, "instance %d", &user_instance))
5044         is_specified = 1;
5045       else
5046         break;
5047     }
5048
5049   if (is_specified)
5050     {
5051       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
5052       mp_lbi->is_specified = is_specified;
5053       if (is_specified)
5054         mp_lbi->user_instance = htonl (user_instance);
5055       if (mac_set)
5056         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
5057       S (mp_lbi);
5058     }
5059   else
5060     {
5061       /* Construct the API message */
5062       M (CREATE_LOOPBACK, mp);
5063       if (mac_set)
5064         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
5065       S (mp);
5066     }
5067
5068   W (ret);
5069   return ret;
5070 }
5071
5072 static int
5073 api_delete_loopback (vat_main_t * vam)
5074 {
5075   unformat_input_t *i = vam->input;
5076   vl_api_delete_loopback_t *mp;
5077   u32 sw_if_index = ~0;
5078   int ret;
5079
5080   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5081     {
5082       if (unformat (i, "sw_if_index %d", &sw_if_index))
5083         ;
5084       else
5085         break;
5086     }
5087
5088   if (sw_if_index == ~0)
5089     {
5090       errmsg ("missing sw_if_index");
5091       return -99;
5092     }
5093
5094   /* Construct the API message */
5095   M (DELETE_LOOPBACK, mp);
5096   mp->sw_if_index = ntohl (sw_if_index);
5097
5098   S (mp);
5099   W (ret);
5100   return ret;
5101 }
5102
5103 static int
5104 api_want_stats (vat_main_t * vam)
5105 {
5106   unformat_input_t *i = vam->input;
5107   vl_api_want_stats_t *mp;
5108   int enable = -1;
5109   int ret;
5110
5111   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5112     {
5113       if (unformat (i, "enable"))
5114         enable = 1;
5115       else if (unformat (i, "disable"))
5116         enable = 0;
5117       else
5118         break;
5119     }
5120
5121   if (enable == -1)
5122     {
5123       errmsg ("missing enable|disable");
5124       return -99;
5125     }
5126
5127   M (WANT_STATS, mp);
5128   mp->enable_disable = enable;
5129
5130   S (mp);
5131   W (ret);
5132   return ret;
5133 }
5134
5135 static int
5136 api_want_interface_events (vat_main_t * vam)
5137 {
5138   unformat_input_t *i = vam->input;
5139   vl_api_want_interface_events_t *mp;
5140   int enable = -1;
5141   int ret;
5142
5143   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5144     {
5145       if (unformat (i, "enable"))
5146         enable = 1;
5147       else if (unformat (i, "disable"))
5148         enable = 0;
5149       else
5150         break;
5151     }
5152
5153   if (enable == -1)
5154     {
5155       errmsg ("missing enable|disable");
5156       return -99;
5157     }
5158
5159   M (WANT_INTERFACE_EVENTS, mp);
5160   mp->enable_disable = enable;
5161
5162   vam->interface_event_display = enable;
5163
5164   S (mp);
5165   W (ret);
5166   return ret;
5167 }
5168
5169
5170 /* Note: non-static, called once to set up the initial intfc table */
5171 int
5172 api_sw_interface_dump (vat_main_t * vam)
5173 {
5174   vl_api_sw_interface_dump_t *mp;
5175   vl_api_control_ping_t *mp_ping;
5176   hash_pair_t *p;
5177   name_sort_t *nses = 0, *ns;
5178   sw_interface_subif_t *sub = NULL;
5179   int ret;
5180
5181   /* Toss the old name table */
5182   /* *INDENT-OFF* */
5183   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5184   ({
5185     vec_add2 (nses, ns, 1);
5186     ns->name = (u8 *)(p->key);
5187     ns->value = (u32) p->value[0];
5188   }));
5189   /* *INDENT-ON* */
5190
5191   hash_free (vam->sw_if_index_by_interface_name);
5192
5193   vec_foreach (ns, nses) vec_free (ns->name);
5194
5195   vec_free (nses);
5196
5197   vec_foreach (sub, vam->sw_if_subif_table)
5198   {
5199     vec_free (sub->interface_name);
5200   }
5201   vec_free (vam->sw_if_subif_table);
5202
5203   /* recreate the interface name hash table */
5204   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
5205
5206   /* Get list of ethernets */
5207   M (SW_INTERFACE_DUMP, mp);
5208   mp->name_filter_valid = 1;
5209   strncpy ((char *) mp->name_filter, "Ether", sizeof (mp->name_filter) - 1);
5210   S (mp);
5211
5212   /* and local / loopback interfaces */
5213   M (SW_INTERFACE_DUMP, mp);
5214   mp->name_filter_valid = 1;
5215   strncpy ((char *) mp->name_filter, "lo", sizeof (mp->name_filter) - 1);
5216   S (mp);
5217
5218   /* and packet-generator interfaces */
5219   M (SW_INTERFACE_DUMP, mp);
5220   mp->name_filter_valid = 1;
5221   strncpy ((char *) mp->name_filter, "pg", sizeof (mp->name_filter) - 1);
5222   S (mp);
5223
5224   /* and vxlan-gpe tunnel interfaces */
5225   M (SW_INTERFACE_DUMP, mp);
5226   mp->name_filter_valid = 1;
5227   strncpy ((char *) mp->name_filter, "vxlan_gpe",
5228            sizeof (mp->name_filter) - 1);
5229   S (mp);
5230
5231   /* and vxlan tunnel interfaces */
5232   M (SW_INTERFACE_DUMP, mp);
5233   mp->name_filter_valid = 1;
5234   strncpy ((char *) mp->name_filter, "vxlan", sizeof (mp->name_filter) - 1);
5235   S (mp);
5236
5237   /* and host (af_packet) interfaces */
5238   M (SW_INTERFACE_DUMP, mp);
5239   mp->name_filter_valid = 1;
5240   strncpy ((char *) mp->name_filter, "host", sizeof (mp->name_filter) - 1);
5241   S (mp);
5242
5243   /* and l2tpv3 tunnel interfaces */
5244   M (SW_INTERFACE_DUMP, mp);
5245   mp->name_filter_valid = 1;
5246   strncpy ((char *) mp->name_filter, "l2tpv3_tunnel",
5247            sizeof (mp->name_filter) - 1);
5248   S (mp);
5249
5250   /* and GRE tunnel interfaces */
5251   M (SW_INTERFACE_DUMP, mp);
5252   mp->name_filter_valid = 1;
5253   strncpy ((char *) mp->name_filter, "gre", sizeof (mp->name_filter) - 1);
5254   S (mp);
5255
5256   /* and LISP-GPE interfaces */
5257   M (SW_INTERFACE_DUMP, mp);
5258   mp->name_filter_valid = 1;
5259   strncpy ((char *) mp->name_filter, "lisp_gpe",
5260            sizeof (mp->name_filter) - 1);
5261   S (mp);
5262
5263   /* and IPSEC tunnel interfaces */
5264   M (SW_INTERFACE_DUMP, mp);
5265   mp->name_filter_valid = 1;
5266   strncpy ((char *) mp->name_filter, "ipsec", sizeof (mp->name_filter) - 1);
5267   S (mp);
5268
5269   /* Use a control ping for synchronization */
5270   M (CONTROL_PING, mp_ping);
5271   S (mp_ping);
5272
5273   W (ret);
5274   return ret;
5275 }
5276
5277 static int
5278 api_sw_interface_set_flags (vat_main_t * vam)
5279 {
5280   unformat_input_t *i = vam->input;
5281   vl_api_sw_interface_set_flags_t *mp;
5282   u32 sw_if_index;
5283   u8 sw_if_index_set = 0;
5284   u8 admin_up = 0, link_up = 0;
5285   int ret;
5286
5287   /* Parse args required to build the message */
5288   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5289     {
5290       if (unformat (i, "admin-up"))
5291         admin_up = 1;
5292       else if (unformat (i, "admin-down"))
5293         admin_up = 0;
5294       else if (unformat (i, "link-up"))
5295         link_up = 1;
5296       else if (unformat (i, "link-down"))
5297         link_up = 0;
5298       else
5299         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5300         sw_if_index_set = 1;
5301       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5302         sw_if_index_set = 1;
5303       else
5304         break;
5305     }
5306
5307   if (sw_if_index_set == 0)
5308     {
5309       errmsg ("missing interface name or sw_if_index");
5310       return -99;
5311     }
5312
5313   /* Construct the API message */
5314   M (SW_INTERFACE_SET_FLAGS, mp);
5315   mp->sw_if_index = ntohl (sw_if_index);
5316   mp->admin_up_down = admin_up;
5317   mp->link_up_down = link_up;
5318
5319   /* send it... */
5320   S (mp);
5321
5322   /* Wait for a reply, return the good/bad news... */
5323   W (ret);
5324   return ret;
5325 }
5326
5327 static int
5328 api_sw_interface_clear_stats (vat_main_t * vam)
5329 {
5330   unformat_input_t *i = vam->input;
5331   vl_api_sw_interface_clear_stats_t *mp;
5332   u32 sw_if_index;
5333   u8 sw_if_index_set = 0;
5334   int ret;
5335
5336   /* Parse args required to build the message */
5337   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5338     {
5339       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5340         sw_if_index_set = 1;
5341       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5342         sw_if_index_set = 1;
5343       else
5344         break;
5345     }
5346
5347   /* Construct the API message */
5348   M (SW_INTERFACE_CLEAR_STATS, mp);
5349
5350   if (sw_if_index_set == 1)
5351     mp->sw_if_index = ntohl (sw_if_index);
5352   else
5353     mp->sw_if_index = ~0;
5354
5355   /* send it... */
5356   S (mp);
5357
5358   /* Wait for a reply, return the good/bad news... */
5359   W (ret);
5360   return ret;
5361 }
5362
5363 static int
5364 api_sw_interface_add_del_address (vat_main_t * vam)
5365 {
5366   unformat_input_t *i = vam->input;
5367   vl_api_sw_interface_add_del_address_t *mp;
5368   u32 sw_if_index;
5369   u8 sw_if_index_set = 0;
5370   u8 is_add = 1, del_all = 0;
5371   u32 address_length = 0;
5372   u8 v4_address_set = 0;
5373   u8 v6_address_set = 0;
5374   ip4_address_t v4address;
5375   ip6_address_t v6address;
5376   int ret;
5377
5378   /* Parse args required to build the message */
5379   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5380     {
5381       if (unformat (i, "del-all"))
5382         del_all = 1;
5383       else if (unformat (i, "del"))
5384         is_add = 0;
5385       else
5386         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5387         sw_if_index_set = 1;
5388       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5389         sw_if_index_set = 1;
5390       else if (unformat (i, "%U/%d",
5391                          unformat_ip4_address, &v4address, &address_length))
5392         v4_address_set = 1;
5393       else if (unformat (i, "%U/%d",
5394                          unformat_ip6_address, &v6address, &address_length))
5395         v6_address_set = 1;
5396       else
5397         break;
5398     }
5399
5400   if (sw_if_index_set == 0)
5401     {
5402       errmsg ("missing interface name or sw_if_index");
5403       return -99;
5404     }
5405   if (v4_address_set && v6_address_set)
5406     {
5407       errmsg ("both v4 and v6 addresses set");
5408       return -99;
5409     }
5410   if (!v4_address_set && !v6_address_set && !del_all)
5411     {
5412       errmsg ("no addresses set");
5413       return -99;
5414     }
5415
5416   /* Construct the API message */
5417   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
5418
5419   mp->sw_if_index = ntohl (sw_if_index);
5420   mp->is_add = is_add;
5421   mp->del_all = del_all;
5422   if (v6_address_set)
5423     {
5424       mp->is_ipv6 = 1;
5425       clib_memcpy (mp->address, &v6address, sizeof (v6address));
5426     }
5427   else
5428     {
5429       clib_memcpy (mp->address, &v4address, sizeof (v4address));
5430     }
5431   mp->address_length = address_length;
5432
5433   /* send it... */
5434   S (mp);
5435
5436   /* Wait for a reply, return good/bad news  */
5437   W (ret);
5438   return ret;
5439 }
5440
5441 static int
5442 api_sw_interface_set_mpls_enable (vat_main_t * vam)
5443 {
5444   unformat_input_t *i = vam->input;
5445   vl_api_sw_interface_set_mpls_enable_t *mp;
5446   u32 sw_if_index;
5447   u8 sw_if_index_set = 0;
5448   u8 enable = 1;
5449   int ret;
5450
5451   /* Parse args required to build the message */
5452   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5453     {
5454       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5455         sw_if_index_set = 1;
5456       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5457         sw_if_index_set = 1;
5458       else if (unformat (i, "disable"))
5459         enable = 0;
5460       else if (unformat (i, "dis"))
5461         enable = 0;
5462       else
5463         break;
5464     }
5465
5466   if (sw_if_index_set == 0)
5467     {
5468       errmsg ("missing interface name or sw_if_index");
5469       return -99;
5470     }
5471
5472   /* Construct the API message */
5473   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
5474
5475   mp->sw_if_index = ntohl (sw_if_index);
5476   mp->enable = enable;
5477
5478   /* send it... */
5479   S (mp);
5480
5481   /* Wait for a reply... */
5482   W (ret);
5483   return ret;
5484 }
5485
5486 static int
5487 api_sw_interface_set_table (vat_main_t * vam)
5488 {
5489   unformat_input_t *i = vam->input;
5490   vl_api_sw_interface_set_table_t *mp;
5491   u32 sw_if_index, vrf_id = 0;
5492   u8 sw_if_index_set = 0;
5493   u8 is_ipv6 = 0;
5494   int ret;
5495
5496   /* Parse args required to build the message */
5497   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5498     {
5499       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5500         sw_if_index_set = 1;
5501       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5502         sw_if_index_set = 1;
5503       else if (unformat (i, "vrf %d", &vrf_id))
5504         ;
5505       else if (unformat (i, "ipv6"))
5506         is_ipv6 = 1;
5507       else
5508         break;
5509     }
5510
5511   if (sw_if_index_set == 0)
5512     {
5513       errmsg ("missing interface name or sw_if_index");
5514       return -99;
5515     }
5516
5517   /* Construct the API message */
5518   M (SW_INTERFACE_SET_TABLE, mp);
5519
5520   mp->sw_if_index = ntohl (sw_if_index);
5521   mp->is_ipv6 = is_ipv6;
5522   mp->vrf_id = ntohl (vrf_id);
5523
5524   /* send it... */
5525   S (mp);
5526
5527   /* Wait for a reply... */
5528   W (ret);
5529   return ret;
5530 }
5531
5532 static void vl_api_sw_interface_get_table_reply_t_handler
5533   (vl_api_sw_interface_get_table_reply_t * mp)
5534 {
5535   vat_main_t *vam = &vat_main;
5536
5537   print (vam->ofp, "%d", ntohl (mp->vrf_id));
5538
5539   vam->retval = ntohl (mp->retval);
5540   vam->result_ready = 1;
5541
5542 }
5543
5544 static void vl_api_sw_interface_get_table_reply_t_handler_json
5545   (vl_api_sw_interface_get_table_reply_t * mp)
5546 {
5547   vat_main_t *vam = &vat_main;
5548   vat_json_node_t node;
5549
5550   vat_json_init_object (&node);
5551   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
5552   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
5553
5554   vat_json_print (vam->ofp, &node);
5555   vat_json_free (&node);
5556
5557   vam->retval = ntohl (mp->retval);
5558   vam->result_ready = 1;
5559 }
5560
5561 static int
5562 api_sw_interface_get_table (vat_main_t * vam)
5563 {
5564   unformat_input_t *i = vam->input;
5565   vl_api_sw_interface_get_table_t *mp;
5566   u32 sw_if_index;
5567   u8 sw_if_index_set = 0;
5568   u8 is_ipv6 = 0;
5569   int ret;
5570
5571   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5572     {
5573       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5574         sw_if_index_set = 1;
5575       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5576         sw_if_index_set = 1;
5577       else if (unformat (i, "ipv6"))
5578         is_ipv6 = 1;
5579       else
5580         break;
5581     }
5582
5583   if (sw_if_index_set == 0)
5584     {
5585       errmsg ("missing interface name or sw_if_index");
5586       return -99;
5587     }
5588
5589   M (SW_INTERFACE_GET_TABLE, mp);
5590   mp->sw_if_index = htonl (sw_if_index);
5591   mp->is_ipv6 = is_ipv6;
5592
5593   S (mp);
5594   W (ret);
5595   return ret;
5596 }
5597
5598 static int
5599 api_sw_interface_set_vpath (vat_main_t * vam)
5600 {
5601   unformat_input_t *i = vam->input;
5602   vl_api_sw_interface_set_vpath_t *mp;
5603   u32 sw_if_index = 0;
5604   u8 sw_if_index_set = 0;
5605   u8 is_enable = 0;
5606   int ret;
5607
5608   /* Parse args required to build the message */
5609   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5610     {
5611       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5612         sw_if_index_set = 1;
5613       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5614         sw_if_index_set = 1;
5615       else if (unformat (i, "enable"))
5616         is_enable = 1;
5617       else if (unformat (i, "disable"))
5618         is_enable = 0;
5619       else
5620         break;
5621     }
5622
5623   if (sw_if_index_set == 0)
5624     {
5625       errmsg ("missing interface name or sw_if_index");
5626       return -99;
5627     }
5628
5629   /* Construct the API message */
5630   M (SW_INTERFACE_SET_VPATH, mp);
5631
5632   mp->sw_if_index = ntohl (sw_if_index);
5633   mp->enable = is_enable;
5634
5635   /* send it... */
5636   S (mp);
5637
5638   /* Wait for a reply... */
5639   W (ret);
5640   return ret;
5641 }
5642
5643 static int
5644 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
5645 {
5646   unformat_input_t *i = vam->input;
5647   vl_api_sw_interface_set_vxlan_bypass_t *mp;
5648   u32 sw_if_index = 0;
5649   u8 sw_if_index_set = 0;
5650   u8 is_enable = 1;
5651   u8 is_ipv6 = 0;
5652   int ret;
5653
5654   /* Parse args required to build the message */
5655   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5656     {
5657       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5658         sw_if_index_set = 1;
5659       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5660         sw_if_index_set = 1;
5661       else if (unformat (i, "enable"))
5662         is_enable = 1;
5663       else if (unformat (i, "disable"))
5664         is_enable = 0;
5665       else if (unformat (i, "ip4"))
5666         is_ipv6 = 0;
5667       else if (unformat (i, "ip6"))
5668         is_ipv6 = 1;
5669       else
5670         break;
5671     }
5672
5673   if (sw_if_index_set == 0)
5674     {
5675       errmsg ("missing interface name or sw_if_index");
5676       return -99;
5677     }
5678
5679   /* Construct the API message */
5680   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
5681
5682   mp->sw_if_index = ntohl (sw_if_index);
5683   mp->enable = is_enable;
5684   mp->is_ipv6 = is_ipv6;
5685
5686   /* send it... */
5687   S (mp);
5688
5689   /* Wait for a reply... */
5690   W (ret);
5691   return ret;
5692 }
5693
5694 static int
5695 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
5696 {
5697   unformat_input_t *i = vam->input;
5698   vl_api_sw_interface_set_l2_xconnect_t *mp;
5699   u32 rx_sw_if_index;
5700   u8 rx_sw_if_index_set = 0;
5701   u32 tx_sw_if_index;
5702   u8 tx_sw_if_index_set = 0;
5703   u8 enable = 1;
5704   int ret;
5705
5706   /* Parse args required to build the message */
5707   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5708     {
5709       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
5710         rx_sw_if_index_set = 1;
5711       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
5712         tx_sw_if_index_set = 1;
5713       else if (unformat (i, "rx"))
5714         {
5715           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5716             {
5717               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
5718                             &rx_sw_if_index))
5719                 rx_sw_if_index_set = 1;
5720             }
5721           else
5722             break;
5723         }
5724       else if (unformat (i, "tx"))
5725         {
5726           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5727             {
5728               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
5729                             &tx_sw_if_index))
5730                 tx_sw_if_index_set = 1;
5731             }
5732           else
5733             break;
5734         }
5735       else if (unformat (i, "enable"))
5736         enable = 1;
5737       else if (unformat (i, "disable"))
5738         enable = 0;
5739       else
5740         break;
5741     }
5742
5743   if (rx_sw_if_index_set == 0)
5744     {
5745       errmsg ("missing rx interface name or rx_sw_if_index");
5746       return -99;
5747     }
5748
5749   if (enable && (tx_sw_if_index_set == 0))
5750     {
5751       errmsg ("missing tx interface name or tx_sw_if_index");
5752       return -99;
5753     }
5754
5755   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
5756
5757   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
5758   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
5759   mp->enable = enable;
5760
5761   S (mp);
5762   W (ret);
5763   return ret;
5764 }
5765
5766 static int
5767 api_sw_interface_set_l2_bridge (vat_main_t * vam)
5768 {
5769   unformat_input_t *i = vam->input;
5770   vl_api_sw_interface_set_l2_bridge_t *mp;
5771   u32 rx_sw_if_index;
5772   u8 rx_sw_if_index_set = 0;
5773   u32 bd_id;
5774   u8 bd_id_set = 0;
5775   u8 bvi = 0;
5776   u32 shg = 0;
5777   u8 enable = 1;
5778   int ret;
5779
5780   /* Parse args required to build the message */
5781   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5782     {
5783       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
5784         rx_sw_if_index_set = 1;
5785       else if (unformat (i, "bd_id %d", &bd_id))
5786         bd_id_set = 1;
5787       else
5788         if (unformat
5789             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
5790         rx_sw_if_index_set = 1;
5791       else if (unformat (i, "shg %d", &shg))
5792         ;
5793       else if (unformat (i, "bvi"))
5794         bvi = 1;
5795       else if (unformat (i, "enable"))
5796         enable = 1;
5797       else if (unformat (i, "disable"))
5798         enable = 0;
5799       else
5800         break;
5801     }
5802
5803   if (rx_sw_if_index_set == 0)
5804     {
5805       errmsg ("missing rx interface name or sw_if_index");
5806       return -99;
5807     }
5808
5809   if (enable && (bd_id_set == 0))
5810     {
5811       errmsg ("missing bridge domain");
5812       return -99;
5813     }
5814
5815   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
5816
5817   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
5818   mp->bd_id = ntohl (bd_id);
5819   mp->shg = (u8) shg;
5820   mp->bvi = bvi;
5821   mp->enable = enable;
5822
5823   S (mp);
5824   W (ret);
5825   return ret;
5826 }
5827
5828 static int
5829 api_bridge_domain_dump (vat_main_t * vam)
5830 {
5831   unformat_input_t *i = vam->input;
5832   vl_api_bridge_domain_dump_t *mp;
5833   vl_api_control_ping_t *mp_ping;
5834   u32 bd_id = ~0;
5835   int ret;
5836
5837   /* Parse args required to build the message */
5838   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5839     {
5840       if (unformat (i, "bd_id %d", &bd_id))
5841         ;
5842       else
5843         break;
5844     }
5845
5846   M (BRIDGE_DOMAIN_DUMP, mp);
5847   mp->bd_id = ntohl (bd_id);
5848   S (mp);
5849
5850   /* Use a control ping for synchronization */
5851   M (CONTROL_PING, mp_ping);
5852   S (mp_ping);
5853
5854   W (ret);
5855   return ret;
5856 }
5857
5858 static int
5859 api_bridge_domain_add_del (vat_main_t * vam)
5860 {
5861   unformat_input_t *i = vam->input;
5862   vl_api_bridge_domain_add_del_t *mp;
5863   u32 bd_id = ~0;
5864   u8 is_add = 1;
5865   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
5866   u32 mac_age = 0;
5867   int ret;
5868
5869   /* Parse args required to build the message */
5870   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5871     {
5872       if (unformat (i, "bd_id %d", &bd_id))
5873         ;
5874       else if (unformat (i, "flood %d", &flood))
5875         ;
5876       else if (unformat (i, "uu-flood %d", &uu_flood))
5877         ;
5878       else if (unformat (i, "forward %d", &forward))
5879         ;
5880       else if (unformat (i, "learn %d", &learn))
5881         ;
5882       else if (unformat (i, "arp-term %d", &arp_term))
5883         ;
5884       else if (unformat (i, "mac-age %d", &mac_age))
5885         ;
5886       else if (unformat (i, "del"))
5887         {
5888           is_add = 0;
5889           flood = uu_flood = forward = learn = 0;
5890         }
5891       else
5892         break;
5893     }
5894
5895   if (bd_id == ~0)
5896     {
5897       errmsg ("missing bridge domain");
5898       return -99;
5899     }
5900
5901   if (mac_age > 255)
5902     {
5903       errmsg ("mac age must be less than 256 ");
5904       return -99;
5905     }
5906
5907   M (BRIDGE_DOMAIN_ADD_DEL, mp);
5908
5909   mp->bd_id = ntohl (bd_id);
5910   mp->flood = flood;
5911   mp->uu_flood = uu_flood;
5912   mp->forward = forward;
5913   mp->learn = learn;
5914   mp->arp_term = arp_term;
5915   mp->is_add = is_add;
5916   mp->mac_age = (u8) mac_age;
5917
5918   S (mp);
5919   W (ret);
5920   return ret;
5921 }
5922
5923 static int
5924 api_l2fib_flush_bd (vat_main_t * vam)
5925 {
5926   unformat_input_t *i = vam->input;
5927   vl_api_l2fib_flush_bd_t *mp;
5928   u32 bd_id = ~0;
5929   int ret;
5930
5931   /* Parse args required to build the message */
5932   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5933     {
5934       if (unformat (i, "bd_id %d", &bd_id));
5935       else
5936         break;
5937     }
5938
5939   if (bd_id == ~0)
5940     {
5941       errmsg ("missing bridge domain");
5942       return -99;
5943     }
5944
5945   M (L2FIB_FLUSH_BD, mp);
5946
5947   mp->bd_id = htonl (bd_id);
5948
5949   S (mp);
5950   W (ret);
5951   return ret;
5952 }
5953
5954 static int
5955 api_l2fib_flush_int (vat_main_t * vam)
5956 {
5957   unformat_input_t *i = vam->input;
5958   vl_api_l2fib_flush_int_t *mp;
5959   u32 sw_if_index = ~0;
5960   int ret;
5961
5962   /* Parse args required to build the message */
5963   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5964     {
5965       if (unformat (i, "sw_if_index %d", &sw_if_index));
5966       else
5967         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
5968       else
5969         break;
5970     }
5971
5972   if (sw_if_index == ~0)
5973     {
5974       errmsg ("missing interface name or sw_if_index");
5975       return -99;
5976     }
5977
5978   M (L2FIB_FLUSH_INT, mp);
5979
5980   mp->sw_if_index = ntohl (sw_if_index);
5981
5982   S (mp);
5983   W (ret);
5984   return ret;
5985 }
5986
5987 static int
5988 api_l2fib_add_del (vat_main_t * vam)
5989 {
5990   unformat_input_t *i = vam->input;
5991   vl_api_l2fib_add_del_t *mp;
5992   f64 timeout;
5993   u64 mac = 0;
5994   u8 mac_set = 0;
5995   u32 bd_id;
5996   u8 bd_id_set = 0;
5997   u32 sw_if_index = ~0;
5998   u8 sw_if_index_set = 0;
5999   u8 is_add = 1;
6000   u8 static_mac = 0;
6001   u8 filter_mac = 0;
6002   u8 bvi_mac = 0;
6003   int count = 1;
6004   f64 before = 0;
6005   int j;
6006
6007   /* Parse args required to build the message */
6008   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6009     {
6010       if (unformat (i, "mac %U", unformat_ethernet_address, &mac))
6011         mac_set = 1;
6012       else if (unformat (i, "bd_id %d", &bd_id))
6013         bd_id_set = 1;
6014       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6015         sw_if_index_set = 1;
6016       else if (unformat (i, "sw_if"))
6017         {
6018           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6019             {
6020               if (unformat
6021                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6022                 sw_if_index_set = 1;
6023             }
6024           else
6025             break;
6026         }
6027       else if (unformat (i, "static"))
6028         static_mac = 1;
6029       else if (unformat (i, "filter"))
6030         {
6031           filter_mac = 1;
6032           static_mac = 1;
6033         }
6034       else if (unformat (i, "bvi"))
6035         {
6036           bvi_mac = 1;
6037           static_mac = 1;
6038         }
6039       else if (unformat (i, "del"))
6040         is_add = 0;
6041       else if (unformat (i, "count %d", &count))
6042         ;
6043       else
6044         break;
6045     }
6046
6047   if (mac_set == 0)
6048     {
6049       errmsg ("missing mac address");
6050       return -99;
6051     }
6052
6053   if (bd_id_set == 0)
6054     {
6055       errmsg ("missing bridge domain");
6056       return -99;
6057     }
6058
6059   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
6060     {
6061       errmsg ("missing interface name or sw_if_index");
6062       return -99;
6063     }
6064
6065   if (count > 1)
6066     {
6067       /* Turn on async mode */
6068       vam->async_mode = 1;
6069       vam->async_errors = 0;
6070       before = vat_time_now (vam);
6071     }
6072
6073   for (j = 0; j < count; j++)
6074     {
6075       M (L2FIB_ADD_DEL, mp);
6076
6077       mp->mac = mac;
6078       mp->bd_id = ntohl (bd_id);
6079       mp->is_add = is_add;
6080
6081       if (is_add)
6082         {
6083           mp->sw_if_index = ntohl (sw_if_index);
6084           mp->static_mac = static_mac;
6085           mp->filter_mac = filter_mac;
6086           mp->bvi_mac = bvi_mac;
6087         }
6088       increment_mac_address (&mac);
6089       /* send it... */
6090       S (mp);
6091     }
6092
6093   if (count > 1)
6094     {
6095       vl_api_control_ping_t *mp_ping;
6096       f64 after;
6097
6098       /* Shut off async mode */
6099       vam->async_mode = 0;
6100
6101       M (CONTROL_PING, mp_ping);
6102       S (mp_ping);
6103
6104       timeout = vat_time_now (vam) + 1.0;
6105       while (vat_time_now (vam) < timeout)
6106         if (vam->result_ready == 1)
6107           goto out;
6108       vam->retval = -99;
6109
6110     out:
6111       if (vam->retval == -99)
6112         errmsg ("timeout");
6113
6114       if (vam->async_errors > 0)
6115         {
6116           errmsg ("%d asynchronous errors", vam->async_errors);
6117           vam->retval = -98;
6118         }
6119       vam->async_errors = 0;
6120       after = vat_time_now (vam);
6121
6122       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6123              count, after - before, count / (after - before));
6124     }
6125   else
6126     {
6127       int ret;
6128
6129       /* Wait for a reply... */
6130       W (ret);
6131       return ret;
6132     }
6133   /* Return the good/bad news */
6134   return (vam->retval);
6135 }
6136
6137 static int
6138 api_bridge_domain_set_mac_age (vat_main_t * vam)
6139 {
6140   unformat_input_t *i = vam->input;
6141   vl_api_bridge_domain_set_mac_age_t *mp;
6142   u32 bd_id = ~0;
6143   u32 mac_age = 0;
6144   int ret;
6145
6146   /* Parse args required to build the message */
6147   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6148     {
6149       if (unformat (i, "bd_id %d", &bd_id));
6150       else if (unformat (i, "mac-age %d", &mac_age));
6151       else
6152         break;
6153     }
6154
6155   if (bd_id == ~0)
6156     {
6157       errmsg ("missing bridge domain");
6158       return -99;
6159     }
6160
6161   if (mac_age > 255)
6162     {
6163       errmsg ("mac age must be less than 256 ");
6164       return -99;
6165     }
6166
6167   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
6168
6169   mp->bd_id = htonl (bd_id);
6170   mp->mac_age = (u8) mac_age;
6171
6172   S (mp);
6173   W (ret);
6174   return ret;
6175 }
6176
6177 static int
6178 api_l2_flags (vat_main_t * vam)
6179 {
6180   unformat_input_t *i = vam->input;
6181   vl_api_l2_flags_t *mp;
6182   u32 sw_if_index;
6183   u32 feature_bitmap = 0;
6184   u8 sw_if_index_set = 0;
6185   int ret;
6186
6187   /* Parse args required to build the message */
6188   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6189     {
6190       if (unformat (i, "sw_if_index %d", &sw_if_index))
6191         sw_if_index_set = 1;
6192       else if (unformat (i, "sw_if"))
6193         {
6194           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6195             {
6196               if (unformat
6197                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6198                 sw_if_index_set = 1;
6199             }
6200           else
6201             break;
6202         }
6203       else if (unformat (i, "learn"))
6204         feature_bitmap |= L2INPUT_FEAT_LEARN;
6205       else if (unformat (i, "forward"))
6206         feature_bitmap |= L2INPUT_FEAT_FWD;
6207       else if (unformat (i, "flood"))
6208         feature_bitmap |= L2INPUT_FEAT_FLOOD;
6209       else if (unformat (i, "uu-flood"))
6210         feature_bitmap |= L2INPUT_FEAT_UU_FLOOD;
6211       else
6212         break;
6213     }
6214
6215   if (sw_if_index_set == 0)
6216     {
6217       errmsg ("missing interface name or sw_if_index");
6218       return -99;
6219     }
6220
6221   M (L2_FLAGS, mp);
6222
6223   mp->sw_if_index = ntohl (sw_if_index);
6224   mp->feature_bitmap = ntohl (feature_bitmap);
6225
6226   S (mp);
6227   W (ret);
6228   return ret;
6229 }
6230
6231 static int
6232 api_bridge_flags (vat_main_t * vam)
6233 {
6234   unformat_input_t *i = vam->input;
6235   vl_api_bridge_flags_t *mp;
6236   u32 bd_id;
6237   u8 bd_id_set = 0;
6238   u8 is_set = 1;
6239   u32 flags = 0;
6240   int ret;
6241
6242   /* Parse args required to build the message */
6243   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6244     {
6245       if (unformat (i, "bd_id %d", &bd_id))
6246         bd_id_set = 1;
6247       else if (unformat (i, "learn"))
6248         flags |= L2_LEARN;
6249       else if (unformat (i, "forward"))
6250         flags |= L2_FWD;
6251       else if (unformat (i, "flood"))
6252         flags |= L2_FLOOD;
6253       else if (unformat (i, "uu-flood"))
6254         flags |= L2_UU_FLOOD;
6255       else if (unformat (i, "arp-term"))
6256         flags |= L2_ARP_TERM;
6257       else if (unformat (i, "off"))
6258         is_set = 0;
6259       else if (unformat (i, "disable"))
6260         is_set = 0;
6261       else
6262         break;
6263     }
6264
6265   if (bd_id_set == 0)
6266     {
6267       errmsg ("missing bridge domain");
6268       return -99;
6269     }
6270
6271   M (BRIDGE_FLAGS, mp);
6272
6273   mp->bd_id = ntohl (bd_id);
6274   mp->feature_bitmap = ntohl (flags);
6275   mp->is_set = is_set;
6276
6277   S (mp);
6278   W (ret);
6279   return ret;
6280 }
6281
6282 static int
6283 api_bd_ip_mac_add_del (vat_main_t * vam)
6284 {
6285   unformat_input_t *i = vam->input;
6286   vl_api_bd_ip_mac_add_del_t *mp;
6287   u32 bd_id;
6288   u8 is_ipv6 = 0;
6289   u8 is_add = 1;
6290   u8 bd_id_set = 0;
6291   u8 ip_set = 0;
6292   u8 mac_set = 0;
6293   ip4_address_t v4addr;
6294   ip6_address_t v6addr;
6295   u8 macaddr[6];
6296   int ret;
6297
6298
6299   /* Parse args required to build the message */
6300   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6301     {
6302       if (unformat (i, "bd_id %d", &bd_id))
6303         {
6304           bd_id_set++;
6305         }
6306       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
6307         {
6308           ip_set++;
6309         }
6310       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
6311         {
6312           ip_set++;
6313           is_ipv6++;
6314         }
6315       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
6316         {
6317           mac_set++;
6318         }
6319       else if (unformat (i, "del"))
6320         is_add = 0;
6321       else
6322         break;
6323     }
6324
6325   if (bd_id_set == 0)
6326     {
6327       errmsg ("missing bridge domain");
6328       return -99;
6329     }
6330   else if (ip_set == 0)
6331     {
6332       errmsg ("missing IP address");
6333       return -99;
6334     }
6335   else if (mac_set == 0)
6336     {
6337       errmsg ("missing MAC address");
6338       return -99;
6339     }
6340
6341   M (BD_IP_MAC_ADD_DEL, mp);
6342
6343   mp->bd_id = ntohl (bd_id);
6344   mp->is_ipv6 = is_ipv6;
6345   mp->is_add = is_add;
6346   if (is_ipv6)
6347     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
6348   else
6349     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
6350   clib_memcpy (mp->mac_address, macaddr, 6);
6351   S (mp);
6352   W (ret);
6353   return ret;
6354 }
6355
6356 static int
6357 api_tap_connect (vat_main_t * vam)
6358 {
6359   unformat_input_t *i = vam->input;
6360   vl_api_tap_connect_t *mp;
6361   u8 mac_address[6];
6362   u8 random_mac = 1;
6363   u8 name_set = 0;
6364   u8 *tap_name;
6365   u8 *tag = 0;
6366   ip4_address_t ip4_address;
6367   u32 ip4_mask_width;
6368   int ip4_address_set = 0;
6369   ip6_address_t ip6_address;
6370   u32 ip6_mask_width;
6371   int ip6_address_set = 0;
6372   int ret;
6373
6374   memset (mac_address, 0, sizeof (mac_address));
6375
6376   /* Parse args required to build the message */
6377   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6378     {
6379       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6380         {
6381           random_mac = 0;
6382         }
6383       else if (unformat (i, "random-mac"))
6384         random_mac = 1;
6385       else if (unformat (i, "tapname %s", &tap_name))
6386         name_set = 1;
6387       else if (unformat (i, "tag %s", &tag))
6388         ;
6389       else if (unformat (i, "address %U/%d",
6390                          unformat_ip4_address, &ip4_address, &ip4_mask_width))
6391         ip4_address_set = 1;
6392       else if (unformat (i, "address %U/%d",
6393                          unformat_ip6_address, &ip6_address, &ip6_mask_width))
6394         ip6_address_set = 1;
6395       else
6396         break;
6397     }
6398
6399   if (name_set == 0)
6400     {
6401       errmsg ("missing tap name");
6402       return -99;
6403     }
6404   if (vec_len (tap_name) > 63)
6405     {
6406       errmsg ("tap name too long");
6407       return -99;
6408     }
6409   vec_add1 (tap_name, 0);
6410
6411   if (vec_len (tag) > 63)
6412     {
6413       errmsg ("tag too long");
6414       return -99;
6415     }
6416
6417   /* Construct the API message */
6418   M (TAP_CONNECT, mp);
6419
6420   mp->use_random_mac = random_mac;
6421   clib_memcpy (mp->mac_address, mac_address, 6);
6422   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
6423   if (tag)
6424     clib_memcpy (mp->tag, tag, vec_len (tag));
6425
6426   if (ip4_address_set)
6427     {
6428       mp->ip4_address_set = 1;
6429       clib_memcpy (mp->ip4_address, &ip4_address, sizeof (mp->ip4_address));
6430       mp->ip4_mask_width = ip4_mask_width;
6431     }
6432   if (ip6_address_set)
6433     {
6434       mp->ip6_address_set = 1;
6435       clib_memcpy (mp->ip6_address, &ip6_address, sizeof (mp->ip6_address));
6436       mp->ip6_mask_width = ip6_mask_width;
6437     }
6438
6439   vec_free (tap_name);
6440   vec_free (tag);
6441
6442   /* send it... */
6443   S (mp);
6444
6445   /* Wait for a reply... */
6446   W (ret);
6447   return ret;
6448 }
6449
6450 static int
6451 api_tap_modify (vat_main_t * vam)
6452 {
6453   unformat_input_t *i = vam->input;
6454   vl_api_tap_modify_t *mp;
6455   u8 mac_address[6];
6456   u8 random_mac = 1;
6457   u8 name_set = 0;
6458   u8 *tap_name;
6459   u32 sw_if_index = ~0;
6460   u8 sw_if_index_set = 0;
6461   int ret;
6462
6463   memset (mac_address, 0, sizeof (mac_address));
6464
6465   /* Parse args required to build the message */
6466   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6467     {
6468       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6469         sw_if_index_set = 1;
6470       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6471         sw_if_index_set = 1;
6472       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6473         {
6474           random_mac = 0;
6475         }
6476       else if (unformat (i, "random-mac"))
6477         random_mac = 1;
6478       else if (unformat (i, "tapname %s", &tap_name))
6479         name_set = 1;
6480       else
6481         break;
6482     }
6483
6484   if (sw_if_index_set == 0)
6485     {
6486       errmsg ("missing vpp interface name");
6487       return -99;
6488     }
6489   if (name_set == 0)
6490     {
6491       errmsg ("missing tap name");
6492       return -99;
6493     }
6494   if (vec_len (tap_name) > 63)
6495     {
6496       errmsg ("tap name too long");
6497     }
6498   vec_add1 (tap_name, 0);
6499
6500   /* Construct the API message */
6501   M (TAP_MODIFY, mp);
6502
6503   mp->use_random_mac = random_mac;
6504   mp->sw_if_index = ntohl (sw_if_index);
6505   clib_memcpy (mp->mac_address, mac_address, 6);
6506   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
6507   vec_free (tap_name);
6508
6509   /* send it... */
6510   S (mp);
6511
6512   /* Wait for a reply... */
6513   W (ret);
6514   return ret;
6515 }
6516
6517 static int
6518 api_tap_delete (vat_main_t * vam)
6519 {
6520   unformat_input_t *i = vam->input;
6521   vl_api_tap_delete_t *mp;
6522   u32 sw_if_index = ~0;
6523   u8 sw_if_index_set = 0;
6524   int ret;
6525
6526   /* Parse args required to build the message */
6527   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6528     {
6529       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6530         sw_if_index_set = 1;
6531       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6532         sw_if_index_set = 1;
6533       else
6534         break;
6535     }
6536
6537   if (sw_if_index_set == 0)
6538     {
6539       errmsg ("missing vpp interface name");
6540       return -99;
6541     }
6542
6543   /* Construct the API message */
6544   M (TAP_DELETE, mp);
6545
6546   mp->sw_if_index = ntohl (sw_if_index);
6547
6548   /* send it... */
6549   S (mp);
6550
6551   /* Wait for a reply... */
6552   W (ret);
6553   return ret;
6554 }
6555
6556 static int
6557 api_ip_add_del_route (vat_main_t * vam)
6558 {
6559   unformat_input_t *i = vam->input;
6560   vl_api_ip_add_del_route_t *mp;
6561   u32 sw_if_index = ~0, vrf_id = 0;
6562   u8 is_ipv6 = 0;
6563   u8 is_local = 0, is_drop = 0;
6564   u8 is_unreach = 0, is_prohibit = 0;
6565   u8 create_vrf_if_needed = 0;
6566   u8 is_add = 1;
6567   u32 next_hop_weight = 1;
6568   u8 not_last = 0;
6569   u8 is_multipath = 0;
6570   u8 address_set = 0;
6571   u8 address_length_set = 0;
6572   u32 next_hop_table_id = 0;
6573   u32 resolve_attempts = 0;
6574   u32 dst_address_length = 0;
6575   u8 next_hop_set = 0;
6576   ip4_address_t v4_dst_address, v4_next_hop_address;
6577   ip6_address_t v6_dst_address, v6_next_hop_address;
6578   int count = 1;
6579   int j;
6580   f64 before = 0;
6581   u32 random_add_del = 0;
6582   u32 *random_vector = 0;
6583   uword *random_hash;
6584   u32 random_seed = 0xdeaddabe;
6585   u32 classify_table_index = ~0;
6586   u8 is_classify = 0;
6587   u8 resolve_host = 0, resolve_attached = 0;
6588   mpls_label_t *next_hop_out_label_stack = NULL;
6589   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
6590   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
6591
6592   /* Parse args required to build the message */
6593   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6594     {
6595       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6596         ;
6597       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6598         ;
6599       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
6600         {
6601           address_set = 1;
6602           is_ipv6 = 0;
6603         }
6604       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
6605         {
6606           address_set = 1;
6607           is_ipv6 = 1;
6608         }
6609       else if (unformat (i, "/%d", &dst_address_length))
6610         {
6611           address_length_set = 1;
6612         }
6613
6614       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
6615                                          &v4_next_hop_address))
6616         {
6617           next_hop_set = 1;
6618         }
6619       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
6620                                          &v6_next_hop_address))
6621         {
6622           next_hop_set = 1;
6623         }
6624       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
6625         ;
6626       else if (unformat (i, "weight %d", &next_hop_weight))
6627         ;
6628       else if (unformat (i, "drop"))
6629         {
6630           is_drop = 1;
6631         }
6632       else if (unformat (i, "null-send-unreach"))
6633         {
6634           is_unreach = 1;
6635         }
6636       else if (unformat (i, "null-send-prohibit"))
6637         {
6638           is_prohibit = 1;
6639         }
6640       else if (unformat (i, "local"))
6641         {
6642           is_local = 1;
6643         }
6644       else if (unformat (i, "classify %d", &classify_table_index))
6645         {
6646           is_classify = 1;
6647         }
6648       else if (unformat (i, "del"))
6649         is_add = 0;
6650       else if (unformat (i, "add"))
6651         is_add = 1;
6652       else if (unformat (i, "not-last"))
6653         not_last = 1;
6654       else if (unformat (i, "resolve-via-host"))
6655         resolve_host = 1;
6656       else if (unformat (i, "resolve-via-attached"))
6657         resolve_attached = 1;
6658       else if (unformat (i, "multipath"))
6659         is_multipath = 1;
6660       else if (unformat (i, "vrf %d", &vrf_id))
6661         ;
6662       else if (unformat (i, "create-vrf"))
6663         create_vrf_if_needed = 1;
6664       else if (unformat (i, "count %d", &count))
6665         ;
6666       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
6667         ;
6668       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
6669         ;
6670       else if (unformat (i, "out-label %d", &next_hop_out_label))
6671         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
6672       else if (unformat (i, "via-label %d", &next_hop_via_label))
6673         ;
6674       else if (unformat (i, "random"))
6675         random_add_del = 1;
6676       else if (unformat (i, "seed %d", &random_seed))
6677         ;
6678       else
6679         {
6680           clib_warning ("parse error '%U'", format_unformat_error, i);
6681           return -99;
6682         }
6683     }
6684
6685   if (!next_hop_set && !is_drop && !is_local &&
6686       !is_classify && !is_unreach && !is_prohibit &&
6687       MPLS_LABEL_INVALID == next_hop_via_label)
6688     {
6689       errmsg
6690         ("next hop / local / drop / unreach / prohibit / classify not set");
6691       return -99;
6692     }
6693
6694   if (next_hop_set && MPLS_LABEL_INVALID != next_hop_via_label)
6695     {
6696       errmsg ("next hop and next-hop via label set");
6697       return -99;
6698     }
6699   if (address_set == 0)
6700     {
6701       errmsg ("missing addresses");
6702       return -99;
6703     }
6704
6705   if (address_length_set == 0)
6706     {
6707       errmsg ("missing address length");
6708       return -99;
6709     }
6710
6711   /* Generate a pile of unique, random routes */
6712   if (random_add_del)
6713     {
6714       u32 this_random_address;
6715       random_hash = hash_create (count, sizeof (uword));
6716
6717       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
6718       for (j = 0; j <= count; j++)
6719         {
6720           do
6721             {
6722               this_random_address = random_u32 (&random_seed);
6723               this_random_address =
6724                 clib_host_to_net_u32 (this_random_address);
6725             }
6726           while (hash_get (random_hash, this_random_address));
6727           vec_add1 (random_vector, this_random_address);
6728           hash_set (random_hash, this_random_address, 1);
6729         }
6730       hash_free (random_hash);
6731       v4_dst_address.as_u32 = random_vector[0];
6732     }
6733
6734   if (count > 1)
6735     {
6736       /* Turn on async mode */
6737       vam->async_mode = 1;
6738       vam->async_errors = 0;
6739       before = vat_time_now (vam);
6740     }
6741
6742   for (j = 0; j < count; j++)
6743     {
6744       /* Construct the API message */
6745       M2 (IP_ADD_DEL_ROUTE, mp,
6746           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
6747
6748       mp->next_hop_sw_if_index = ntohl (sw_if_index);
6749       mp->table_id = ntohl (vrf_id);
6750       mp->create_vrf_if_needed = create_vrf_if_needed;
6751
6752       mp->is_add = is_add;
6753       mp->is_drop = is_drop;
6754       mp->is_unreach = is_unreach;
6755       mp->is_prohibit = is_prohibit;
6756       mp->is_ipv6 = is_ipv6;
6757       mp->is_local = is_local;
6758       mp->is_classify = is_classify;
6759       mp->is_multipath = is_multipath;
6760       mp->is_resolve_host = resolve_host;
6761       mp->is_resolve_attached = resolve_attached;
6762       mp->not_last = not_last;
6763       mp->next_hop_weight = next_hop_weight;
6764       mp->dst_address_length = dst_address_length;
6765       mp->next_hop_table_id = ntohl (next_hop_table_id);
6766       mp->classify_table_index = ntohl (classify_table_index);
6767       mp->next_hop_via_label = ntohl (next_hop_via_label);
6768       mp->next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
6769       if (0 != mp->next_hop_n_out_labels)
6770         {
6771           memcpy (mp->next_hop_out_label_stack,
6772                   next_hop_out_label_stack,
6773                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
6774           vec_free (next_hop_out_label_stack);
6775         }
6776
6777       if (is_ipv6)
6778         {
6779           clib_memcpy (mp->dst_address, &v6_dst_address,
6780                        sizeof (v6_dst_address));
6781           if (next_hop_set)
6782             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
6783                          sizeof (v6_next_hop_address));
6784           increment_v6_address (&v6_dst_address);
6785         }
6786       else
6787         {
6788           clib_memcpy (mp->dst_address, &v4_dst_address,
6789                        sizeof (v4_dst_address));
6790           if (next_hop_set)
6791             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
6792                          sizeof (v4_next_hop_address));
6793           if (random_add_del)
6794             v4_dst_address.as_u32 = random_vector[j + 1];
6795           else
6796             increment_v4_address (&v4_dst_address);
6797         }
6798       /* send it... */
6799       S (mp);
6800       /* If we receive SIGTERM, stop now... */
6801       if (vam->do_exit)
6802         break;
6803     }
6804
6805   /* When testing multiple add/del ops, use a control-ping to sync */
6806   if (count > 1)
6807     {
6808       vl_api_control_ping_t *mp_ping;
6809       f64 after;
6810       f64 timeout;
6811
6812       /* Shut off async mode */
6813       vam->async_mode = 0;
6814
6815       M (CONTROL_PING, mp_ping);
6816       S (mp_ping);
6817
6818       timeout = vat_time_now (vam) + 1.0;
6819       while (vat_time_now (vam) < timeout)
6820         if (vam->result_ready == 1)
6821           goto out;
6822       vam->retval = -99;
6823
6824     out:
6825       if (vam->retval == -99)
6826         errmsg ("timeout");
6827
6828       if (vam->async_errors > 0)
6829         {
6830           errmsg ("%d asynchronous errors", vam->async_errors);
6831           vam->retval = -98;
6832         }
6833       vam->async_errors = 0;
6834       after = vat_time_now (vam);
6835
6836       /* slim chance, but we might have eaten SIGTERM on the first iteration */
6837       if (j > 0)
6838         count = j;
6839
6840       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6841              count, after - before, count / (after - before));
6842     }
6843   else
6844     {
6845       int ret;
6846
6847       /* Wait for a reply... */
6848       W (ret);
6849       return ret;
6850     }
6851
6852   /* Return the good/bad news */
6853   return (vam->retval);
6854 }
6855
6856 static int
6857 api_ip_mroute_add_del (vat_main_t * vam)
6858 {
6859   unformat_input_t *i = vam->input;
6860   vl_api_ip_mroute_add_del_t *mp;
6861   u32 sw_if_index = ~0, vrf_id = 0;
6862   u8 is_ipv6 = 0;
6863   u8 is_local = 0;
6864   u8 create_vrf_if_needed = 0;
6865   u8 is_add = 1;
6866   u8 address_set = 0;
6867   u32 grp_address_length = 0;
6868   ip4_address_t v4_grp_address, v4_src_address;
6869   ip6_address_t v6_grp_address, v6_src_address;
6870   mfib_itf_flags_t iflags = 0;
6871   mfib_entry_flags_t eflags = 0;
6872   int ret;
6873
6874   /* Parse args required to build the message */
6875   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6876     {
6877       if (unformat (i, "sw_if_index %d", &sw_if_index))
6878         ;
6879       else if (unformat (i, "%U %U",
6880                          unformat_ip4_address, &v4_src_address,
6881                          unformat_ip4_address, &v4_grp_address))
6882         {
6883           grp_address_length = 64;
6884           address_set = 1;
6885           is_ipv6 = 0;
6886         }
6887       else if (unformat (i, "%U %U",
6888                          unformat_ip6_address, &v6_src_address,
6889                          unformat_ip6_address, &v6_grp_address))
6890         {
6891           grp_address_length = 256;
6892           address_set = 1;
6893           is_ipv6 = 1;
6894         }
6895       else if (unformat (i, "%U", unformat_ip4_address, &v4_grp_address))
6896         {
6897           memset (&v4_src_address, 0, sizeof (v4_src_address));
6898           grp_address_length = 32;
6899           address_set = 1;
6900           is_ipv6 = 0;
6901         }
6902       else if (unformat (i, "%U", unformat_ip6_address, &v6_grp_address))
6903         {
6904           memset (&v6_src_address, 0, sizeof (v6_src_address));
6905           grp_address_length = 128;
6906           address_set = 1;
6907           is_ipv6 = 1;
6908         }
6909       else if (unformat (i, "/%d", &grp_address_length))
6910         ;
6911       else if (unformat (i, "local"))
6912         {
6913           is_local = 1;
6914         }
6915       else if (unformat (i, "del"))
6916         is_add = 0;
6917       else if (unformat (i, "add"))
6918         is_add = 1;
6919       else if (unformat (i, "vrf %d", &vrf_id))
6920         ;
6921       else if (unformat (i, "create-vrf"))
6922         create_vrf_if_needed = 1;
6923       else if (unformat (i, "%U", unformat_mfib_itf_flags, &iflags))
6924         ;
6925       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
6926         ;
6927       else
6928         {
6929           clib_warning ("parse error '%U'", format_unformat_error, i);
6930           return -99;
6931         }
6932     }
6933
6934   if (address_set == 0)
6935     {
6936       errmsg ("missing addresses\n");
6937       return -99;
6938     }
6939
6940   /* Construct the API message */
6941   M (IP_MROUTE_ADD_DEL, mp);
6942
6943   mp->next_hop_sw_if_index = ntohl (sw_if_index);
6944   mp->table_id = ntohl (vrf_id);
6945   mp->create_vrf_if_needed = create_vrf_if_needed;
6946
6947   mp->is_add = is_add;
6948   mp->is_ipv6 = is_ipv6;
6949   mp->is_local = is_local;
6950   mp->itf_flags = ntohl (iflags);
6951   mp->entry_flags = ntohl (eflags);
6952   mp->grp_address_length = grp_address_length;
6953   mp->grp_address_length = ntohs (mp->grp_address_length);
6954
6955   if (is_ipv6)
6956     {
6957       clib_memcpy (mp->grp_address, &v6_grp_address, sizeof (v6_grp_address));
6958       clib_memcpy (mp->src_address, &v6_src_address, sizeof (v6_src_address));
6959     }
6960   else
6961     {
6962       clib_memcpy (mp->grp_address, &v4_grp_address, sizeof (v4_grp_address));
6963       clib_memcpy (mp->src_address, &v4_src_address, sizeof (v4_src_address));
6964
6965     }
6966
6967   /* send it... */
6968   S (mp);
6969   /* Wait for a reply... */
6970   W (ret);
6971   return ret;
6972 }
6973
6974 static int
6975 api_mpls_route_add_del (vat_main_t * vam)
6976 {
6977   unformat_input_t *i = vam->input;
6978   vl_api_mpls_route_add_del_t *mp;
6979   u32 sw_if_index = ~0, table_id = 0;
6980   u8 create_table_if_needed = 0;
6981   u8 is_add = 1;
6982   u32 next_hop_weight = 1;
6983   u8 is_multipath = 0;
6984   u32 next_hop_table_id = 0;
6985   u8 next_hop_set = 0;
6986   ip4_address_t v4_next_hop_address = {
6987     .as_u32 = 0,
6988   };
6989   ip6_address_t v6_next_hop_address = { {0} };
6990   int count = 1;
6991   int j;
6992   f64 before = 0;
6993   u32 classify_table_index = ~0;
6994   u8 is_classify = 0;
6995   u8 resolve_host = 0, resolve_attached = 0;
6996   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
6997   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
6998   mpls_label_t *next_hop_out_label_stack = NULL;
6999   mpls_label_t local_label = MPLS_LABEL_INVALID;
7000   u8 is_eos = 0;
7001   u8 next_hop_proto_is_ip4 = 1;
7002
7003   /* Parse args required to build the message */
7004   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7005     {
7006       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7007         ;
7008       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7009         ;
7010       else if (unformat (i, "%d", &local_label))
7011         ;
7012       else if (unformat (i, "eos"))
7013         is_eos = 1;
7014       else if (unformat (i, "non-eos"))
7015         is_eos = 0;
7016       else if (unformat (i, "via %U", unformat_ip4_address,
7017                          &v4_next_hop_address))
7018         {
7019           next_hop_set = 1;
7020           next_hop_proto_is_ip4 = 1;
7021         }
7022       else if (unformat (i, "via %U", unformat_ip6_address,
7023                          &v6_next_hop_address))
7024         {
7025           next_hop_set = 1;
7026           next_hop_proto_is_ip4 = 0;
7027         }
7028       else if (unformat (i, "weight %d", &next_hop_weight))
7029         ;
7030       else if (unformat (i, "create-table"))
7031         create_table_if_needed = 1;
7032       else if (unformat (i, "classify %d", &classify_table_index))
7033         {
7034           is_classify = 1;
7035         }
7036       else if (unformat (i, "del"))
7037         is_add = 0;
7038       else if (unformat (i, "add"))
7039         is_add = 1;
7040       else if (unformat (i, "resolve-via-host"))
7041         resolve_host = 1;
7042       else if (unformat (i, "resolve-via-attached"))
7043         resolve_attached = 1;
7044       else if (unformat (i, "multipath"))
7045         is_multipath = 1;
7046       else if (unformat (i, "count %d", &count))
7047         ;
7048       else if (unformat (i, "lookup-in-ip4-table %d", &next_hop_table_id))
7049         {
7050           next_hop_set = 1;
7051           next_hop_proto_is_ip4 = 1;
7052         }
7053       else if (unformat (i, "lookup-in-ip6-table %d", &next_hop_table_id))
7054         {
7055           next_hop_set = 1;
7056           next_hop_proto_is_ip4 = 0;
7057         }
7058       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
7059         ;
7060       else if (unformat (i, "via-label %d", &next_hop_via_label))
7061         ;
7062       else if (unformat (i, "out-label %d", &next_hop_out_label))
7063         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
7064       else
7065         {
7066           clib_warning ("parse error '%U'", format_unformat_error, i);
7067           return -99;
7068         }
7069     }
7070
7071   if (!next_hop_set && !is_classify)
7072     {
7073       errmsg ("next hop / classify not set");
7074       return -99;
7075     }
7076
7077   if (MPLS_LABEL_INVALID == local_label)
7078     {
7079       errmsg ("missing label");
7080       return -99;
7081     }
7082
7083   if (count > 1)
7084     {
7085       /* Turn on async mode */
7086       vam->async_mode = 1;
7087       vam->async_errors = 0;
7088       before = vat_time_now (vam);
7089     }
7090
7091   for (j = 0; j < count; j++)
7092     {
7093       /* Construct the API message */
7094       M2 (MPLS_ROUTE_ADD_DEL, mp,
7095           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
7096
7097       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
7098       mp->mr_table_id = ntohl (table_id);
7099       mp->mr_create_table_if_needed = create_table_if_needed;
7100
7101       mp->mr_is_add = is_add;
7102       mp->mr_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
7103       mp->mr_is_classify = is_classify;
7104       mp->mr_is_multipath = is_multipath;
7105       mp->mr_is_resolve_host = resolve_host;
7106       mp->mr_is_resolve_attached = resolve_attached;
7107       mp->mr_next_hop_weight = next_hop_weight;
7108       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
7109       mp->mr_classify_table_index = ntohl (classify_table_index);
7110       mp->mr_next_hop_via_label = ntohl (next_hop_via_label);
7111       mp->mr_label = ntohl (local_label);
7112       mp->mr_eos = is_eos;
7113
7114       mp->mr_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
7115       if (0 != mp->mr_next_hop_n_out_labels)
7116         {
7117           memcpy (mp->mr_next_hop_out_label_stack,
7118                   next_hop_out_label_stack,
7119                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
7120           vec_free (next_hop_out_label_stack);
7121         }
7122
7123       if (next_hop_set)
7124         {
7125           if (next_hop_proto_is_ip4)
7126             {
7127               clib_memcpy (mp->mr_next_hop,
7128                            &v4_next_hop_address,
7129                            sizeof (v4_next_hop_address));
7130             }
7131           else
7132             {
7133               clib_memcpy (mp->mr_next_hop,
7134                            &v6_next_hop_address,
7135                            sizeof (v6_next_hop_address));
7136             }
7137         }
7138       local_label++;
7139
7140       /* send it... */
7141       S (mp);
7142       /* If we receive SIGTERM, stop now... */
7143       if (vam->do_exit)
7144         break;
7145     }
7146
7147   /* When testing multiple add/del ops, use a control-ping to sync */
7148   if (count > 1)
7149     {
7150       vl_api_control_ping_t *mp_ping;
7151       f64 after;
7152       f64 timeout;
7153
7154       /* Shut off async mode */
7155       vam->async_mode = 0;
7156
7157       M (CONTROL_PING, mp_ping);
7158       S (mp_ping);
7159
7160       timeout = vat_time_now (vam) + 1.0;
7161       while (vat_time_now (vam) < timeout)
7162         if (vam->result_ready == 1)
7163           goto out;
7164       vam->retval = -99;
7165
7166     out:
7167       if (vam->retval == -99)
7168         errmsg ("timeout");
7169
7170       if (vam->async_errors > 0)
7171         {
7172           errmsg ("%d asynchronous errors", vam->async_errors);
7173           vam->retval = -98;
7174         }
7175       vam->async_errors = 0;
7176       after = vat_time_now (vam);
7177
7178       /* slim chance, but we might have eaten SIGTERM on the first iteration */
7179       if (j > 0)
7180         count = j;
7181
7182       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
7183              count, after - before, count / (after - before));
7184     }
7185   else
7186     {
7187       int ret;
7188
7189       /* Wait for a reply... */
7190       W (ret);
7191       return ret;
7192     }
7193
7194   /* Return the good/bad news */
7195   return (vam->retval);
7196 }
7197
7198 static int
7199 api_mpls_ip_bind_unbind (vat_main_t * vam)
7200 {
7201   unformat_input_t *i = vam->input;
7202   vl_api_mpls_ip_bind_unbind_t *mp;
7203   u32 ip_table_id = 0;
7204   u8 create_table_if_needed = 0;
7205   u8 is_bind = 1;
7206   u8 is_ip4 = 1;
7207   ip4_address_t v4_address;
7208   ip6_address_t v6_address;
7209   u32 address_length;
7210   u8 address_set = 0;
7211   mpls_label_t local_label = MPLS_LABEL_INVALID;
7212   int ret;
7213
7214   /* Parse args required to build the message */
7215   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7216     {
7217       if (unformat (i, "%U/%d", unformat_ip4_address,
7218                     &v4_address, &address_length))
7219         {
7220           is_ip4 = 1;
7221           address_set = 1;
7222         }
7223       else if (unformat (i, "%U/%d", unformat_ip6_address,
7224                          &v6_address, &address_length))
7225         {
7226           is_ip4 = 0;
7227           address_set = 1;
7228         }
7229       else if (unformat (i, "%d", &local_label))
7230         ;
7231       else if (unformat (i, "create-table"))
7232         create_table_if_needed = 1;
7233       else if (unformat (i, "table-id %d", &ip_table_id))
7234         ;
7235       else if (unformat (i, "unbind"))
7236         is_bind = 0;
7237       else if (unformat (i, "bind"))
7238         is_bind = 1;
7239       else
7240         {
7241           clib_warning ("parse error '%U'", format_unformat_error, i);
7242           return -99;
7243         }
7244     }
7245
7246   if (!address_set)
7247     {
7248       errmsg ("IP addres not set");
7249       return -99;
7250     }
7251
7252   if (MPLS_LABEL_INVALID == local_label)
7253     {
7254       errmsg ("missing label");
7255       return -99;
7256     }
7257
7258   /* Construct the API message */
7259   M (MPLS_IP_BIND_UNBIND, mp);
7260
7261   mp->mb_create_table_if_needed = create_table_if_needed;
7262   mp->mb_is_bind = is_bind;
7263   mp->mb_is_ip4 = is_ip4;
7264   mp->mb_ip_table_id = ntohl (ip_table_id);
7265   mp->mb_mpls_table_id = 0;
7266   mp->mb_label = ntohl (local_label);
7267   mp->mb_address_length = address_length;
7268
7269   if (is_ip4)
7270     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
7271   else
7272     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
7273
7274   /* send it... */
7275   S (mp);
7276
7277   /* Wait for a reply... */
7278   W (ret);
7279   return ret;
7280 }
7281
7282 static int
7283 api_proxy_arp_add_del (vat_main_t * vam)
7284 {
7285   unformat_input_t *i = vam->input;
7286   vl_api_proxy_arp_add_del_t *mp;
7287   u32 vrf_id = 0;
7288   u8 is_add = 1;
7289   ip4_address_t lo, hi;
7290   u8 range_set = 0;
7291   int ret;
7292
7293   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7294     {
7295       if (unformat (i, "vrf %d", &vrf_id))
7296         ;
7297       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
7298                          unformat_ip4_address, &hi))
7299         range_set = 1;
7300       else if (unformat (i, "del"))
7301         is_add = 0;
7302       else
7303         {
7304           clib_warning ("parse error '%U'", format_unformat_error, i);
7305           return -99;
7306         }
7307     }
7308
7309   if (range_set == 0)
7310     {
7311       errmsg ("address range not set");
7312       return -99;
7313     }
7314
7315   M (PROXY_ARP_ADD_DEL, mp);
7316
7317   mp->vrf_id = ntohl (vrf_id);
7318   mp->is_add = is_add;
7319   clib_memcpy (mp->low_address, &lo, sizeof (mp->low_address));
7320   clib_memcpy (mp->hi_address, &hi, sizeof (mp->hi_address));
7321
7322   S (mp);
7323   W (ret);
7324   return ret;
7325 }
7326
7327 static int
7328 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
7329 {
7330   unformat_input_t *i = vam->input;
7331   vl_api_proxy_arp_intfc_enable_disable_t *mp;
7332   u32 sw_if_index;
7333   u8 enable = 1;
7334   u8 sw_if_index_set = 0;
7335   int ret;
7336
7337   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7338     {
7339       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7340         sw_if_index_set = 1;
7341       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7342         sw_if_index_set = 1;
7343       else if (unformat (i, "enable"))
7344         enable = 1;
7345       else if (unformat (i, "disable"))
7346         enable = 0;
7347       else
7348         {
7349           clib_warning ("parse error '%U'", format_unformat_error, i);
7350           return -99;
7351         }
7352     }
7353
7354   if (sw_if_index_set == 0)
7355     {
7356       errmsg ("missing interface name or sw_if_index");
7357       return -99;
7358     }
7359
7360   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
7361
7362   mp->sw_if_index = ntohl (sw_if_index);
7363   mp->enable_disable = enable;
7364
7365   S (mp);
7366   W (ret);
7367   return ret;
7368 }
7369
7370 static int
7371 api_mpls_tunnel_add_del (vat_main_t * vam)
7372 {
7373   unformat_input_t *i = vam->input;
7374   vl_api_mpls_tunnel_add_del_t *mp;
7375
7376   u8 is_add = 1;
7377   u8 l2_only = 0;
7378   u32 sw_if_index = ~0;
7379   u32 next_hop_sw_if_index = ~0;
7380   u32 next_hop_proto_is_ip4 = 1;
7381
7382   u32 next_hop_table_id = 0;
7383   ip4_address_t v4_next_hop_address = {
7384     .as_u32 = 0,
7385   };
7386   ip6_address_t v6_next_hop_address = { {0} };
7387   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID, *labels = NULL;
7388   int ret;
7389
7390   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7391     {
7392       if (unformat (i, "add"))
7393         is_add = 1;
7394       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
7395         is_add = 0;
7396       else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
7397         ;
7398       else if (unformat (i, "via %U",
7399                          unformat_ip4_address, &v4_next_hop_address))
7400         {
7401           next_hop_proto_is_ip4 = 1;
7402         }
7403       else if (unformat (i, "via %U",
7404                          unformat_ip6_address, &v6_next_hop_address))
7405         {
7406           next_hop_proto_is_ip4 = 0;
7407         }
7408       else if (unformat (i, "l2-only"))
7409         l2_only = 1;
7410       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
7411         ;
7412       else if (unformat (i, "out-label %d", &next_hop_out_label))
7413         vec_add1 (labels, ntohl (next_hop_out_label));
7414       else
7415         {
7416           clib_warning ("parse error '%U'", format_unformat_error, i);
7417           return -99;
7418         }
7419     }
7420
7421   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (mpls_label_t) * vec_len (labels));
7422
7423   mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
7424   mp->mt_sw_if_index = ntohl (sw_if_index);
7425   mp->mt_is_add = is_add;
7426   mp->mt_l2_only = l2_only;
7427   mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
7428   mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
7429
7430   mp->mt_next_hop_n_out_labels = vec_len (labels);
7431
7432   if (0 != mp->mt_next_hop_n_out_labels)
7433     {
7434       clib_memcpy (mp->mt_next_hop_out_label_stack, labels,
7435                    sizeof (mpls_label_t) * mp->mt_next_hop_n_out_labels);
7436       vec_free (labels);
7437     }
7438
7439   if (next_hop_proto_is_ip4)
7440     {
7441       clib_memcpy (mp->mt_next_hop,
7442                    &v4_next_hop_address, sizeof (v4_next_hop_address));
7443     }
7444   else
7445     {
7446       clib_memcpy (mp->mt_next_hop,
7447                    &v6_next_hop_address, sizeof (v6_next_hop_address));
7448     }
7449
7450   S (mp);
7451   W (ret);
7452   return ret;
7453 }
7454
7455 static int
7456 api_sw_interface_set_unnumbered (vat_main_t * vam)
7457 {
7458   unformat_input_t *i = vam->input;
7459   vl_api_sw_interface_set_unnumbered_t *mp;
7460   u32 sw_if_index;
7461   u32 unnum_sw_index = ~0;
7462   u8 is_add = 1;
7463   u8 sw_if_index_set = 0;
7464   int ret;
7465
7466   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7467     {
7468       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7469         sw_if_index_set = 1;
7470       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7471         sw_if_index_set = 1;
7472       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
7473         ;
7474       else if (unformat (i, "del"))
7475         is_add = 0;
7476       else
7477         {
7478           clib_warning ("parse error '%U'", format_unformat_error, i);
7479           return -99;
7480         }
7481     }
7482
7483   if (sw_if_index_set == 0)
7484     {
7485       errmsg ("missing interface name or sw_if_index");
7486       return -99;
7487     }
7488
7489   M (SW_INTERFACE_SET_UNNUMBERED, mp);
7490
7491   mp->sw_if_index = ntohl (sw_if_index);
7492   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
7493   mp->is_add = is_add;
7494
7495   S (mp);
7496   W (ret);
7497   return ret;
7498 }
7499
7500 static int
7501 api_ip_neighbor_add_del (vat_main_t * vam)
7502 {
7503   unformat_input_t *i = vam->input;
7504   vl_api_ip_neighbor_add_del_t *mp;
7505   u32 sw_if_index;
7506   u8 sw_if_index_set = 0;
7507   u8 is_add = 1;
7508   u8 is_static = 0;
7509   u8 is_no_fib_entry = 0;
7510   u8 mac_address[6];
7511   u8 mac_set = 0;
7512   u8 v4_address_set = 0;
7513   u8 v6_address_set = 0;
7514   ip4_address_t v4address;
7515   ip6_address_t v6address;
7516   int ret;
7517
7518   memset (mac_address, 0, sizeof (mac_address));
7519
7520   /* Parse args required to build the message */
7521   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7522     {
7523       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7524         {
7525           mac_set = 1;
7526         }
7527       else if (unformat (i, "del"))
7528         is_add = 0;
7529       else
7530         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7531         sw_if_index_set = 1;
7532       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7533         sw_if_index_set = 1;
7534       else if (unformat (i, "is_static"))
7535         is_static = 1;
7536       else if (unformat (i, "no-fib-entry"))
7537         is_no_fib_entry = 1;
7538       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
7539         v4_address_set = 1;
7540       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
7541         v6_address_set = 1;
7542       else
7543         {
7544           clib_warning ("parse error '%U'", format_unformat_error, i);
7545           return -99;
7546         }
7547     }
7548
7549   if (sw_if_index_set == 0)
7550     {
7551       errmsg ("missing interface name or sw_if_index");
7552       return -99;
7553     }
7554   if (v4_address_set && v6_address_set)
7555     {
7556       errmsg ("both v4 and v6 addresses set");
7557       return -99;
7558     }
7559   if (!v4_address_set && !v6_address_set)
7560     {
7561       errmsg ("no address set");
7562       return -99;
7563     }
7564
7565   /* Construct the API message */
7566   M (IP_NEIGHBOR_ADD_DEL, mp);
7567
7568   mp->sw_if_index = ntohl (sw_if_index);
7569   mp->is_add = is_add;
7570   mp->is_static = is_static;
7571   mp->is_no_adj_fib = is_no_fib_entry;
7572   if (mac_set)
7573     clib_memcpy (mp->mac_address, mac_address, 6);
7574   if (v6_address_set)
7575     {
7576       mp->is_ipv6 = 1;
7577       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
7578     }
7579   else
7580     {
7581       /* mp->is_ipv6 = 0; via memset in M macro above */
7582       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
7583     }
7584
7585   /* send it... */
7586   S (mp);
7587
7588   /* Wait for a reply, return good/bad news  */
7589   W (ret);
7590   return ret;
7591 }
7592
7593 static int
7594 api_reset_vrf (vat_main_t * vam)
7595 {
7596   unformat_input_t *i = vam->input;
7597   vl_api_reset_vrf_t *mp;
7598   u32 vrf_id = 0;
7599   u8 is_ipv6 = 0;
7600   u8 vrf_id_set = 0;
7601   int ret;
7602
7603   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7604     {
7605       if (unformat (i, "vrf %d", &vrf_id))
7606         vrf_id_set = 1;
7607       else if (unformat (i, "ipv6"))
7608         is_ipv6 = 1;
7609       else
7610         {
7611           clib_warning ("parse error '%U'", format_unformat_error, i);
7612           return -99;
7613         }
7614     }
7615
7616   if (vrf_id_set == 0)
7617     {
7618       errmsg ("missing vrf id");
7619       return -99;
7620     }
7621
7622   M (RESET_VRF, mp);
7623
7624   mp->vrf_id = ntohl (vrf_id);
7625   mp->is_ipv6 = is_ipv6;
7626
7627   S (mp);
7628   W (ret);
7629   return ret;
7630 }
7631
7632 static int
7633 api_create_vlan_subif (vat_main_t * vam)
7634 {
7635   unformat_input_t *i = vam->input;
7636   vl_api_create_vlan_subif_t *mp;
7637   u32 sw_if_index;
7638   u8 sw_if_index_set = 0;
7639   u32 vlan_id;
7640   u8 vlan_id_set = 0;
7641   int ret;
7642
7643   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7644     {
7645       if (unformat (i, "sw_if_index %d", &sw_if_index))
7646         sw_if_index_set = 1;
7647       else
7648         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7649         sw_if_index_set = 1;
7650       else if (unformat (i, "vlan %d", &vlan_id))
7651         vlan_id_set = 1;
7652       else
7653         {
7654           clib_warning ("parse error '%U'", format_unformat_error, i);
7655           return -99;
7656         }
7657     }
7658
7659   if (sw_if_index_set == 0)
7660     {
7661       errmsg ("missing interface name or sw_if_index");
7662       return -99;
7663     }
7664
7665   if (vlan_id_set == 0)
7666     {
7667       errmsg ("missing vlan_id");
7668       return -99;
7669     }
7670   M (CREATE_VLAN_SUBIF, mp);
7671
7672   mp->sw_if_index = ntohl (sw_if_index);
7673   mp->vlan_id = ntohl (vlan_id);
7674
7675   S (mp);
7676   W (ret);
7677   return ret;
7678 }
7679
7680 #define foreach_create_subif_bit                \
7681 _(no_tags)                                      \
7682 _(one_tag)                                      \
7683 _(two_tags)                                     \
7684 _(dot1ad)                                       \
7685 _(exact_match)                                  \
7686 _(default_sub)                                  \
7687 _(outer_vlan_id_any)                            \
7688 _(inner_vlan_id_any)
7689
7690 static int
7691 api_create_subif (vat_main_t * vam)
7692 {
7693   unformat_input_t *i = vam->input;
7694   vl_api_create_subif_t *mp;
7695   u32 sw_if_index;
7696   u8 sw_if_index_set = 0;
7697   u32 sub_id;
7698   u8 sub_id_set = 0;
7699   u32 no_tags = 0;
7700   u32 one_tag = 0;
7701   u32 two_tags = 0;
7702   u32 dot1ad = 0;
7703   u32 exact_match = 0;
7704   u32 default_sub = 0;
7705   u32 outer_vlan_id_any = 0;
7706   u32 inner_vlan_id_any = 0;
7707   u32 tmp;
7708   u16 outer_vlan_id = 0;
7709   u16 inner_vlan_id = 0;
7710   int ret;
7711
7712   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7713     {
7714       if (unformat (i, "sw_if_index %d", &sw_if_index))
7715         sw_if_index_set = 1;
7716       else
7717         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7718         sw_if_index_set = 1;
7719       else if (unformat (i, "sub_id %d", &sub_id))
7720         sub_id_set = 1;
7721       else if (unformat (i, "outer_vlan_id %d", &tmp))
7722         outer_vlan_id = tmp;
7723       else if (unformat (i, "inner_vlan_id %d", &tmp))
7724         inner_vlan_id = tmp;
7725
7726 #define _(a) else if (unformat (i, #a)) a = 1 ;
7727       foreach_create_subif_bit
7728 #undef _
7729         else
7730         {
7731           clib_warning ("parse error '%U'", format_unformat_error, i);
7732           return -99;
7733         }
7734     }
7735
7736   if (sw_if_index_set == 0)
7737     {
7738       errmsg ("missing interface name or sw_if_index");
7739       return -99;
7740     }
7741
7742   if (sub_id_set == 0)
7743     {
7744       errmsg ("missing sub_id");
7745       return -99;
7746     }
7747   M (CREATE_SUBIF, mp);
7748
7749   mp->sw_if_index = ntohl (sw_if_index);
7750   mp->sub_id = ntohl (sub_id);
7751
7752 #define _(a) mp->a = a;
7753   foreach_create_subif_bit;
7754 #undef _
7755
7756   mp->outer_vlan_id = ntohs (outer_vlan_id);
7757   mp->inner_vlan_id = ntohs (inner_vlan_id);
7758
7759   S (mp);
7760   W (ret);
7761   return ret;
7762 }
7763
7764 static int
7765 api_oam_add_del (vat_main_t * vam)
7766 {
7767   unformat_input_t *i = vam->input;
7768   vl_api_oam_add_del_t *mp;
7769   u32 vrf_id = 0;
7770   u8 is_add = 1;
7771   ip4_address_t src, dst;
7772   u8 src_set = 0;
7773   u8 dst_set = 0;
7774   int ret;
7775
7776   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7777     {
7778       if (unformat (i, "vrf %d", &vrf_id))
7779         ;
7780       else if (unformat (i, "src %U", unformat_ip4_address, &src))
7781         src_set = 1;
7782       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
7783         dst_set = 1;
7784       else if (unformat (i, "del"))
7785         is_add = 0;
7786       else
7787         {
7788           clib_warning ("parse error '%U'", format_unformat_error, i);
7789           return -99;
7790         }
7791     }
7792
7793   if (src_set == 0)
7794     {
7795       errmsg ("missing src addr");
7796       return -99;
7797     }
7798
7799   if (dst_set == 0)
7800     {
7801       errmsg ("missing dst addr");
7802       return -99;
7803     }
7804
7805   M (OAM_ADD_DEL, mp);
7806
7807   mp->vrf_id = ntohl (vrf_id);
7808   mp->is_add = is_add;
7809   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
7810   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
7811
7812   S (mp);
7813   W (ret);
7814   return ret;
7815 }
7816
7817 static int
7818 api_reset_fib (vat_main_t * vam)
7819 {
7820   unformat_input_t *i = vam->input;
7821   vl_api_reset_fib_t *mp;
7822   u32 vrf_id = 0;
7823   u8 is_ipv6 = 0;
7824   u8 vrf_id_set = 0;
7825
7826   int ret;
7827   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7828     {
7829       if (unformat (i, "vrf %d", &vrf_id))
7830         vrf_id_set = 1;
7831       else if (unformat (i, "ipv6"))
7832         is_ipv6 = 1;
7833       else
7834         {
7835           clib_warning ("parse error '%U'", format_unformat_error, i);
7836           return -99;
7837         }
7838     }
7839
7840   if (vrf_id_set == 0)
7841     {
7842       errmsg ("missing vrf id");
7843       return -99;
7844     }
7845
7846   M (RESET_FIB, mp);
7847
7848   mp->vrf_id = ntohl (vrf_id);
7849   mp->is_ipv6 = is_ipv6;
7850
7851   S (mp);
7852   W (ret);
7853   return ret;
7854 }
7855
7856 static int
7857 api_dhcp_proxy_config (vat_main_t * vam)
7858 {
7859   unformat_input_t *i = vam->input;
7860   vl_api_dhcp_proxy_config_t *mp;
7861   u32 rx_vrf_id = 0;
7862   u32 server_vrf_id = 0;
7863   u8 is_add = 1;
7864   u8 v4_address_set = 0;
7865   u8 v6_address_set = 0;
7866   ip4_address_t v4address;
7867   ip6_address_t v6address;
7868   u8 v4_src_address_set = 0;
7869   u8 v6_src_address_set = 0;
7870   ip4_address_t v4srcaddress;
7871   ip6_address_t v6srcaddress;
7872   int ret;
7873
7874   /* Parse args required to build the message */
7875   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7876     {
7877       if (unformat (i, "del"))
7878         is_add = 0;
7879       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
7880         ;
7881       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
7882         ;
7883       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
7884         v4_address_set = 1;
7885       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
7886         v6_address_set = 1;
7887       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
7888         v4_src_address_set = 1;
7889       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
7890         v6_src_address_set = 1;
7891       else
7892         break;
7893     }
7894
7895   if (v4_address_set && v6_address_set)
7896     {
7897       errmsg ("both v4 and v6 server addresses set");
7898       return -99;
7899     }
7900   if (!v4_address_set && !v6_address_set)
7901     {
7902       errmsg ("no server addresses set");
7903       return -99;
7904     }
7905
7906   if (v4_src_address_set && v6_src_address_set)
7907     {
7908       errmsg ("both v4 and v6  src addresses set");
7909       return -99;
7910     }
7911   if (!v4_src_address_set && !v6_src_address_set)
7912     {
7913       errmsg ("no src addresses set");
7914       return -99;
7915     }
7916
7917   if (!(v4_src_address_set && v4_address_set) &&
7918       !(v6_src_address_set && v6_address_set))
7919     {
7920       errmsg ("no matching server and src addresses set");
7921       return -99;
7922     }
7923
7924   /* Construct the API message */
7925   M (DHCP_PROXY_CONFIG, mp);
7926
7927   mp->is_add = is_add;
7928   mp->rx_vrf_id = ntohl (rx_vrf_id);
7929   mp->server_vrf_id = ntohl (server_vrf_id);
7930   if (v6_address_set)
7931     {
7932       mp->is_ipv6 = 1;
7933       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
7934       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
7935     }
7936   else
7937     {
7938       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
7939       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
7940     }
7941
7942   /* send it... */
7943   S (mp);
7944
7945   /* Wait for a reply, return good/bad news  */
7946   W (ret);
7947   return ret;
7948 }
7949
7950 #define vl_api_dhcp_proxy_details_t_endian vl_noop_handler
7951 #define vl_api_dhcp_proxy_details_t_print vl_noop_handler
7952
7953 static void
7954 vl_api_dhcp_proxy_details_t_handler (vl_api_dhcp_proxy_details_t * mp)
7955 {
7956   vat_main_t *vam = &vat_main;
7957   u32 i, count = mp->count;
7958   vl_api_dhcp_server_t *s;
7959
7960   if (mp->is_ipv6)
7961     print (vam->ofp,
7962            "RX Table-ID %d, Source Address %U, VSS FIB-ID %d, VSS OUI %d",
7963            ntohl (mp->rx_vrf_id),
7964            format_ip6_address, mp->dhcp_src_address,
7965            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
7966   else
7967     print (vam->ofp,
7968            "RX Table-ID %d, Source Address %U, VSS FIB-ID %d, VSS OUI %d",
7969            ntohl (mp->rx_vrf_id),
7970            format_ip4_address, mp->dhcp_src_address,
7971            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
7972
7973   for (i = 0; i < count; i++)
7974     {
7975       s = &mp->servers[i];
7976
7977       if (mp->is_ipv6)
7978         print (vam->ofp,
7979                " Server Table-ID %d, Server Address %U",
7980                ntohl (s->server_vrf_id), format_ip6_address, s->dhcp_server);
7981       else
7982         print (vam->ofp,
7983                " Server Table-ID %d, Server Address %U",
7984                ntohl (s->server_vrf_id), format_ip4_address, s->dhcp_server);
7985     }
7986 }
7987
7988 static void vl_api_dhcp_proxy_details_t_handler_json
7989   (vl_api_dhcp_proxy_details_t * mp)
7990 {
7991   vat_main_t *vam = &vat_main;
7992   vat_json_node_t *node = NULL;
7993   u32 i, count = mp->count;
7994   struct in_addr ip4;
7995   struct in6_addr ip6;
7996   vl_api_dhcp_server_t *s;
7997
7998   if (VAT_JSON_ARRAY != vam->json_tree.type)
7999     {
8000       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
8001       vat_json_init_array (&vam->json_tree);
8002     }
8003   node = vat_json_array_add (&vam->json_tree);
8004
8005   vat_json_init_object (node);
8006   vat_json_object_add_uint (node, "rx-table-id", ntohl (mp->rx_vrf_id));
8007   vat_json_object_add_uint (node, "vss-fib-id", ntohl (mp->vss_fib_id));
8008   vat_json_object_add_uint (node, "vss-oui", ntohl (mp->vss_oui));
8009
8010   if (mp->is_ipv6)
8011     {
8012       clib_memcpy (&ip6, &mp->dhcp_src_address, sizeof (ip6));
8013       vat_json_object_add_ip6 (node, "src_address", ip6);
8014     }
8015   else
8016     {
8017       clib_memcpy (&ip4, &mp->dhcp_src_address, sizeof (ip4));
8018       vat_json_object_add_ip4 (node, "src_address", ip4);
8019     }
8020
8021   for (i = 0; i < count; i++)
8022     {
8023       s = &mp->servers[i];
8024
8025       vat_json_object_add_uint (node, "server-table-id",
8026                                 ntohl (s->server_vrf_id));
8027
8028       if (mp->is_ipv6)
8029         {
8030           clib_memcpy (&ip4, &s->dhcp_server, sizeof (ip4));
8031           vat_json_object_add_ip4 (node, "src_address", ip4);
8032         }
8033       else
8034         {
8035           clib_memcpy (&ip6, &s->dhcp_server, sizeof (ip6));
8036           vat_json_object_add_ip6 (node, "server_address", ip6);
8037         }
8038     }
8039 }
8040
8041 static int
8042 api_dhcp_proxy_dump (vat_main_t * vam)
8043 {
8044   unformat_input_t *i = vam->input;
8045   vl_api_control_ping_t *mp_ping;
8046   vl_api_dhcp_proxy_dump_t *mp;
8047   u8 is_ipv6 = 0;
8048   int ret;
8049
8050   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8051     {
8052       if (unformat (i, "ipv6"))
8053         is_ipv6 = 1;
8054       else
8055         {
8056           clib_warning ("parse error '%U'", format_unformat_error, i);
8057           return -99;
8058         }
8059     }
8060
8061   M (DHCP_PROXY_DUMP, mp);
8062
8063   mp->is_ip6 = is_ipv6;
8064   S (mp);
8065
8066   /* Use a control ping for synchronization */
8067   M (CONTROL_PING, mp_ping);
8068   S (mp_ping);
8069
8070   W (ret);
8071   return ret;
8072 }
8073
8074 static int
8075 api_dhcp_proxy_set_vss (vat_main_t * vam)
8076 {
8077   unformat_input_t *i = vam->input;
8078   vl_api_dhcp_proxy_set_vss_t *mp;
8079   u8 is_ipv6 = 0;
8080   u8 is_add = 1;
8081   u32 tbl_id;
8082   u8 tbl_id_set = 0;
8083   u32 oui;
8084   u8 oui_set = 0;
8085   u32 fib_id;
8086   u8 fib_id_set = 0;
8087   int ret;
8088
8089   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8090     {
8091       if (unformat (i, "tbl_id %d", &tbl_id))
8092         tbl_id_set = 1;
8093       if (unformat (i, "fib_id %d", &fib_id))
8094         fib_id_set = 1;
8095       if (unformat (i, "oui %d", &oui))
8096         oui_set = 1;
8097       else if (unformat (i, "ipv6"))
8098         is_ipv6 = 1;
8099       else if (unformat (i, "del"))
8100         is_add = 0;
8101       else
8102         {
8103           clib_warning ("parse error '%U'", format_unformat_error, i);
8104           return -99;
8105         }
8106     }
8107
8108   if (tbl_id_set == 0)
8109     {
8110       errmsg ("missing tbl id");
8111       return -99;
8112     }
8113
8114   if (fib_id_set == 0)
8115     {
8116       errmsg ("missing fib id");
8117       return -99;
8118     }
8119   if (oui_set == 0)
8120     {
8121       errmsg ("missing oui");
8122       return -99;
8123     }
8124
8125   M (DHCP_PROXY_SET_VSS, mp);
8126   mp->tbl_id = ntohl (tbl_id);
8127   mp->fib_id = ntohl (fib_id);
8128   mp->oui = ntohl (oui);
8129   mp->is_ipv6 = is_ipv6;
8130   mp->is_add = is_add;
8131
8132   S (mp);
8133   W (ret);
8134   return ret;
8135 }
8136
8137 static int
8138 api_dhcp_client_config (vat_main_t * vam)
8139 {
8140   unformat_input_t *i = vam->input;
8141   vl_api_dhcp_client_config_t *mp;
8142   u32 sw_if_index;
8143   u8 sw_if_index_set = 0;
8144   u8 is_add = 1;
8145   u8 *hostname = 0;
8146   u8 disable_event = 0;
8147   int ret;
8148
8149   /* Parse args required to build the message */
8150   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8151     {
8152       if (unformat (i, "del"))
8153         is_add = 0;
8154       else
8155         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8156         sw_if_index_set = 1;
8157       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8158         sw_if_index_set = 1;
8159       else if (unformat (i, "hostname %s", &hostname))
8160         ;
8161       else if (unformat (i, "disable_event"))
8162         disable_event = 1;
8163       else
8164         break;
8165     }
8166
8167   if (sw_if_index_set == 0)
8168     {
8169       errmsg ("missing interface name or sw_if_index");
8170       return -99;
8171     }
8172
8173   if (vec_len (hostname) > 63)
8174     {
8175       errmsg ("hostname too long");
8176     }
8177   vec_add1 (hostname, 0);
8178
8179   /* Construct the API message */
8180   M (DHCP_CLIENT_CONFIG, mp);
8181
8182   mp->sw_if_index = htonl (sw_if_index);
8183   clib_memcpy (mp->hostname, hostname, vec_len (hostname));
8184   vec_free (hostname);
8185   mp->is_add = is_add;
8186   mp->want_dhcp_event = disable_event ? 0 : 1;
8187   mp->pid = htonl (getpid ());
8188
8189   /* send it... */
8190   S (mp);
8191
8192   /* Wait for a reply, return good/bad news  */
8193   W (ret);
8194   return ret;
8195 }
8196
8197 static int
8198 api_set_ip_flow_hash (vat_main_t * vam)
8199 {
8200   unformat_input_t *i = vam->input;
8201   vl_api_set_ip_flow_hash_t *mp;
8202   u32 vrf_id = 0;
8203   u8 is_ipv6 = 0;
8204   u8 vrf_id_set = 0;
8205   u8 src = 0;
8206   u8 dst = 0;
8207   u8 sport = 0;
8208   u8 dport = 0;
8209   u8 proto = 0;
8210   u8 reverse = 0;
8211   int ret;
8212
8213   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8214     {
8215       if (unformat (i, "vrf %d", &vrf_id))
8216         vrf_id_set = 1;
8217       else if (unformat (i, "ipv6"))
8218         is_ipv6 = 1;
8219       else if (unformat (i, "src"))
8220         src = 1;
8221       else if (unformat (i, "dst"))
8222         dst = 1;
8223       else if (unformat (i, "sport"))
8224         sport = 1;
8225       else if (unformat (i, "dport"))
8226         dport = 1;
8227       else if (unformat (i, "proto"))
8228         proto = 1;
8229       else if (unformat (i, "reverse"))
8230         reverse = 1;
8231
8232       else
8233         {
8234           clib_warning ("parse error '%U'", format_unformat_error, i);
8235           return -99;
8236         }
8237     }
8238
8239   if (vrf_id_set == 0)
8240     {
8241       errmsg ("missing vrf id");
8242       return -99;
8243     }
8244
8245   M (SET_IP_FLOW_HASH, mp);
8246   mp->src = src;
8247   mp->dst = dst;
8248   mp->sport = sport;
8249   mp->dport = dport;
8250   mp->proto = proto;
8251   mp->reverse = reverse;
8252   mp->vrf_id = ntohl (vrf_id);
8253   mp->is_ipv6 = is_ipv6;
8254
8255   S (mp);
8256   W (ret);
8257   return ret;
8258 }
8259
8260 static int
8261 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
8262 {
8263   unformat_input_t *i = vam->input;
8264   vl_api_sw_interface_ip6_enable_disable_t *mp;
8265   u32 sw_if_index;
8266   u8 sw_if_index_set = 0;
8267   u8 enable = 0;
8268   int ret;
8269
8270   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8271     {
8272       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8273         sw_if_index_set = 1;
8274       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8275         sw_if_index_set = 1;
8276       else if (unformat (i, "enable"))
8277         enable = 1;
8278       else if (unformat (i, "disable"))
8279         enable = 0;
8280       else
8281         {
8282           clib_warning ("parse error '%U'", format_unformat_error, i);
8283           return -99;
8284         }
8285     }
8286
8287   if (sw_if_index_set == 0)
8288     {
8289       errmsg ("missing interface name or sw_if_index");
8290       return -99;
8291     }
8292
8293   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
8294
8295   mp->sw_if_index = ntohl (sw_if_index);
8296   mp->enable = enable;
8297
8298   S (mp);
8299   W (ret);
8300   return ret;
8301 }
8302
8303 static int
8304 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
8305 {
8306   unformat_input_t *i = vam->input;
8307   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
8308   u32 sw_if_index;
8309   u8 sw_if_index_set = 0;
8310   u8 v6_address_set = 0;
8311   ip6_address_t v6address;
8312   int ret;
8313
8314   /* Parse args required to build the message */
8315   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8316     {
8317       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8318         sw_if_index_set = 1;
8319       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8320         sw_if_index_set = 1;
8321       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
8322         v6_address_set = 1;
8323       else
8324         break;
8325     }
8326
8327   if (sw_if_index_set == 0)
8328     {
8329       errmsg ("missing interface name or sw_if_index");
8330       return -99;
8331     }
8332   if (!v6_address_set)
8333     {
8334       errmsg ("no address set");
8335       return -99;
8336     }
8337
8338   /* Construct the API message */
8339   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS, mp);
8340
8341   mp->sw_if_index = ntohl (sw_if_index);
8342   clib_memcpy (mp->address, &v6address, sizeof (v6address));
8343
8344   /* send it... */
8345   S (mp);
8346
8347   /* Wait for a reply, return good/bad news  */
8348   W (ret);
8349   return ret;
8350 }
8351
8352 static int
8353 api_ip6nd_proxy_add_del (vat_main_t * vam)
8354 {
8355   unformat_input_t *i = vam->input;
8356   vl_api_ip6nd_proxy_add_del_t *mp;
8357   u32 sw_if_index = ~0;
8358   u8 v6_address_set = 0;
8359   ip6_address_t v6address;
8360   u8 is_del = 0;
8361   int ret;
8362
8363   /* Parse args required to build the message */
8364   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8365     {
8366       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8367         ;
8368       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8369         ;
8370       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
8371         v6_address_set = 1;
8372       if (unformat (i, "del"))
8373         is_del = 1;
8374       else
8375         {
8376           clib_warning ("parse error '%U'", format_unformat_error, i);
8377           return -99;
8378         }
8379     }
8380
8381   if (sw_if_index == ~0)
8382     {
8383       errmsg ("missing interface name or sw_if_index");
8384       return -99;
8385     }
8386   if (!v6_address_set)
8387     {
8388       errmsg ("no address set");
8389       return -99;
8390     }
8391
8392   /* Construct the API message */
8393   M (IP6ND_PROXY_ADD_DEL, mp);
8394
8395   mp->is_del = is_del;
8396   mp->sw_if_index = ntohl (sw_if_index);
8397   clib_memcpy (mp->address, &v6address, sizeof (v6address));
8398
8399   /* send it... */
8400   S (mp);
8401
8402   /* Wait for a reply, return good/bad news  */
8403   W (ret);
8404   return ret;
8405 }
8406
8407 static int
8408 api_ip6nd_proxy_dump (vat_main_t * vam)
8409 {
8410   vl_api_ip6nd_proxy_dump_t *mp;
8411   vl_api_control_ping_t *mp_ping;
8412   int ret;
8413
8414   M (IP6ND_PROXY_DUMP, mp);
8415
8416   S (mp);
8417
8418   /* Use a control ping for synchronization */
8419   M (CONTROL_PING, mp_ping);
8420   S (mp_ping);
8421
8422   W (ret);
8423   return ret;
8424 }
8425
8426 static void vl_api_ip6nd_proxy_details_t_handler
8427   (vl_api_ip6nd_proxy_details_t * mp)
8428 {
8429   vat_main_t *vam = &vat_main;
8430
8431   print (vam->ofp, "host %U sw_if_index %d",
8432          format_ip6_address, mp->address, ntohl (mp->sw_if_index));
8433 }
8434
8435 static void vl_api_ip6nd_proxy_details_t_handler_json
8436   (vl_api_ip6nd_proxy_details_t * mp)
8437 {
8438   vat_main_t *vam = &vat_main;
8439   struct in6_addr ip6;
8440   vat_json_node_t *node = NULL;
8441
8442   if (VAT_JSON_ARRAY != vam->json_tree.type)
8443     {
8444       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
8445       vat_json_init_array (&vam->json_tree);
8446     }
8447   node = vat_json_array_add (&vam->json_tree);
8448
8449   vat_json_init_object (node);
8450   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
8451
8452   clib_memcpy (&ip6, mp->address, sizeof (ip6));
8453   vat_json_object_add_ip6 (node, "host", ip6);
8454 }
8455
8456 static int
8457 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
8458 {
8459   unformat_input_t *i = vam->input;
8460   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
8461   u32 sw_if_index;
8462   u8 sw_if_index_set = 0;
8463   u32 address_length = 0;
8464   u8 v6_address_set = 0;
8465   ip6_address_t v6address;
8466   u8 use_default = 0;
8467   u8 no_advertise = 0;
8468   u8 off_link = 0;
8469   u8 no_autoconfig = 0;
8470   u8 no_onlink = 0;
8471   u8 is_no = 0;
8472   u32 val_lifetime = 0;
8473   u32 pref_lifetime = 0;
8474   int ret;
8475
8476   /* Parse args required to build the message */
8477   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8478     {
8479       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8480         sw_if_index_set = 1;
8481       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8482         sw_if_index_set = 1;
8483       else if (unformat (i, "%U/%d",
8484                          unformat_ip6_address, &v6address, &address_length))
8485         v6_address_set = 1;
8486       else if (unformat (i, "val_life %d", &val_lifetime))
8487         ;
8488       else if (unformat (i, "pref_life %d", &pref_lifetime))
8489         ;
8490       else if (unformat (i, "def"))
8491         use_default = 1;
8492       else if (unformat (i, "noadv"))
8493         no_advertise = 1;
8494       else if (unformat (i, "offl"))
8495         off_link = 1;
8496       else if (unformat (i, "noauto"))
8497         no_autoconfig = 1;
8498       else if (unformat (i, "nolink"))
8499         no_onlink = 1;
8500       else if (unformat (i, "isno"))
8501         is_no = 1;
8502       else
8503         {
8504           clib_warning ("parse error '%U'", format_unformat_error, i);
8505           return -99;
8506         }
8507     }
8508
8509   if (sw_if_index_set == 0)
8510     {
8511       errmsg ("missing interface name or sw_if_index");
8512       return -99;
8513     }
8514   if (!v6_address_set)
8515     {
8516       errmsg ("no address set");
8517       return -99;
8518     }
8519
8520   /* Construct the API message */
8521   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
8522
8523   mp->sw_if_index = ntohl (sw_if_index);
8524   clib_memcpy (mp->address, &v6address, sizeof (v6address));
8525   mp->address_length = address_length;
8526   mp->use_default = use_default;
8527   mp->no_advertise = no_advertise;
8528   mp->off_link = off_link;
8529   mp->no_autoconfig = no_autoconfig;
8530   mp->no_onlink = no_onlink;
8531   mp->is_no = is_no;
8532   mp->val_lifetime = ntohl (val_lifetime);
8533   mp->pref_lifetime = ntohl (pref_lifetime);
8534
8535   /* send it... */
8536   S (mp);
8537
8538   /* Wait for a reply, return good/bad news  */
8539   W (ret);
8540   return ret;
8541 }
8542
8543 static int
8544 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
8545 {
8546   unformat_input_t *i = vam->input;
8547   vl_api_sw_interface_ip6nd_ra_config_t *mp;
8548   u32 sw_if_index;
8549   u8 sw_if_index_set = 0;
8550   u8 suppress = 0;
8551   u8 managed = 0;
8552   u8 other = 0;
8553   u8 ll_option = 0;
8554   u8 send_unicast = 0;
8555   u8 cease = 0;
8556   u8 is_no = 0;
8557   u8 default_router = 0;
8558   u32 max_interval = 0;
8559   u32 min_interval = 0;
8560   u32 lifetime = 0;
8561   u32 initial_count = 0;
8562   u32 initial_interval = 0;
8563   int ret;
8564
8565
8566   /* Parse args required to build the message */
8567   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8568     {
8569       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8570         sw_if_index_set = 1;
8571       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8572         sw_if_index_set = 1;
8573       else if (unformat (i, "maxint %d", &max_interval))
8574         ;
8575       else if (unformat (i, "minint %d", &min_interval))
8576         ;
8577       else if (unformat (i, "life %d", &lifetime))
8578         ;
8579       else if (unformat (i, "count %d", &initial_count))
8580         ;
8581       else if (unformat (i, "interval %d", &initial_interval))
8582         ;
8583       else if (unformat (i, "suppress") || unformat (i, "surpress"))
8584         suppress = 1;
8585       else if (unformat (i, "managed"))
8586         managed = 1;
8587       else if (unformat (i, "other"))
8588         other = 1;
8589       else if (unformat (i, "ll"))
8590         ll_option = 1;
8591       else if (unformat (i, "send"))
8592         send_unicast = 1;
8593       else if (unformat (i, "cease"))
8594         cease = 1;
8595       else if (unformat (i, "isno"))
8596         is_no = 1;
8597       else if (unformat (i, "def"))
8598         default_router = 1;
8599       else
8600         {
8601           clib_warning ("parse error '%U'", format_unformat_error, i);
8602           return -99;
8603         }
8604     }
8605
8606   if (sw_if_index_set == 0)
8607     {
8608       errmsg ("missing interface name or sw_if_index");
8609       return -99;
8610     }
8611
8612   /* Construct the API message */
8613   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
8614
8615   mp->sw_if_index = ntohl (sw_if_index);
8616   mp->max_interval = ntohl (max_interval);
8617   mp->min_interval = ntohl (min_interval);
8618   mp->lifetime = ntohl (lifetime);
8619   mp->initial_count = ntohl (initial_count);
8620   mp->initial_interval = ntohl (initial_interval);
8621   mp->suppress = suppress;
8622   mp->managed = managed;
8623   mp->other = other;
8624   mp->ll_option = ll_option;
8625   mp->send_unicast = send_unicast;
8626   mp->cease = cease;
8627   mp->is_no = is_no;
8628   mp->default_router = default_router;
8629
8630   /* send it... */
8631   S (mp);
8632
8633   /* Wait for a reply, return good/bad news  */
8634   W (ret);
8635   return ret;
8636 }
8637
8638 static int
8639 api_set_arp_neighbor_limit (vat_main_t * vam)
8640 {
8641   unformat_input_t *i = vam->input;
8642   vl_api_set_arp_neighbor_limit_t *mp;
8643   u32 arp_nbr_limit;
8644   u8 limit_set = 0;
8645   u8 is_ipv6 = 0;
8646   int ret;
8647
8648   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8649     {
8650       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
8651         limit_set = 1;
8652       else if (unformat (i, "ipv6"))
8653         is_ipv6 = 1;
8654       else
8655         {
8656           clib_warning ("parse error '%U'", format_unformat_error, i);
8657           return -99;
8658         }
8659     }
8660
8661   if (limit_set == 0)
8662     {
8663       errmsg ("missing limit value");
8664       return -99;
8665     }
8666
8667   M (SET_ARP_NEIGHBOR_LIMIT, mp);
8668
8669   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
8670   mp->is_ipv6 = is_ipv6;
8671
8672   S (mp);
8673   W (ret);
8674   return ret;
8675 }
8676
8677 static int
8678 api_l2_patch_add_del (vat_main_t * vam)
8679 {
8680   unformat_input_t *i = vam->input;
8681   vl_api_l2_patch_add_del_t *mp;
8682   u32 rx_sw_if_index;
8683   u8 rx_sw_if_index_set = 0;
8684   u32 tx_sw_if_index;
8685   u8 tx_sw_if_index_set = 0;
8686   u8 is_add = 1;
8687   int ret;
8688
8689   /* Parse args required to build the message */
8690   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8691     {
8692       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
8693         rx_sw_if_index_set = 1;
8694       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
8695         tx_sw_if_index_set = 1;
8696       else if (unformat (i, "rx"))
8697         {
8698           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8699             {
8700               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
8701                             &rx_sw_if_index))
8702                 rx_sw_if_index_set = 1;
8703             }
8704           else
8705             break;
8706         }
8707       else if (unformat (i, "tx"))
8708         {
8709           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8710             {
8711               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
8712                             &tx_sw_if_index))
8713                 tx_sw_if_index_set = 1;
8714             }
8715           else
8716             break;
8717         }
8718       else if (unformat (i, "del"))
8719         is_add = 0;
8720       else
8721         break;
8722     }
8723
8724   if (rx_sw_if_index_set == 0)
8725     {
8726       errmsg ("missing rx interface name or rx_sw_if_index");
8727       return -99;
8728     }
8729
8730   if (tx_sw_if_index_set == 0)
8731     {
8732       errmsg ("missing tx interface name or tx_sw_if_index");
8733       return -99;
8734     }
8735
8736   M (L2_PATCH_ADD_DEL, mp);
8737
8738   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
8739   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
8740   mp->is_add = is_add;
8741
8742   S (mp);
8743   W (ret);
8744   return ret;
8745 }
8746
8747 u8 is_del;
8748 u8 localsid_addr[16];
8749 u8 end_psp;
8750 u8 behavior;
8751 u32 sw_if_index;
8752 u32 vlan_index;
8753 u32 fib_table;
8754 u8 nh_addr[16];
8755
8756 static int
8757 api_sr_localsid_add_del (vat_main_t * vam)
8758 {
8759   unformat_input_t *i = vam->input;
8760   vl_api_sr_localsid_add_del_t *mp;
8761
8762   u8 is_del;
8763   ip6_address_t localsid;
8764   u8 end_psp = 0;
8765   u8 behavior = ~0;
8766   u32 sw_if_index;
8767   u32 fib_table = ~(u32) 0;
8768   ip6_address_t next_hop;
8769
8770   bool nexthop_set = 0;
8771
8772   int ret;
8773
8774   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8775     {
8776       if (unformat (i, "del"))
8777         is_del = 1;
8778       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
8779       else if (unformat (i, "next-hop %U", unformat_ip6_address, &next_hop))
8780         nexthop_set = 1;
8781       else if (unformat (i, "behavior %u", &behavior));
8782       else if (unformat (i, "sw_if_index %u", &sw_if_index));
8783       else if (unformat (i, "fib-table %u", &fib_table));
8784       else if (unformat (i, "end.psp %u", &behavior));
8785       else
8786         break;
8787     }
8788
8789   M (SR_LOCALSID_ADD_DEL, mp);
8790
8791   clib_memcpy (mp->localsid_addr, &localsid, sizeof (mp->localsid_addr));
8792   if (nexthop_set)
8793     clib_memcpy (mp->nh_addr, &next_hop, sizeof (mp->nh_addr));
8794   mp->behavior = behavior;
8795   mp->sw_if_index = ntohl (sw_if_index);
8796   mp->fib_table = ntohl (fib_table);
8797   mp->end_psp = end_psp;
8798   mp->is_del = is_del;
8799
8800   S (mp);
8801   W (ret);
8802   return ret;
8803 }
8804
8805 static int
8806 api_ioam_enable (vat_main_t * vam)
8807 {
8808   unformat_input_t *input = vam->input;
8809   vl_api_ioam_enable_t *mp;
8810   u32 id = 0;
8811   int has_trace_option = 0;
8812   int has_pot_option = 0;
8813   int has_seqno_option = 0;
8814   int has_analyse_option = 0;
8815   int ret;
8816
8817   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8818     {
8819       if (unformat (input, "trace"))
8820         has_trace_option = 1;
8821       else if (unformat (input, "pot"))
8822         has_pot_option = 1;
8823       else if (unformat (input, "seqno"))
8824         has_seqno_option = 1;
8825       else if (unformat (input, "analyse"))
8826         has_analyse_option = 1;
8827       else
8828         break;
8829     }
8830   M (IOAM_ENABLE, mp);
8831   mp->id = htons (id);
8832   mp->seqno = has_seqno_option;
8833   mp->analyse = has_analyse_option;
8834   mp->pot_enable = has_pot_option;
8835   mp->trace_enable = has_trace_option;
8836
8837   S (mp);
8838   W (ret);
8839   return ret;
8840 }
8841
8842
8843 static int
8844 api_ioam_disable (vat_main_t * vam)
8845 {
8846   vl_api_ioam_disable_t *mp;
8847   int ret;
8848
8849   M (IOAM_DISABLE, mp);
8850   S (mp);
8851   W (ret);
8852   return ret;
8853 }
8854
8855 #define foreach_tcp_proto_field                 \
8856 _(src_port)                                     \
8857 _(dst_port)
8858
8859 #define foreach_udp_proto_field                 \
8860 _(src_port)                                     \
8861 _(dst_port)
8862
8863 #define foreach_ip4_proto_field                 \
8864 _(src_address)                                  \
8865 _(dst_address)                                  \
8866 _(tos)                                          \
8867 _(length)                                       \
8868 _(fragment_id)                                  \
8869 _(ttl)                                          \
8870 _(protocol)                                     \
8871 _(checksum)
8872
8873 typedef struct
8874 {
8875   u16 src_port, dst_port;
8876 } tcpudp_header_t;
8877
8878 #if VPP_API_TEST_BUILTIN == 0
8879 uword
8880 unformat_tcp_mask (unformat_input_t * input, va_list * args)
8881 {
8882   u8 **maskp = va_arg (*args, u8 **);
8883   u8 *mask = 0;
8884   u8 found_something = 0;
8885   tcp_header_t *tcp;
8886
8887 #define _(a) u8 a=0;
8888   foreach_tcp_proto_field;
8889 #undef _
8890
8891   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8892     {
8893       if (0);
8894 #define _(a) else if (unformat (input, #a)) a=1;
8895       foreach_tcp_proto_field
8896 #undef _
8897         else
8898         break;
8899     }
8900
8901 #define _(a) found_something += a;
8902   foreach_tcp_proto_field;
8903 #undef _
8904
8905   if (found_something == 0)
8906     return 0;
8907
8908   vec_validate (mask, sizeof (*tcp) - 1);
8909
8910   tcp = (tcp_header_t *) mask;
8911
8912 #define _(a) if (a) memset (&tcp->a, 0xff, sizeof (tcp->a));
8913   foreach_tcp_proto_field;
8914 #undef _
8915
8916   *maskp = mask;
8917   return 1;
8918 }
8919
8920 uword
8921 unformat_udp_mask (unformat_input_t * input, va_list * args)
8922 {
8923   u8 **maskp = va_arg (*args, u8 **);
8924   u8 *mask = 0;
8925   u8 found_something = 0;
8926   udp_header_t *udp;
8927
8928 #define _(a) u8 a=0;
8929   foreach_udp_proto_field;
8930 #undef _
8931
8932   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8933     {
8934       if (0);
8935 #define _(a) else if (unformat (input, #a)) a=1;
8936       foreach_udp_proto_field
8937 #undef _
8938         else
8939         break;
8940     }
8941
8942 #define _(a) found_something += a;
8943   foreach_udp_proto_field;
8944 #undef _
8945
8946   if (found_something == 0)
8947     return 0;
8948
8949   vec_validate (mask, sizeof (*udp) - 1);
8950
8951   udp = (udp_header_t *) mask;
8952
8953 #define _(a) if (a) memset (&udp->a, 0xff, sizeof (udp->a));
8954   foreach_udp_proto_field;
8955 #undef _
8956
8957   *maskp = mask;
8958   return 1;
8959 }
8960
8961 uword
8962 unformat_l4_mask (unformat_input_t * input, va_list * args)
8963 {
8964   u8 **maskp = va_arg (*args, u8 **);
8965   u16 src_port = 0, dst_port = 0;
8966   tcpudp_header_t *tcpudp;
8967
8968   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8969     {
8970       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
8971         return 1;
8972       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
8973         return 1;
8974       else if (unformat (input, "src_port"))
8975         src_port = 0xFFFF;
8976       else if (unformat (input, "dst_port"))
8977         dst_port = 0xFFFF;
8978       else
8979         return 0;
8980     }
8981
8982   if (!src_port && !dst_port)
8983     return 0;
8984
8985   u8 *mask = 0;
8986   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
8987
8988   tcpudp = (tcpudp_header_t *) mask;
8989   tcpudp->src_port = src_port;
8990   tcpudp->dst_port = dst_port;
8991
8992   *maskp = mask;
8993
8994   return 1;
8995 }
8996
8997 uword
8998 unformat_ip4_mask (unformat_input_t * input, va_list * args)
8999 {
9000   u8 **maskp = va_arg (*args, u8 **);
9001   u8 *mask = 0;
9002   u8 found_something = 0;
9003   ip4_header_t *ip;
9004
9005 #define _(a) u8 a=0;
9006   foreach_ip4_proto_field;
9007 #undef _
9008   u8 version = 0;
9009   u8 hdr_length = 0;
9010
9011
9012   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9013     {
9014       if (unformat (input, "version"))
9015         version = 1;
9016       else if (unformat (input, "hdr_length"))
9017         hdr_length = 1;
9018       else if (unformat (input, "src"))
9019         src_address = 1;
9020       else if (unformat (input, "dst"))
9021         dst_address = 1;
9022       else if (unformat (input, "proto"))
9023         protocol = 1;
9024
9025 #define _(a) else if (unformat (input, #a)) a=1;
9026       foreach_ip4_proto_field
9027 #undef _
9028         else
9029         break;
9030     }
9031
9032 #define _(a) found_something += a;
9033   foreach_ip4_proto_field;
9034 #undef _
9035
9036   if (found_something == 0)
9037     return 0;
9038
9039   vec_validate (mask, sizeof (*ip) - 1);
9040
9041   ip = (ip4_header_t *) mask;
9042
9043 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
9044   foreach_ip4_proto_field;
9045 #undef _
9046
9047   ip->ip_version_and_header_length = 0;
9048
9049   if (version)
9050     ip->ip_version_and_header_length |= 0xF0;
9051
9052   if (hdr_length)
9053     ip->ip_version_and_header_length |= 0x0F;
9054
9055   *maskp = mask;
9056   return 1;
9057 }
9058
9059 #define foreach_ip6_proto_field                 \
9060 _(src_address)                                  \
9061 _(dst_address)                                  \
9062 _(payload_length)                               \
9063 _(hop_limit)                                    \
9064 _(protocol)
9065
9066 uword
9067 unformat_ip6_mask (unformat_input_t * input, va_list * args)
9068 {
9069   u8 **maskp = va_arg (*args, u8 **);
9070   u8 *mask = 0;
9071   u8 found_something = 0;
9072   ip6_header_t *ip;
9073   u32 ip_version_traffic_class_and_flow_label;
9074
9075 #define _(a) u8 a=0;
9076   foreach_ip6_proto_field;
9077 #undef _
9078   u8 version = 0;
9079   u8 traffic_class = 0;
9080   u8 flow_label = 0;
9081
9082   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9083     {
9084       if (unformat (input, "version"))
9085         version = 1;
9086       else if (unformat (input, "traffic-class"))
9087         traffic_class = 1;
9088       else if (unformat (input, "flow-label"))
9089         flow_label = 1;
9090       else if (unformat (input, "src"))
9091         src_address = 1;
9092       else if (unformat (input, "dst"))
9093         dst_address = 1;
9094       else if (unformat (input, "proto"))
9095         protocol = 1;
9096
9097 #define _(a) else if (unformat (input, #a)) a=1;
9098       foreach_ip6_proto_field
9099 #undef _
9100         else
9101         break;
9102     }
9103
9104 #define _(a) found_something += a;
9105   foreach_ip6_proto_field;
9106 #undef _
9107
9108   if (found_something == 0)
9109     return 0;
9110
9111   vec_validate (mask, sizeof (*ip) - 1);
9112
9113   ip = (ip6_header_t *) mask;
9114
9115 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
9116   foreach_ip6_proto_field;
9117 #undef _
9118
9119   ip_version_traffic_class_and_flow_label = 0;
9120
9121   if (version)
9122     ip_version_traffic_class_and_flow_label |= 0xF0000000;
9123
9124   if (traffic_class)
9125     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
9126
9127   if (flow_label)
9128     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
9129
9130   ip->ip_version_traffic_class_and_flow_label =
9131     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
9132
9133   *maskp = mask;
9134   return 1;
9135 }
9136
9137 uword
9138 unformat_l3_mask (unformat_input_t * input, va_list * args)
9139 {
9140   u8 **maskp = va_arg (*args, u8 **);
9141
9142   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9143     {
9144       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
9145         return 1;
9146       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
9147         return 1;
9148       else
9149         break;
9150     }
9151   return 0;
9152 }
9153
9154 uword
9155 unformat_l2_mask (unformat_input_t * input, va_list * args)
9156 {
9157   u8 **maskp = va_arg (*args, u8 **);
9158   u8 *mask = 0;
9159   u8 src = 0;
9160   u8 dst = 0;
9161   u8 proto = 0;
9162   u8 tag1 = 0;
9163   u8 tag2 = 0;
9164   u8 ignore_tag1 = 0;
9165   u8 ignore_tag2 = 0;
9166   u8 cos1 = 0;
9167   u8 cos2 = 0;
9168   u8 dot1q = 0;
9169   u8 dot1ad = 0;
9170   int len = 14;
9171
9172   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9173     {
9174       if (unformat (input, "src"))
9175         src = 1;
9176       else if (unformat (input, "dst"))
9177         dst = 1;
9178       else if (unformat (input, "proto"))
9179         proto = 1;
9180       else if (unformat (input, "tag1"))
9181         tag1 = 1;
9182       else if (unformat (input, "tag2"))
9183         tag2 = 1;
9184       else if (unformat (input, "ignore-tag1"))
9185         ignore_tag1 = 1;
9186       else if (unformat (input, "ignore-tag2"))
9187         ignore_tag2 = 1;
9188       else if (unformat (input, "cos1"))
9189         cos1 = 1;
9190       else if (unformat (input, "cos2"))
9191         cos2 = 1;
9192       else if (unformat (input, "dot1q"))
9193         dot1q = 1;
9194       else if (unformat (input, "dot1ad"))
9195         dot1ad = 1;
9196       else
9197         break;
9198     }
9199   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
9200        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
9201     return 0;
9202
9203   if (tag1 || ignore_tag1 || cos1 || dot1q)
9204     len = 18;
9205   if (tag2 || ignore_tag2 || cos2 || dot1ad)
9206     len = 22;
9207
9208   vec_validate (mask, len - 1);
9209
9210   if (dst)
9211     memset (mask, 0xff, 6);
9212
9213   if (src)
9214     memset (mask + 6, 0xff, 6);
9215
9216   if (tag2 || dot1ad)
9217     {
9218       /* inner vlan tag */
9219       if (tag2)
9220         {
9221           mask[19] = 0xff;
9222           mask[18] = 0x0f;
9223         }
9224       if (cos2)
9225         mask[18] |= 0xe0;
9226       if (proto)
9227         mask[21] = mask[20] = 0xff;
9228       if (tag1)
9229         {
9230           mask[15] = 0xff;
9231           mask[14] = 0x0f;
9232         }
9233       if (cos1)
9234         mask[14] |= 0xe0;
9235       *maskp = mask;
9236       return 1;
9237     }
9238   if (tag1 | dot1q)
9239     {
9240       if (tag1)
9241         {
9242           mask[15] = 0xff;
9243           mask[14] = 0x0f;
9244         }
9245       if (cos1)
9246         mask[14] |= 0xe0;
9247       if (proto)
9248         mask[16] = mask[17] = 0xff;
9249
9250       *maskp = mask;
9251       return 1;
9252     }
9253   if (cos2)
9254     mask[18] |= 0xe0;
9255   if (cos1)
9256     mask[14] |= 0xe0;
9257   if (proto)
9258     mask[12] = mask[13] = 0xff;
9259
9260   *maskp = mask;
9261   return 1;
9262 }
9263
9264 uword
9265 unformat_classify_mask (unformat_input_t * input, va_list * args)
9266 {
9267   u8 **maskp = va_arg (*args, u8 **);
9268   u32 *skipp = va_arg (*args, u32 *);
9269   u32 *matchp = va_arg (*args, u32 *);
9270   u32 match;
9271   u8 *mask = 0;
9272   u8 *l2 = 0;
9273   u8 *l3 = 0;
9274   u8 *l4 = 0;
9275   int i;
9276
9277   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9278     {
9279       if (unformat (input, "hex %U", unformat_hex_string, &mask))
9280         ;
9281       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
9282         ;
9283       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
9284         ;
9285       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
9286         ;
9287       else
9288         break;
9289     }
9290
9291   if (l4 && !l3)
9292     {
9293       vec_free (mask);
9294       vec_free (l2);
9295       vec_free (l4);
9296       return 0;
9297     }
9298
9299   if (mask || l2 || l3 || l4)
9300     {
9301       if (l2 || l3 || l4)
9302         {
9303           /* "With a free Ethernet header in every package" */
9304           if (l2 == 0)
9305             vec_validate (l2, 13);
9306           mask = l2;
9307           if (vec_len (l3))
9308             {
9309               vec_append (mask, l3);
9310               vec_free (l3);
9311             }
9312           if (vec_len (l4))
9313             {
9314               vec_append (mask, l4);
9315               vec_free (l4);
9316             }
9317         }
9318
9319       /* Scan forward looking for the first significant mask octet */
9320       for (i = 0; i < vec_len (mask); i++)
9321         if (mask[i])
9322           break;
9323
9324       /* compute (skip, match) params */
9325       *skipp = i / sizeof (u32x4);
9326       vec_delete (mask, *skipp * sizeof (u32x4), 0);
9327
9328       /* Pad mask to an even multiple of the vector size */
9329       while (vec_len (mask) % sizeof (u32x4))
9330         vec_add1 (mask, 0);
9331
9332       match = vec_len (mask) / sizeof (u32x4);
9333
9334       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
9335         {
9336           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
9337           if (*tmp || *(tmp + 1))
9338             break;
9339           match--;
9340         }
9341       if (match == 0)
9342         clib_warning ("BUG: match 0");
9343
9344       _vec_len (mask) = match * sizeof (u32x4);
9345
9346       *matchp = match;
9347       *maskp = mask;
9348
9349       return 1;
9350     }
9351
9352   return 0;
9353 }
9354 #endif /* VPP_API_TEST_BUILTIN */
9355
9356 #define foreach_l2_next                         \
9357 _(drop, DROP)                                   \
9358 _(ethernet, ETHERNET_INPUT)                     \
9359 _(ip4, IP4_INPUT)                               \
9360 _(ip6, IP6_INPUT)
9361
9362 uword
9363 unformat_l2_next_index (unformat_input_t * input, va_list * args)
9364 {
9365   u32 *miss_next_indexp = va_arg (*args, u32 *);
9366   u32 next_index = 0;
9367   u32 tmp;
9368
9369 #define _(n,N) \
9370   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
9371   foreach_l2_next;
9372 #undef _
9373
9374   if (unformat (input, "%d", &tmp))
9375     {
9376       next_index = tmp;
9377       goto out;
9378     }
9379
9380   return 0;
9381
9382 out:
9383   *miss_next_indexp = next_index;
9384   return 1;
9385 }
9386
9387 #define foreach_ip_next                         \
9388 _(drop, DROP)                                   \
9389 _(local, LOCAL)                                 \
9390 _(rewrite, REWRITE)
9391
9392 uword
9393 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
9394 {
9395   u32 *miss_next_indexp = va_arg (*args, u32 *);
9396   u32 next_index = 0;
9397   u32 tmp;
9398
9399 #define _(n,N) \
9400   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
9401   foreach_ip_next;
9402 #undef _
9403
9404   if (unformat (input, "%d", &tmp))
9405     {
9406       next_index = tmp;
9407       goto out;
9408     }
9409
9410   return 0;
9411
9412 out:
9413   *miss_next_indexp = next_index;
9414   return 1;
9415 }
9416
9417 #define foreach_acl_next                        \
9418 _(deny, DENY)
9419
9420 uword
9421 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
9422 {
9423   u32 *miss_next_indexp = va_arg (*args, u32 *);
9424   u32 next_index = 0;
9425   u32 tmp;
9426
9427 #define _(n,N) \
9428   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
9429   foreach_acl_next;
9430 #undef _
9431
9432   if (unformat (input, "permit"))
9433     {
9434       next_index = ~0;
9435       goto out;
9436     }
9437   else if (unformat (input, "%d", &tmp))
9438     {
9439       next_index = tmp;
9440       goto out;
9441     }
9442
9443   return 0;
9444
9445 out:
9446   *miss_next_indexp = next_index;
9447   return 1;
9448 }
9449
9450 uword
9451 unformat_policer_precolor (unformat_input_t * input, va_list * args)
9452 {
9453   u32 *r = va_arg (*args, u32 *);
9454
9455   if (unformat (input, "conform-color"))
9456     *r = POLICE_CONFORM;
9457   else if (unformat (input, "exceed-color"))
9458     *r = POLICE_EXCEED;
9459   else
9460     return 0;
9461
9462   return 1;
9463 }
9464
9465 static int
9466 api_classify_add_del_table (vat_main_t * vam)
9467 {
9468   unformat_input_t *i = vam->input;
9469   vl_api_classify_add_del_table_t *mp;
9470
9471   u32 nbuckets = 2;
9472   u32 skip = ~0;
9473   u32 match = ~0;
9474   int is_add = 1;
9475   int del_chain = 0;
9476   u32 table_index = ~0;
9477   u32 next_table_index = ~0;
9478   u32 miss_next_index = ~0;
9479   u32 memory_size = 32 << 20;
9480   u8 *mask = 0;
9481   u32 current_data_flag = 0;
9482   int current_data_offset = 0;
9483   int ret;
9484
9485   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9486     {
9487       if (unformat (i, "del"))
9488         is_add = 0;
9489       else if (unformat (i, "del-chain"))
9490         {
9491           is_add = 0;
9492           del_chain = 1;
9493         }
9494       else if (unformat (i, "buckets %d", &nbuckets))
9495         ;
9496       else if (unformat (i, "memory_size %d", &memory_size))
9497         ;
9498       else if (unformat (i, "skip %d", &skip))
9499         ;
9500       else if (unformat (i, "match %d", &match))
9501         ;
9502       else if (unformat (i, "table %d", &table_index))
9503         ;
9504       else if (unformat (i, "mask %U", unformat_classify_mask,
9505                          &mask, &skip, &match))
9506         ;
9507       else if (unformat (i, "next-table %d", &next_table_index))
9508         ;
9509       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
9510                          &miss_next_index))
9511         ;
9512       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
9513                          &miss_next_index))
9514         ;
9515       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
9516                          &miss_next_index))
9517         ;
9518       else if (unformat (i, "current-data-flag %d", &current_data_flag))
9519         ;
9520       else if (unformat (i, "current-data-offset %d", &current_data_offset))
9521         ;
9522       else
9523         break;
9524     }
9525
9526   if (is_add && mask == 0)
9527     {
9528       errmsg ("Mask required");
9529       return -99;
9530     }
9531
9532   if (is_add && skip == ~0)
9533     {
9534       errmsg ("skip count required");
9535       return -99;
9536     }
9537
9538   if (is_add && match == ~0)
9539     {
9540       errmsg ("match count required");
9541       return -99;
9542     }
9543
9544   if (!is_add && table_index == ~0)
9545     {
9546       errmsg ("table index required for delete");
9547       return -99;
9548     }
9549
9550   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
9551
9552   mp->is_add = is_add;
9553   mp->del_chain = del_chain;
9554   mp->table_index = ntohl (table_index);
9555   mp->nbuckets = ntohl (nbuckets);
9556   mp->memory_size = ntohl (memory_size);
9557   mp->skip_n_vectors = ntohl (skip);
9558   mp->match_n_vectors = ntohl (match);
9559   mp->next_table_index = ntohl (next_table_index);
9560   mp->miss_next_index = ntohl (miss_next_index);
9561   mp->current_data_flag = ntohl (current_data_flag);
9562   mp->current_data_offset = ntohl (current_data_offset);
9563   clib_memcpy (mp->mask, mask, vec_len (mask));
9564
9565   vec_free (mask);
9566
9567   S (mp);
9568   W (ret);
9569   return ret;
9570 }
9571
9572 #if VPP_API_TEST_BUILTIN == 0
9573 uword
9574 unformat_l4_match (unformat_input_t * input, va_list * args)
9575 {
9576   u8 **matchp = va_arg (*args, u8 **);
9577
9578   u8 *proto_header = 0;
9579   int src_port = 0;
9580   int dst_port = 0;
9581
9582   tcpudp_header_t h;
9583
9584   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9585     {
9586       if (unformat (input, "src_port %d", &src_port))
9587         ;
9588       else if (unformat (input, "dst_port %d", &dst_port))
9589         ;
9590       else
9591         return 0;
9592     }
9593
9594   h.src_port = clib_host_to_net_u16 (src_port);
9595   h.dst_port = clib_host_to_net_u16 (dst_port);
9596   vec_validate (proto_header, sizeof (h) - 1);
9597   memcpy (proto_header, &h, sizeof (h));
9598
9599   *matchp = proto_header;
9600
9601   return 1;
9602 }
9603
9604 uword
9605 unformat_ip4_match (unformat_input_t * input, va_list * args)
9606 {
9607   u8 **matchp = va_arg (*args, u8 **);
9608   u8 *match = 0;
9609   ip4_header_t *ip;
9610   int version = 0;
9611   u32 version_val;
9612   int hdr_length = 0;
9613   u32 hdr_length_val;
9614   int src = 0, dst = 0;
9615   ip4_address_t src_val, dst_val;
9616   int proto = 0;
9617   u32 proto_val;
9618   int tos = 0;
9619   u32 tos_val;
9620   int length = 0;
9621   u32 length_val;
9622   int fragment_id = 0;
9623   u32 fragment_id_val;
9624   int ttl = 0;
9625   int ttl_val;
9626   int checksum = 0;
9627   u32 checksum_val;
9628
9629   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9630     {
9631       if (unformat (input, "version %d", &version_val))
9632         version = 1;
9633       else if (unformat (input, "hdr_length %d", &hdr_length_val))
9634         hdr_length = 1;
9635       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
9636         src = 1;
9637       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
9638         dst = 1;
9639       else if (unformat (input, "proto %d", &proto_val))
9640         proto = 1;
9641       else if (unformat (input, "tos %d", &tos_val))
9642         tos = 1;
9643       else if (unformat (input, "length %d", &length_val))
9644         length = 1;
9645       else if (unformat (input, "fragment_id %d", &fragment_id_val))
9646         fragment_id = 1;
9647       else if (unformat (input, "ttl %d", &ttl_val))
9648         ttl = 1;
9649       else if (unformat (input, "checksum %d", &checksum_val))
9650         checksum = 1;
9651       else
9652         break;
9653     }
9654
9655   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
9656       + ttl + checksum == 0)
9657     return 0;
9658
9659   /*
9660    * Aligned because we use the real comparison functions
9661    */
9662   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
9663
9664   ip = (ip4_header_t *) match;
9665
9666   /* These are realistically matched in practice */
9667   if (src)
9668     ip->src_address.as_u32 = src_val.as_u32;
9669
9670   if (dst)
9671     ip->dst_address.as_u32 = dst_val.as_u32;
9672
9673   if (proto)
9674     ip->protocol = proto_val;
9675
9676
9677   /* These are not, but they're included for completeness */
9678   if (version)
9679     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
9680
9681   if (hdr_length)
9682     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
9683
9684   if (tos)
9685     ip->tos = tos_val;
9686
9687   if (length)
9688     ip->length = clib_host_to_net_u16 (length_val);
9689
9690   if (ttl)
9691     ip->ttl = ttl_val;
9692
9693   if (checksum)
9694     ip->checksum = clib_host_to_net_u16 (checksum_val);
9695
9696   *matchp = match;
9697   return 1;
9698 }
9699
9700 uword
9701 unformat_ip6_match (unformat_input_t * input, va_list * args)
9702 {
9703   u8 **matchp = va_arg (*args, u8 **);
9704   u8 *match = 0;
9705   ip6_header_t *ip;
9706   int version = 0;
9707   u32 version_val;
9708   u8 traffic_class = 0;
9709   u32 traffic_class_val = 0;
9710   u8 flow_label = 0;
9711   u8 flow_label_val;
9712   int src = 0, dst = 0;
9713   ip6_address_t src_val, dst_val;
9714   int proto = 0;
9715   u32 proto_val;
9716   int payload_length = 0;
9717   u32 payload_length_val;
9718   int hop_limit = 0;
9719   int hop_limit_val;
9720   u32 ip_version_traffic_class_and_flow_label;
9721
9722   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9723     {
9724       if (unformat (input, "version %d", &version_val))
9725         version = 1;
9726       else if (unformat (input, "traffic_class %d", &traffic_class_val))
9727         traffic_class = 1;
9728       else if (unformat (input, "flow_label %d", &flow_label_val))
9729         flow_label = 1;
9730       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
9731         src = 1;
9732       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
9733         dst = 1;
9734       else if (unformat (input, "proto %d", &proto_val))
9735         proto = 1;
9736       else if (unformat (input, "payload_length %d", &payload_length_val))
9737         payload_length = 1;
9738       else if (unformat (input, "hop_limit %d", &hop_limit_val))
9739         hop_limit = 1;
9740       else
9741         break;
9742     }
9743
9744   if (version + traffic_class + flow_label + src + dst + proto +
9745       payload_length + hop_limit == 0)
9746     return 0;
9747
9748   /*
9749    * Aligned because we use the real comparison functions
9750    */
9751   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
9752
9753   ip = (ip6_header_t *) match;
9754
9755   if (src)
9756     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
9757
9758   if (dst)
9759     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
9760
9761   if (proto)
9762     ip->protocol = proto_val;
9763
9764   ip_version_traffic_class_and_flow_label = 0;
9765
9766   if (version)
9767     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
9768
9769   if (traffic_class)
9770     ip_version_traffic_class_and_flow_label |=
9771       (traffic_class_val & 0xFF) << 20;
9772
9773   if (flow_label)
9774     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
9775
9776   ip->ip_version_traffic_class_and_flow_label =
9777     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
9778
9779   if (payload_length)
9780     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
9781
9782   if (hop_limit)
9783     ip->hop_limit = hop_limit_val;
9784
9785   *matchp = match;
9786   return 1;
9787 }
9788
9789 uword
9790 unformat_l3_match (unformat_input_t * input, va_list * args)
9791 {
9792   u8 **matchp = va_arg (*args, u8 **);
9793
9794   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9795     {
9796       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
9797         return 1;
9798       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
9799         return 1;
9800       else
9801         break;
9802     }
9803   return 0;
9804 }
9805
9806 uword
9807 unformat_vlan_tag (unformat_input_t * input, va_list * args)
9808 {
9809   u8 *tagp = va_arg (*args, u8 *);
9810   u32 tag;
9811
9812   if (unformat (input, "%d", &tag))
9813     {
9814       tagp[0] = (tag >> 8) & 0x0F;
9815       tagp[1] = tag & 0xFF;
9816       return 1;
9817     }
9818
9819   return 0;
9820 }
9821
9822 uword
9823 unformat_l2_match (unformat_input_t * input, va_list * args)
9824 {
9825   u8 **matchp = va_arg (*args, u8 **);
9826   u8 *match = 0;
9827   u8 src = 0;
9828   u8 src_val[6];
9829   u8 dst = 0;
9830   u8 dst_val[6];
9831   u8 proto = 0;
9832   u16 proto_val;
9833   u8 tag1 = 0;
9834   u8 tag1_val[2];
9835   u8 tag2 = 0;
9836   u8 tag2_val[2];
9837   int len = 14;
9838   u8 ignore_tag1 = 0;
9839   u8 ignore_tag2 = 0;
9840   u8 cos1 = 0;
9841   u8 cos2 = 0;
9842   u32 cos1_val = 0;
9843   u32 cos2_val = 0;
9844
9845   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9846     {
9847       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
9848         src = 1;
9849       else
9850         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
9851         dst = 1;
9852       else if (unformat (input, "proto %U",
9853                          unformat_ethernet_type_host_byte_order, &proto_val))
9854         proto = 1;
9855       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
9856         tag1 = 1;
9857       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
9858         tag2 = 1;
9859       else if (unformat (input, "ignore-tag1"))
9860         ignore_tag1 = 1;
9861       else if (unformat (input, "ignore-tag2"))
9862         ignore_tag2 = 1;
9863       else if (unformat (input, "cos1 %d", &cos1_val))
9864         cos1 = 1;
9865       else if (unformat (input, "cos2 %d", &cos2_val))
9866         cos2 = 1;
9867       else
9868         break;
9869     }
9870   if ((src + dst + proto + tag1 + tag2 +
9871        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
9872     return 0;
9873
9874   if (tag1 || ignore_tag1 || cos1)
9875     len = 18;
9876   if (tag2 || ignore_tag2 || cos2)
9877     len = 22;
9878
9879   vec_validate_aligned (match, len - 1, sizeof (u32x4));
9880
9881   if (dst)
9882     clib_memcpy (match, dst_val, 6);
9883
9884   if (src)
9885     clib_memcpy (match + 6, src_val, 6);
9886
9887   if (tag2)
9888     {
9889       /* inner vlan tag */
9890       match[19] = tag2_val[1];
9891       match[18] = tag2_val[0];
9892       if (cos2)
9893         match[18] |= (cos2_val & 0x7) << 5;
9894       if (proto)
9895         {
9896           match[21] = proto_val & 0xff;
9897           match[20] = proto_val >> 8;
9898         }
9899       if (tag1)
9900         {
9901           match[15] = tag1_val[1];
9902           match[14] = tag1_val[0];
9903         }
9904       if (cos1)
9905         match[14] |= (cos1_val & 0x7) << 5;
9906       *matchp = match;
9907       return 1;
9908     }
9909   if (tag1)
9910     {
9911       match[15] = tag1_val[1];
9912       match[14] = tag1_val[0];
9913       if (proto)
9914         {
9915           match[17] = proto_val & 0xff;
9916           match[16] = proto_val >> 8;
9917         }
9918       if (cos1)
9919         match[14] |= (cos1_val & 0x7) << 5;
9920
9921       *matchp = match;
9922       return 1;
9923     }
9924   if (cos2)
9925     match[18] |= (cos2_val & 0x7) << 5;
9926   if (cos1)
9927     match[14] |= (cos1_val & 0x7) << 5;
9928   if (proto)
9929     {
9930       match[13] = proto_val & 0xff;
9931       match[12] = proto_val >> 8;
9932     }
9933
9934   *matchp = match;
9935   return 1;
9936 }
9937 #endif
9938
9939 uword
9940 api_unformat_classify_match (unformat_input_t * input, va_list * args)
9941 {
9942   u8 **matchp = va_arg (*args, u8 **);
9943   u32 skip_n_vectors = va_arg (*args, u32);
9944   u32 match_n_vectors = va_arg (*args, u32);
9945
9946   u8 *match = 0;
9947   u8 *l2 = 0;
9948   u8 *l3 = 0;
9949   u8 *l4 = 0;
9950
9951   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9952     {
9953       if (unformat (input, "hex %U", unformat_hex_string, &match))
9954         ;
9955       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
9956         ;
9957       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
9958         ;
9959       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
9960         ;
9961       else
9962         break;
9963     }
9964
9965   if (l4 && !l3)
9966     {
9967       vec_free (match);
9968       vec_free (l2);
9969       vec_free (l4);
9970       return 0;
9971     }
9972
9973   if (match || l2 || l3 || l4)
9974     {
9975       if (l2 || l3 || l4)
9976         {
9977           /* "Win a free Ethernet header in every packet" */
9978           if (l2 == 0)
9979             vec_validate_aligned (l2, 13, sizeof (u32x4));
9980           match = l2;
9981           if (vec_len (l3))
9982             {
9983               vec_append_aligned (match, l3, sizeof (u32x4));
9984               vec_free (l3);
9985             }
9986           if (vec_len (l4))
9987             {
9988               vec_append_aligned (match, l4, sizeof (u32x4));
9989               vec_free (l4);
9990             }
9991         }
9992
9993       /* Make sure the vector is big enough even if key is all 0's */
9994       vec_validate_aligned
9995         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
9996          sizeof (u32x4));
9997
9998       /* Set size, include skipped vectors */
9999       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
10000
10001       *matchp = match;
10002
10003       return 1;
10004     }
10005
10006   return 0;
10007 }
10008
10009 static int
10010 api_classify_add_del_session (vat_main_t * vam)
10011 {
10012   unformat_input_t *i = vam->input;
10013   vl_api_classify_add_del_session_t *mp;
10014   int is_add = 1;
10015   u32 table_index = ~0;
10016   u32 hit_next_index = ~0;
10017   u32 opaque_index = ~0;
10018   u8 *match = 0;
10019   i32 advance = 0;
10020   u32 skip_n_vectors = 0;
10021   u32 match_n_vectors = 0;
10022   u32 action = 0;
10023   u32 metadata = 0;
10024   int ret;
10025
10026   /*
10027    * Warning: you have to supply skip_n and match_n
10028    * because the API client cant simply look at the classify
10029    * table object.
10030    */
10031
10032   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10033     {
10034       if (unformat (i, "del"))
10035         is_add = 0;
10036       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
10037                          &hit_next_index))
10038         ;
10039       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
10040                          &hit_next_index))
10041         ;
10042       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
10043                          &hit_next_index))
10044         ;
10045       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
10046         ;
10047       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
10048         ;
10049       else if (unformat (i, "opaque-index %d", &opaque_index))
10050         ;
10051       else if (unformat (i, "skip_n %d", &skip_n_vectors))
10052         ;
10053       else if (unformat (i, "match_n %d", &match_n_vectors))
10054         ;
10055       else if (unformat (i, "match %U", api_unformat_classify_match,
10056                          &match, skip_n_vectors, match_n_vectors))
10057         ;
10058       else if (unformat (i, "advance %d", &advance))
10059         ;
10060       else if (unformat (i, "table-index %d", &table_index))
10061         ;
10062       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
10063         action = 1;
10064       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
10065         action = 2;
10066       else if (unformat (i, "action %d", &action))
10067         ;
10068       else if (unformat (i, "metadata %d", &metadata))
10069         ;
10070       else
10071         break;
10072     }
10073
10074   if (table_index == ~0)
10075     {
10076       errmsg ("Table index required");
10077       return -99;
10078     }
10079
10080   if (is_add && match == 0)
10081     {
10082       errmsg ("Match value required");
10083       return -99;
10084     }
10085
10086   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
10087
10088   mp->is_add = is_add;
10089   mp->table_index = ntohl (table_index);
10090   mp->hit_next_index = ntohl (hit_next_index);
10091   mp->opaque_index = ntohl (opaque_index);
10092   mp->advance = ntohl (advance);
10093   mp->action = action;
10094   mp->metadata = ntohl (metadata);
10095   clib_memcpy (mp->match, match, vec_len (match));
10096   vec_free (match);
10097
10098   S (mp);
10099   W (ret);
10100   return ret;
10101 }
10102
10103 static int
10104 api_classify_set_interface_ip_table (vat_main_t * vam)
10105 {
10106   unformat_input_t *i = vam->input;
10107   vl_api_classify_set_interface_ip_table_t *mp;
10108   u32 sw_if_index;
10109   int sw_if_index_set;
10110   u32 table_index = ~0;
10111   u8 is_ipv6 = 0;
10112   int ret;
10113
10114   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10115     {
10116       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10117         sw_if_index_set = 1;
10118       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10119         sw_if_index_set = 1;
10120       else if (unformat (i, "table %d", &table_index))
10121         ;
10122       else
10123         {
10124           clib_warning ("parse error '%U'", format_unformat_error, i);
10125           return -99;
10126         }
10127     }
10128
10129   if (sw_if_index_set == 0)
10130     {
10131       errmsg ("missing interface name or sw_if_index");
10132       return -99;
10133     }
10134
10135
10136   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
10137
10138   mp->sw_if_index = ntohl (sw_if_index);
10139   mp->table_index = ntohl (table_index);
10140   mp->is_ipv6 = is_ipv6;
10141
10142   S (mp);
10143   W (ret);
10144   return ret;
10145 }
10146
10147 static int
10148 api_classify_set_interface_l2_tables (vat_main_t * vam)
10149 {
10150   unformat_input_t *i = vam->input;
10151   vl_api_classify_set_interface_l2_tables_t *mp;
10152   u32 sw_if_index;
10153   int sw_if_index_set;
10154   u32 ip4_table_index = ~0;
10155   u32 ip6_table_index = ~0;
10156   u32 other_table_index = ~0;
10157   u32 is_input = 1;
10158   int ret;
10159
10160   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10161     {
10162       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10163         sw_if_index_set = 1;
10164       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10165         sw_if_index_set = 1;
10166       else if (unformat (i, "ip4-table %d", &ip4_table_index))
10167         ;
10168       else if (unformat (i, "ip6-table %d", &ip6_table_index))
10169         ;
10170       else if (unformat (i, "other-table %d", &other_table_index))
10171         ;
10172       else if (unformat (i, "is-input %d", &is_input))
10173         ;
10174       else
10175         {
10176           clib_warning ("parse error '%U'", format_unformat_error, i);
10177           return -99;
10178         }
10179     }
10180
10181   if (sw_if_index_set == 0)
10182     {
10183       errmsg ("missing interface name or sw_if_index");
10184       return -99;
10185     }
10186
10187
10188   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
10189
10190   mp->sw_if_index = ntohl (sw_if_index);
10191   mp->ip4_table_index = ntohl (ip4_table_index);
10192   mp->ip6_table_index = ntohl (ip6_table_index);
10193   mp->other_table_index = ntohl (other_table_index);
10194   mp->is_input = (u8) is_input;
10195
10196   S (mp);
10197   W (ret);
10198   return ret;
10199 }
10200
10201 static int
10202 api_set_ipfix_exporter (vat_main_t * vam)
10203 {
10204   unformat_input_t *i = vam->input;
10205   vl_api_set_ipfix_exporter_t *mp;
10206   ip4_address_t collector_address;
10207   u8 collector_address_set = 0;
10208   u32 collector_port = ~0;
10209   ip4_address_t src_address;
10210   u8 src_address_set = 0;
10211   u32 vrf_id = ~0;
10212   u32 path_mtu = ~0;
10213   u32 template_interval = ~0;
10214   u8 udp_checksum = 0;
10215   int ret;
10216
10217   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10218     {
10219       if (unformat (i, "collector_address %U", unformat_ip4_address,
10220                     &collector_address))
10221         collector_address_set = 1;
10222       else if (unformat (i, "collector_port %d", &collector_port))
10223         ;
10224       else if (unformat (i, "src_address %U", unformat_ip4_address,
10225                          &src_address))
10226         src_address_set = 1;
10227       else if (unformat (i, "vrf_id %d", &vrf_id))
10228         ;
10229       else if (unformat (i, "path_mtu %d", &path_mtu))
10230         ;
10231       else if (unformat (i, "template_interval %d", &template_interval))
10232         ;
10233       else if (unformat (i, "udp_checksum"))
10234         udp_checksum = 1;
10235       else
10236         break;
10237     }
10238
10239   if (collector_address_set == 0)
10240     {
10241       errmsg ("collector_address required");
10242       return -99;
10243     }
10244
10245   if (src_address_set == 0)
10246     {
10247       errmsg ("src_address required");
10248       return -99;
10249     }
10250
10251   M (SET_IPFIX_EXPORTER, mp);
10252
10253   memcpy (mp->collector_address, collector_address.data,
10254           sizeof (collector_address.data));
10255   mp->collector_port = htons ((u16) collector_port);
10256   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
10257   mp->vrf_id = htonl (vrf_id);
10258   mp->path_mtu = htonl (path_mtu);
10259   mp->template_interval = htonl (template_interval);
10260   mp->udp_checksum = udp_checksum;
10261
10262   S (mp);
10263   W (ret);
10264   return ret;
10265 }
10266
10267 static int
10268 api_set_ipfix_classify_stream (vat_main_t * vam)
10269 {
10270   unformat_input_t *i = vam->input;
10271   vl_api_set_ipfix_classify_stream_t *mp;
10272   u32 domain_id = 0;
10273   u32 src_port = UDP_DST_PORT_ipfix;
10274   int ret;
10275
10276   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10277     {
10278       if (unformat (i, "domain %d", &domain_id))
10279         ;
10280       else if (unformat (i, "src_port %d", &src_port))
10281         ;
10282       else
10283         {
10284           errmsg ("unknown input `%U'", format_unformat_error, i);
10285           return -99;
10286         }
10287     }
10288
10289   M (SET_IPFIX_CLASSIFY_STREAM, mp);
10290
10291   mp->domain_id = htonl (domain_id);
10292   mp->src_port = htons ((u16) src_port);
10293
10294   S (mp);
10295   W (ret);
10296   return ret;
10297 }
10298
10299 static int
10300 api_ipfix_classify_table_add_del (vat_main_t * vam)
10301 {
10302   unformat_input_t *i = vam->input;
10303   vl_api_ipfix_classify_table_add_del_t *mp;
10304   int is_add = -1;
10305   u32 classify_table_index = ~0;
10306   u8 ip_version = 0;
10307   u8 transport_protocol = 255;
10308   int ret;
10309
10310   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10311     {
10312       if (unformat (i, "add"))
10313         is_add = 1;
10314       else if (unformat (i, "del"))
10315         is_add = 0;
10316       else if (unformat (i, "table %d", &classify_table_index))
10317         ;
10318       else if (unformat (i, "ip4"))
10319         ip_version = 4;
10320       else if (unformat (i, "ip6"))
10321         ip_version = 6;
10322       else if (unformat (i, "tcp"))
10323         transport_protocol = 6;
10324       else if (unformat (i, "udp"))
10325         transport_protocol = 17;
10326       else
10327         {
10328           errmsg ("unknown input `%U'", format_unformat_error, i);
10329           return -99;
10330         }
10331     }
10332
10333   if (is_add == -1)
10334     {
10335       errmsg ("expecting: add|del");
10336       return -99;
10337     }
10338   if (classify_table_index == ~0)
10339     {
10340       errmsg ("classifier table not specified");
10341       return -99;
10342     }
10343   if (ip_version == 0)
10344     {
10345       errmsg ("IP version not specified");
10346       return -99;
10347     }
10348
10349   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
10350
10351   mp->is_add = is_add;
10352   mp->table_id = htonl (classify_table_index);
10353   mp->ip_version = ip_version;
10354   mp->transport_protocol = transport_protocol;
10355
10356   S (mp);
10357   W (ret);
10358   return ret;
10359 }
10360
10361 static int
10362 api_get_node_index (vat_main_t * vam)
10363 {
10364   unformat_input_t *i = vam->input;
10365   vl_api_get_node_index_t *mp;
10366   u8 *name = 0;
10367   int ret;
10368
10369   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10370     {
10371       if (unformat (i, "node %s", &name))
10372         ;
10373       else
10374         break;
10375     }
10376   if (name == 0)
10377     {
10378       errmsg ("node name required");
10379       return -99;
10380     }
10381   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
10382     {
10383       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10384       return -99;
10385     }
10386
10387   M (GET_NODE_INDEX, mp);
10388   clib_memcpy (mp->node_name, name, vec_len (name));
10389   vec_free (name);
10390
10391   S (mp);
10392   W (ret);
10393   return ret;
10394 }
10395
10396 static int
10397 api_get_next_index (vat_main_t * vam)
10398 {
10399   unformat_input_t *i = vam->input;
10400   vl_api_get_next_index_t *mp;
10401   u8 *node_name = 0, *next_node_name = 0;
10402   int ret;
10403
10404   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10405     {
10406       if (unformat (i, "node-name %s", &node_name))
10407         ;
10408       else if (unformat (i, "next-node-name %s", &next_node_name))
10409         break;
10410     }
10411
10412   if (node_name == 0)
10413     {
10414       errmsg ("node name required");
10415       return -99;
10416     }
10417   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
10418     {
10419       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10420       return -99;
10421     }
10422
10423   if (next_node_name == 0)
10424     {
10425       errmsg ("next node name required");
10426       return -99;
10427     }
10428   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
10429     {
10430       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
10431       return -99;
10432     }
10433
10434   M (GET_NEXT_INDEX, mp);
10435   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
10436   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
10437   vec_free (node_name);
10438   vec_free (next_node_name);
10439
10440   S (mp);
10441   W (ret);
10442   return ret;
10443 }
10444
10445 static int
10446 api_add_node_next (vat_main_t * vam)
10447 {
10448   unformat_input_t *i = vam->input;
10449   vl_api_add_node_next_t *mp;
10450   u8 *name = 0;
10451   u8 *next = 0;
10452   int ret;
10453
10454   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10455     {
10456       if (unformat (i, "node %s", &name))
10457         ;
10458       else if (unformat (i, "next %s", &next))
10459         ;
10460       else
10461         break;
10462     }
10463   if (name == 0)
10464     {
10465       errmsg ("node name required");
10466       return -99;
10467     }
10468   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
10469     {
10470       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10471       return -99;
10472     }
10473   if (next == 0)
10474     {
10475       errmsg ("next node required");
10476       return -99;
10477     }
10478   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
10479     {
10480       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
10481       return -99;
10482     }
10483
10484   M (ADD_NODE_NEXT, mp);
10485   clib_memcpy (mp->node_name, name, vec_len (name));
10486   clib_memcpy (mp->next_name, next, vec_len (next));
10487   vec_free (name);
10488   vec_free (next);
10489
10490   S (mp);
10491   W (ret);
10492   return ret;
10493 }
10494
10495 static int
10496 api_l2tpv3_create_tunnel (vat_main_t * vam)
10497 {
10498   unformat_input_t *i = vam->input;
10499   ip6_address_t client_address, our_address;
10500   int client_address_set = 0;
10501   int our_address_set = 0;
10502   u32 local_session_id = 0;
10503   u32 remote_session_id = 0;
10504   u64 local_cookie = 0;
10505   u64 remote_cookie = 0;
10506   u8 l2_sublayer_present = 0;
10507   vl_api_l2tpv3_create_tunnel_t *mp;
10508   int ret;
10509
10510   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10511     {
10512       if (unformat (i, "client_address %U", unformat_ip6_address,
10513                     &client_address))
10514         client_address_set = 1;
10515       else if (unformat (i, "our_address %U", unformat_ip6_address,
10516                          &our_address))
10517         our_address_set = 1;
10518       else if (unformat (i, "local_session_id %d", &local_session_id))
10519         ;
10520       else if (unformat (i, "remote_session_id %d", &remote_session_id))
10521         ;
10522       else if (unformat (i, "local_cookie %lld", &local_cookie))
10523         ;
10524       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
10525         ;
10526       else if (unformat (i, "l2-sublayer-present"))
10527         l2_sublayer_present = 1;
10528       else
10529         break;
10530     }
10531
10532   if (client_address_set == 0)
10533     {
10534       errmsg ("client_address required");
10535       return -99;
10536     }
10537
10538   if (our_address_set == 0)
10539     {
10540       errmsg ("our_address required");
10541       return -99;
10542     }
10543
10544   M (L2TPV3_CREATE_TUNNEL, mp);
10545
10546   clib_memcpy (mp->client_address, client_address.as_u8,
10547                sizeof (mp->client_address));
10548
10549   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
10550
10551   mp->local_session_id = ntohl (local_session_id);
10552   mp->remote_session_id = ntohl (remote_session_id);
10553   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
10554   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
10555   mp->l2_sublayer_present = l2_sublayer_present;
10556   mp->is_ipv6 = 1;
10557
10558   S (mp);
10559   W (ret);
10560   return ret;
10561 }
10562
10563 static int
10564 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
10565 {
10566   unformat_input_t *i = vam->input;
10567   u32 sw_if_index;
10568   u8 sw_if_index_set = 0;
10569   u64 new_local_cookie = 0;
10570   u64 new_remote_cookie = 0;
10571   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
10572   int ret;
10573
10574   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10575     {
10576       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10577         sw_if_index_set = 1;
10578       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10579         sw_if_index_set = 1;
10580       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
10581         ;
10582       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
10583         ;
10584       else
10585         break;
10586     }
10587
10588   if (sw_if_index_set == 0)
10589     {
10590       errmsg ("missing interface name or sw_if_index");
10591       return -99;
10592     }
10593
10594   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
10595
10596   mp->sw_if_index = ntohl (sw_if_index);
10597   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
10598   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
10599
10600   S (mp);
10601   W (ret);
10602   return ret;
10603 }
10604
10605 static int
10606 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
10607 {
10608   unformat_input_t *i = vam->input;
10609   vl_api_l2tpv3_interface_enable_disable_t *mp;
10610   u32 sw_if_index;
10611   u8 sw_if_index_set = 0;
10612   u8 enable_disable = 1;
10613   int ret;
10614
10615   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10616     {
10617       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10618         sw_if_index_set = 1;
10619       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10620         sw_if_index_set = 1;
10621       else if (unformat (i, "enable"))
10622         enable_disable = 1;
10623       else if (unformat (i, "disable"))
10624         enable_disable = 0;
10625       else
10626         break;
10627     }
10628
10629   if (sw_if_index_set == 0)
10630     {
10631       errmsg ("missing interface name or sw_if_index");
10632       return -99;
10633     }
10634
10635   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
10636
10637   mp->sw_if_index = ntohl (sw_if_index);
10638   mp->enable_disable = enable_disable;
10639
10640   S (mp);
10641   W (ret);
10642   return ret;
10643 }
10644
10645 static int
10646 api_l2tpv3_set_lookup_key (vat_main_t * vam)
10647 {
10648   unformat_input_t *i = vam->input;
10649   vl_api_l2tpv3_set_lookup_key_t *mp;
10650   u8 key = ~0;
10651   int ret;
10652
10653   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10654     {
10655       if (unformat (i, "lookup_v6_src"))
10656         key = L2T_LOOKUP_SRC_ADDRESS;
10657       else if (unformat (i, "lookup_v6_dst"))
10658         key = L2T_LOOKUP_DST_ADDRESS;
10659       else if (unformat (i, "lookup_session_id"))
10660         key = L2T_LOOKUP_SESSION_ID;
10661       else
10662         break;
10663     }
10664
10665   if (key == (u8) ~ 0)
10666     {
10667       errmsg ("l2tp session lookup key unset");
10668       return -99;
10669     }
10670
10671   M (L2TPV3_SET_LOOKUP_KEY, mp);
10672
10673   mp->key = key;
10674
10675   S (mp);
10676   W (ret);
10677   return ret;
10678 }
10679
10680 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
10681   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
10682 {
10683   vat_main_t *vam = &vat_main;
10684
10685   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
10686          format_ip6_address, mp->our_address,
10687          format_ip6_address, mp->client_address,
10688          clib_net_to_host_u32 (mp->sw_if_index));
10689
10690   print (vam->ofp,
10691          "   local cookies %016llx %016llx remote cookie %016llx",
10692          clib_net_to_host_u64 (mp->local_cookie[0]),
10693          clib_net_to_host_u64 (mp->local_cookie[1]),
10694          clib_net_to_host_u64 (mp->remote_cookie));
10695
10696   print (vam->ofp, "   local session-id %d remote session-id %d",
10697          clib_net_to_host_u32 (mp->local_session_id),
10698          clib_net_to_host_u32 (mp->remote_session_id));
10699
10700   print (vam->ofp, "   l2 specific sublayer %s\n",
10701          mp->l2_sublayer_present ? "preset" : "absent");
10702
10703 }
10704
10705 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
10706   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
10707 {
10708   vat_main_t *vam = &vat_main;
10709   vat_json_node_t *node = NULL;
10710   struct in6_addr addr;
10711
10712   if (VAT_JSON_ARRAY != vam->json_tree.type)
10713     {
10714       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10715       vat_json_init_array (&vam->json_tree);
10716     }
10717   node = vat_json_array_add (&vam->json_tree);
10718
10719   vat_json_init_object (node);
10720
10721   clib_memcpy (&addr, mp->our_address, sizeof (addr));
10722   vat_json_object_add_ip6 (node, "our_address", addr);
10723   clib_memcpy (&addr, mp->client_address, sizeof (addr));
10724   vat_json_object_add_ip6 (node, "client_address", addr);
10725
10726   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
10727   vat_json_init_array (lc);
10728   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
10729   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
10730   vat_json_object_add_uint (node, "remote_cookie",
10731                             clib_net_to_host_u64 (mp->remote_cookie));
10732
10733   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
10734   vat_json_object_add_uint (node, "local_session_id",
10735                             clib_net_to_host_u32 (mp->local_session_id));
10736   vat_json_object_add_uint (node, "remote_session_id",
10737                             clib_net_to_host_u32 (mp->remote_session_id));
10738   vat_json_object_add_string_copy (node, "l2_sublayer",
10739                                    mp->l2_sublayer_present ? (u8 *) "present"
10740                                    : (u8 *) "absent");
10741 }
10742
10743 static int
10744 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
10745 {
10746   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
10747   vl_api_control_ping_t *mp_ping;
10748   int ret;
10749
10750   /* Get list of l2tpv3-tunnel interfaces */
10751   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
10752   S (mp);
10753
10754   /* Use a control ping for synchronization */
10755   M (CONTROL_PING, mp_ping);
10756   S (mp_ping);
10757
10758   W (ret);
10759   return ret;
10760 }
10761
10762
10763 static void vl_api_sw_interface_tap_details_t_handler
10764   (vl_api_sw_interface_tap_details_t * mp)
10765 {
10766   vat_main_t *vam = &vat_main;
10767
10768   print (vam->ofp, "%-16s %d",
10769          mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
10770 }
10771
10772 static void vl_api_sw_interface_tap_details_t_handler_json
10773   (vl_api_sw_interface_tap_details_t * mp)
10774 {
10775   vat_main_t *vam = &vat_main;
10776   vat_json_node_t *node = NULL;
10777
10778   if (VAT_JSON_ARRAY != vam->json_tree.type)
10779     {
10780       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10781       vat_json_init_array (&vam->json_tree);
10782     }
10783   node = vat_json_array_add (&vam->json_tree);
10784
10785   vat_json_init_object (node);
10786   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10787   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
10788 }
10789
10790 static int
10791 api_sw_interface_tap_dump (vat_main_t * vam)
10792 {
10793   vl_api_sw_interface_tap_dump_t *mp;
10794   vl_api_control_ping_t *mp_ping;
10795   int ret;
10796
10797   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
10798   /* Get list of tap interfaces */
10799   M (SW_INTERFACE_TAP_DUMP, mp);
10800   S (mp);
10801
10802   /* Use a control ping for synchronization */
10803   M (CONTROL_PING, mp_ping);
10804   S (mp_ping);
10805
10806   W (ret);
10807   return ret;
10808 }
10809
10810 static uword unformat_vxlan_decap_next
10811   (unformat_input_t * input, va_list * args)
10812 {
10813   u32 *result = va_arg (*args, u32 *);
10814   u32 tmp;
10815
10816   if (unformat (input, "l2"))
10817     *result = VXLAN_INPUT_NEXT_L2_INPUT;
10818   else if (unformat (input, "%d", &tmp))
10819     *result = tmp;
10820   else
10821     return 0;
10822   return 1;
10823 }
10824
10825 static int
10826 api_vxlan_add_del_tunnel (vat_main_t * vam)
10827 {
10828   unformat_input_t *line_input = vam->input;
10829   vl_api_vxlan_add_del_tunnel_t *mp;
10830   ip46_address_t src, dst;
10831   u8 is_add = 1;
10832   u8 ipv4_set = 0, ipv6_set = 0;
10833   u8 src_set = 0;
10834   u8 dst_set = 0;
10835   u8 grp_set = 0;
10836   u32 mcast_sw_if_index = ~0;
10837   u32 encap_vrf_id = 0;
10838   u32 decap_next_index = ~0;
10839   u32 vni = 0;
10840   int ret;
10841
10842   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
10843   memset (&src, 0, sizeof src);
10844   memset (&dst, 0, sizeof dst);
10845
10846   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10847     {
10848       if (unformat (line_input, "del"))
10849         is_add = 0;
10850       else
10851         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
10852         {
10853           ipv4_set = 1;
10854           src_set = 1;
10855         }
10856       else
10857         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
10858         {
10859           ipv4_set = 1;
10860           dst_set = 1;
10861         }
10862       else
10863         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
10864         {
10865           ipv6_set = 1;
10866           src_set = 1;
10867         }
10868       else
10869         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
10870         {
10871           ipv6_set = 1;
10872           dst_set = 1;
10873         }
10874       else if (unformat (line_input, "group %U %U",
10875                          unformat_ip4_address, &dst.ip4,
10876                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
10877         {
10878           grp_set = dst_set = 1;
10879           ipv4_set = 1;
10880         }
10881       else if (unformat (line_input, "group %U",
10882                          unformat_ip4_address, &dst.ip4))
10883         {
10884           grp_set = dst_set = 1;
10885           ipv4_set = 1;
10886         }
10887       else if (unformat (line_input, "group %U %U",
10888                          unformat_ip6_address, &dst.ip6,
10889                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
10890         {
10891           grp_set = dst_set = 1;
10892           ipv6_set = 1;
10893         }
10894       else if (unformat (line_input, "group %U",
10895                          unformat_ip6_address, &dst.ip6))
10896         {
10897           grp_set = dst_set = 1;
10898           ipv6_set = 1;
10899         }
10900       else
10901         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
10902         ;
10903       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
10904         ;
10905       else if (unformat (line_input, "decap-next %U",
10906                          unformat_vxlan_decap_next, &decap_next_index))
10907         ;
10908       else if (unformat (line_input, "vni %d", &vni))
10909         ;
10910       else
10911         {
10912           errmsg ("parse error '%U'", format_unformat_error, line_input);
10913           return -99;
10914         }
10915     }
10916
10917   if (src_set == 0)
10918     {
10919       errmsg ("tunnel src address not specified");
10920       return -99;
10921     }
10922   if (dst_set == 0)
10923     {
10924       errmsg ("tunnel dst address not specified");
10925       return -99;
10926     }
10927
10928   if (grp_set && !ip46_address_is_multicast (&dst))
10929     {
10930       errmsg ("tunnel group address not multicast");
10931       return -99;
10932     }
10933   if (grp_set && mcast_sw_if_index == ~0)
10934     {
10935       errmsg ("tunnel nonexistent multicast device");
10936       return -99;
10937     }
10938   if (grp_set == 0 && ip46_address_is_multicast (&dst))
10939     {
10940       errmsg ("tunnel dst address must be unicast");
10941       return -99;
10942     }
10943
10944
10945   if (ipv4_set && ipv6_set)
10946     {
10947       errmsg ("both IPv4 and IPv6 addresses specified");
10948       return -99;
10949     }
10950
10951   if ((vni == 0) || (vni >> 24))
10952     {
10953       errmsg ("vni not specified or out of range");
10954       return -99;
10955     }
10956
10957   M (VXLAN_ADD_DEL_TUNNEL, mp);
10958
10959   if (ipv6_set)
10960     {
10961       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
10962       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
10963     }
10964   else
10965     {
10966       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
10967       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
10968     }
10969   mp->encap_vrf_id = ntohl (encap_vrf_id);
10970   mp->decap_next_index = ntohl (decap_next_index);
10971   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
10972   mp->vni = ntohl (vni);
10973   mp->is_add = is_add;
10974   mp->is_ipv6 = ipv6_set;
10975
10976   S (mp);
10977   W (ret);
10978   return ret;
10979 }
10980
10981 static void vl_api_vxlan_tunnel_details_t_handler
10982   (vl_api_vxlan_tunnel_details_t * mp)
10983 {
10984   vat_main_t *vam = &vat_main;
10985   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
10986   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
10987
10988   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
10989          ntohl (mp->sw_if_index),
10990          format_ip46_address, &src, IP46_TYPE_ANY,
10991          format_ip46_address, &dst, IP46_TYPE_ANY,
10992          ntohl (mp->encap_vrf_id),
10993          ntohl (mp->decap_next_index), ntohl (mp->vni),
10994          ntohl (mp->mcast_sw_if_index));
10995 }
10996
10997 static void vl_api_vxlan_tunnel_details_t_handler_json
10998   (vl_api_vxlan_tunnel_details_t * mp)
10999 {
11000   vat_main_t *vam = &vat_main;
11001   vat_json_node_t *node = NULL;
11002
11003   if (VAT_JSON_ARRAY != vam->json_tree.type)
11004     {
11005       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11006       vat_json_init_array (&vam->json_tree);
11007     }
11008   node = vat_json_array_add (&vam->json_tree);
11009
11010   vat_json_init_object (node);
11011   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11012   if (mp->is_ipv6)
11013     {
11014       struct in6_addr ip6;
11015
11016       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
11017       vat_json_object_add_ip6 (node, "src_address", ip6);
11018       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
11019       vat_json_object_add_ip6 (node, "dst_address", ip6);
11020     }
11021   else
11022     {
11023       struct in_addr ip4;
11024
11025       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
11026       vat_json_object_add_ip4 (node, "src_address", ip4);
11027       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
11028       vat_json_object_add_ip4 (node, "dst_address", ip4);
11029     }
11030   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
11031   vat_json_object_add_uint (node, "decap_next_index",
11032                             ntohl (mp->decap_next_index));
11033   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
11034   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
11035   vat_json_object_add_uint (node, "mcast_sw_if_index",
11036                             ntohl (mp->mcast_sw_if_index));
11037 }
11038
11039 static int
11040 api_vxlan_tunnel_dump (vat_main_t * vam)
11041 {
11042   unformat_input_t *i = vam->input;
11043   vl_api_vxlan_tunnel_dump_t *mp;
11044   vl_api_control_ping_t *mp_ping;
11045   u32 sw_if_index;
11046   u8 sw_if_index_set = 0;
11047   int ret;
11048
11049   /* Parse args required to build the message */
11050   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11051     {
11052       if (unformat (i, "sw_if_index %d", &sw_if_index))
11053         sw_if_index_set = 1;
11054       else
11055         break;
11056     }
11057
11058   if (sw_if_index_set == 0)
11059     {
11060       sw_if_index = ~0;
11061     }
11062
11063   if (!vam->json_output)
11064     {
11065       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
11066              "sw_if_index", "src_address", "dst_address",
11067              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
11068     }
11069
11070   /* Get list of vxlan-tunnel interfaces */
11071   M (VXLAN_TUNNEL_DUMP, mp);
11072
11073   mp->sw_if_index = htonl (sw_if_index);
11074
11075   S (mp);
11076
11077   /* Use a control ping for synchronization */
11078   M (CONTROL_PING, mp_ping);
11079   S (mp_ping);
11080
11081   W (ret);
11082   return ret;
11083 }
11084
11085 static int
11086 api_gre_add_del_tunnel (vat_main_t * vam)
11087 {
11088   unformat_input_t *line_input = vam->input;
11089   vl_api_gre_add_del_tunnel_t *mp;
11090   ip4_address_t src4, dst4;
11091   ip6_address_t src6, dst6;
11092   u8 is_add = 1;
11093   u8 ipv4_set = 0;
11094   u8 ipv6_set = 0;
11095   u8 teb = 0;
11096   u8 src_set = 0;
11097   u8 dst_set = 0;
11098   u32 outer_fib_id = 0;
11099   int ret;
11100
11101   memset (&src4, 0, sizeof src4);
11102   memset (&dst4, 0, sizeof dst4);
11103   memset (&src6, 0, sizeof src6);
11104   memset (&dst6, 0, sizeof dst6);
11105
11106   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11107     {
11108       if (unformat (line_input, "del"))
11109         is_add = 0;
11110       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
11111         {
11112           src_set = 1;
11113           ipv4_set = 1;
11114         }
11115       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
11116         {
11117           dst_set = 1;
11118           ipv4_set = 1;
11119         }
11120       else if (unformat (line_input, "src %U", unformat_ip6_address, &src6))
11121         {
11122           src_set = 1;
11123           ipv6_set = 1;
11124         }
11125       else if (unformat (line_input, "dst %U", unformat_ip6_address, &dst6))
11126         {
11127           dst_set = 1;
11128           ipv6_set = 1;
11129         }
11130       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
11131         ;
11132       else if (unformat (line_input, "teb"))
11133         teb = 1;
11134       else
11135         {
11136           errmsg ("parse error '%U'", format_unformat_error, line_input);
11137           return -99;
11138         }
11139     }
11140
11141   if (src_set == 0)
11142     {
11143       errmsg ("tunnel src address not specified");
11144       return -99;
11145     }
11146   if (dst_set == 0)
11147     {
11148       errmsg ("tunnel dst address not specified");
11149       return -99;
11150     }
11151   if (ipv4_set && ipv6_set)
11152     {
11153       errmsg ("both IPv4 and IPv6 addresses specified");
11154       return -99;
11155     }
11156
11157
11158   M (GRE_ADD_DEL_TUNNEL, mp);
11159
11160   if (ipv4_set)
11161     {
11162       clib_memcpy (&mp->src_address, &src4, 4);
11163       clib_memcpy (&mp->dst_address, &dst4, 4);
11164     }
11165   else
11166     {
11167       clib_memcpy (&mp->src_address, &src6, 16);
11168       clib_memcpy (&mp->dst_address, &dst6, 16);
11169     }
11170   mp->outer_fib_id = ntohl (outer_fib_id);
11171   mp->is_add = is_add;
11172   mp->teb = teb;
11173   mp->is_ipv6 = ipv6_set;
11174
11175   S (mp);
11176   W (ret);
11177   return ret;
11178 }
11179
11180 static void vl_api_gre_tunnel_details_t_handler
11181   (vl_api_gre_tunnel_details_t * mp)
11182 {
11183   vat_main_t *vam = &vat_main;
11184   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->src_address);
11185   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->dst_address);
11186
11187   print (vam->ofp, "%11d%24U%24U%6d%14d",
11188          ntohl (mp->sw_if_index),
11189          format_ip46_address, &src, IP46_TYPE_ANY,
11190          format_ip46_address, &dst, IP46_TYPE_ANY,
11191          mp->teb, ntohl (mp->outer_fib_id));
11192 }
11193
11194 static void vl_api_gre_tunnel_details_t_handler_json
11195   (vl_api_gre_tunnel_details_t * mp)
11196 {
11197   vat_main_t *vam = &vat_main;
11198   vat_json_node_t *node = NULL;
11199   struct in_addr ip4;
11200   struct in6_addr ip6;
11201
11202   if (VAT_JSON_ARRAY != vam->json_tree.type)
11203     {
11204       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11205       vat_json_init_array (&vam->json_tree);
11206     }
11207   node = vat_json_array_add (&vam->json_tree);
11208
11209   vat_json_init_object (node);
11210   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11211   if (!mp->is_ipv6)
11212     {
11213       clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
11214       vat_json_object_add_ip4 (node, "src_address", ip4);
11215       clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
11216       vat_json_object_add_ip4 (node, "dst_address", ip4);
11217     }
11218   else
11219     {
11220       clib_memcpy (&ip6, &mp->src_address, sizeof (ip6));
11221       vat_json_object_add_ip6 (node, "src_address", ip6);
11222       clib_memcpy (&ip6, &mp->dst_address, sizeof (ip6));
11223       vat_json_object_add_ip6 (node, "dst_address", ip6);
11224     }
11225   vat_json_object_add_uint (node, "teb", mp->teb);
11226   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
11227   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6);
11228 }
11229
11230 static int
11231 api_gre_tunnel_dump (vat_main_t * vam)
11232 {
11233   unformat_input_t *i = vam->input;
11234   vl_api_gre_tunnel_dump_t *mp;
11235   vl_api_control_ping_t *mp_ping;
11236   u32 sw_if_index;
11237   u8 sw_if_index_set = 0;
11238   int ret;
11239
11240   /* Parse args required to build the message */
11241   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11242     {
11243       if (unformat (i, "sw_if_index %d", &sw_if_index))
11244         sw_if_index_set = 1;
11245       else
11246         break;
11247     }
11248
11249   if (sw_if_index_set == 0)
11250     {
11251       sw_if_index = ~0;
11252     }
11253
11254   if (!vam->json_output)
11255     {
11256       print (vam->ofp, "%11s%24s%24s%6s%14s",
11257              "sw_if_index", "src_address", "dst_address", "teb",
11258              "outer_fib_id");
11259     }
11260
11261   /* Get list of gre-tunnel interfaces */
11262   M (GRE_TUNNEL_DUMP, mp);
11263
11264   mp->sw_if_index = htonl (sw_if_index);
11265
11266   S (mp);
11267
11268   /* Use a control ping for synchronization */
11269   M (CONTROL_PING, mp_ping);
11270   S (mp_ping);
11271
11272   W (ret);
11273   return ret;
11274 }
11275
11276 static int
11277 api_l2_fib_clear_table (vat_main_t * vam)
11278 {
11279 //  unformat_input_t * i = vam->input;
11280   vl_api_l2_fib_clear_table_t *mp;
11281   int ret;
11282
11283   M (L2_FIB_CLEAR_TABLE, mp);
11284
11285   S (mp);
11286   W (ret);
11287   return ret;
11288 }
11289
11290 static int
11291 api_l2_interface_efp_filter (vat_main_t * vam)
11292 {
11293   unformat_input_t *i = vam->input;
11294   vl_api_l2_interface_efp_filter_t *mp;
11295   u32 sw_if_index;
11296   u8 enable = 1;
11297   u8 sw_if_index_set = 0;
11298   int ret;
11299
11300   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11301     {
11302       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11303         sw_if_index_set = 1;
11304       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11305         sw_if_index_set = 1;
11306       else if (unformat (i, "enable"))
11307         enable = 1;
11308       else if (unformat (i, "disable"))
11309         enable = 0;
11310       else
11311         {
11312           clib_warning ("parse error '%U'", format_unformat_error, i);
11313           return -99;
11314         }
11315     }
11316
11317   if (sw_if_index_set == 0)
11318     {
11319       errmsg ("missing sw_if_index");
11320       return -99;
11321     }
11322
11323   M (L2_INTERFACE_EFP_FILTER, mp);
11324
11325   mp->sw_if_index = ntohl (sw_if_index);
11326   mp->enable_disable = enable;
11327
11328   S (mp);
11329   W (ret);
11330   return ret;
11331 }
11332
11333 #define foreach_vtr_op                          \
11334 _("disable",  L2_VTR_DISABLED)                  \
11335 _("push-1",  L2_VTR_PUSH_1)                     \
11336 _("push-2",  L2_VTR_PUSH_2)                     \
11337 _("pop-1",  L2_VTR_POP_1)                       \
11338 _("pop-2",  L2_VTR_POP_2)                       \
11339 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
11340 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
11341 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
11342 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
11343
11344 static int
11345 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
11346 {
11347   unformat_input_t *i = vam->input;
11348   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
11349   u32 sw_if_index;
11350   u8 sw_if_index_set = 0;
11351   u8 vtr_op_set = 0;
11352   u32 vtr_op = 0;
11353   u32 push_dot1q = 1;
11354   u32 tag1 = ~0;
11355   u32 tag2 = ~0;
11356   int ret;
11357
11358   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11359     {
11360       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11361         sw_if_index_set = 1;
11362       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11363         sw_if_index_set = 1;
11364       else if (unformat (i, "vtr_op %d", &vtr_op))
11365         vtr_op_set = 1;
11366 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
11367       foreach_vtr_op
11368 #undef _
11369         else if (unformat (i, "push_dot1q %d", &push_dot1q))
11370         ;
11371       else if (unformat (i, "tag1 %d", &tag1))
11372         ;
11373       else if (unformat (i, "tag2 %d", &tag2))
11374         ;
11375       else
11376         {
11377           clib_warning ("parse error '%U'", format_unformat_error, i);
11378           return -99;
11379         }
11380     }
11381
11382   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
11383     {
11384       errmsg ("missing vtr operation or sw_if_index");
11385       return -99;
11386     }
11387
11388   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
11389   mp->sw_if_index = ntohl (sw_if_index);
11390   mp->vtr_op = ntohl (vtr_op);
11391   mp->push_dot1q = ntohl (push_dot1q);
11392   mp->tag1 = ntohl (tag1);
11393   mp->tag2 = ntohl (tag2);
11394
11395   S (mp);
11396   W (ret);
11397   return ret;
11398 }
11399
11400 static int
11401 api_create_vhost_user_if (vat_main_t * vam)
11402 {
11403   unformat_input_t *i = vam->input;
11404   vl_api_create_vhost_user_if_t *mp;
11405   u8 *file_name;
11406   u8 is_server = 0;
11407   u8 file_name_set = 0;
11408   u32 custom_dev_instance = ~0;
11409   u8 hwaddr[6];
11410   u8 use_custom_mac = 0;
11411   u8 *tag = 0;
11412   int ret;
11413   u8 operation_mode = VHOST_USER_POLLING_MODE;
11414
11415   /* Shut up coverity */
11416   memset (hwaddr, 0, sizeof (hwaddr));
11417
11418   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11419     {
11420       if (unformat (i, "socket %s", &file_name))
11421         {
11422           file_name_set = 1;
11423         }
11424       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
11425         ;
11426       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
11427         use_custom_mac = 1;
11428       else if (unformat (i, "server"))
11429         is_server = 1;
11430       else if (unformat (i, "tag %s", &tag))
11431         ;
11432       else if (unformat (i, "mode %U",
11433                          api_unformat_vhost_user_operation_mode,
11434                          &operation_mode))
11435         ;
11436       else
11437         break;
11438     }
11439
11440   if (file_name_set == 0)
11441     {
11442       errmsg ("missing socket file name");
11443       return -99;
11444     }
11445
11446   if (vec_len (file_name) > 255)
11447     {
11448       errmsg ("socket file name too long");
11449       return -99;
11450     }
11451   vec_add1 (file_name, 0);
11452
11453   M (CREATE_VHOST_USER_IF, mp);
11454
11455   mp->operation_mode = operation_mode;
11456   mp->is_server = is_server;
11457   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
11458   vec_free (file_name);
11459   if (custom_dev_instance != ~0)
11460     {
11461       mp->renumber = 1;
11462       mp->custom_dev_instance = ntohl (custom_dev_instance);
11463     }
11464   mp->use_custom_mac = use_custom_mac;
11465   clib_memcpy (mp->mac_address, hwaddr, 6);
11466   if (tag)
11467     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
11468   vec_free (tag);
11469
11470   S (mp);
11471   W (ret);
11472   return ret;
11473 }
11474
11475 static int
11476 api_modify_vhost_user_if (vat_main_t * vam)
11477 {
11478   unformat_input_t *i = vam->input;
11479   vl_api_modify_vhost_user_if_t *mp;
11480   u8 *file_name;
11481   u8 is_server = 0;
11482   u8 file_name_set = 0;
11483   u32 custom_dev_instance = ~0;
11484   u8 sw_if_index_set = 0;
11485   u32 sw_if_index = (u32) ~ 0;
11486   int ret;
11487   u8 operation_mode = VHOST_USER_POLLING_MODE;
11488
11489   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11490     {
11491       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11492         sw_if_index_set = 1;
11493       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11494         sw_if_index_set = 1;
11495       else if (unformat (i, "socket %s", &file_name))
11496         {
11497           file_name_set = 1;
11498         }
11499       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
11500         ;
11501       else if (unformat (i, "server"))
11502         is_server = 1;
11503       else if (unformat (i, "mode %U",
11504                          api_unformat_vhost_user_operation_mode,
11505                          &operation_mode))
11506         ;
11507       else
11508         break;
11509     }
11510
11511   if (sw_if_index_set == 0)
11512     {
11513       errmsg ("missing sw_if_index or interface name");
11514       return -99;
11515     }
11516
11517   if (file_name_set == 0)
11518     {
11519       errmsg ("missing socket file name");
11520       return -99;
11521     }
11522
11523   if (vec_len (file_name) > 255)
11524     {
11525       errmsg ("socket file name too long");
11526       return -99;
11527     }
11528   vec_add1 (file_name, 0);
11529
11530   M (MODIFY_VHOST_USER_IF, mp);
11531
11532   mp->operation_mode = operation_mode;
11533   mp->sw_if_index = ntohl (sw_if_index);
11534   mp->is_server = is_server;
11535   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
11536   vec_free (file_name);
11537   if (custom_dev_instance != ~0)
11538     {
11539       mp->renumber = 1;
11540       mp->custom_dev_instance = ntohl (custom_dev_instance);
11541     }
11542
11543   S (mp);
11544   W (ret);
11545   return ret;
11546 }
11547
11548 static int
11549 api_delete_vhost_user_if (vat_main_t * vam)
11550 {
11551   unformat_input_t *i = vam->input;
11552   vl_api_delete_vhost_user_if_t *mp;
11553   u32 sw_if_index = ~0;
11554   u8 sw_if_index_set = 0;
11555   int ret;
11556
11557   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11558     {
11559       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11560         sw_if_index_set = 1;
11561       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11562         sw_if_index_set = 1;
11563       else
11564         break;
11565     }
11566
11567   if (sw_if_index_set == 0)
11568     {
11569       errmsg ("missing sw_if_index or interface name");
11570       return -99;
11571     }
11572
11573
11574   M (DELETE_VHOST_USER_IF, mp);
11575
11576   mp->sw_if_index = ntohl (sw_if_index);
11577
11578   S (mp);
11579   W (ret);
11580   return ret;
11581 }
11582
11583 static void vl_api_sw_interface_vhost_user_details_t_handler
11584   (vl_api_sw_interface_vhost_user_details_t * mp)
11585 {
11586   vat_main_t *vam = &vat_main;
11587
11588   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %U %s",
11589          (char *) mp->interface_name,
11590          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
11591          clib_net_to_host_u64 (mp->features), mp->is_server,
11592          ntohl (mp->num_regions), api_format_vhost_user_operation_mode,
11593          mp->operation_mode, (char *) mp->sock_filename);
11594   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
11595 }
11596
11597 static void vl_api_sw_interface_vhost_user_details_t_handler_json
11598   (vl_api_sw_interface_vhost_user_details_t * mp)
11599 {
11600   vat_main_t *vam = &vat_main;
11601   vat_json_node_t *node = NULL;
11602
11603   if (VAT_JSON_ARRAY != vam->json_tree.type)
11604     {
11605       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11606       vat_json_init_array (&vam->json_tree);
11607     }
11608   node = vat_json_array_add (&vam->json_tree);
11609
11610   vat_json_init_object (node);
11611   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11612   vat_json_object_add_string_copy (node, "interface_name",
11613                                    mp->interface_name);
11614   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
11615                             ntohl (mp->virtio_net_hdr_sz));
11616   vat_json_object_add_uint (node, "features",
11617                             clib_net_to_host_u64 (mp->features));
11618   vat_json_object_add_uint (node, "is_server", mp->is_server);
11619   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
11620   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
11621   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
11622   vat_json_object_add_uint (node, "mode", mp->operation_mode);
11623 }
11624
11625 static int
11626 api_sw_interface_vhost_user_dump (vat_main_t * vam)
11627 {
11628   vl_api_sw_interface_vhost_user_dump_t *mp;
11629   vl_api_control_ping_t *mp_ping;
11630   int ret;
11631   print (vam->ofp,
11632          "Interface name            idx hdr_sz features server regions mode"
11633          "      filename");
11634
11635   /* Get list of vhost-user interfaces */
11636   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
11637   S (mp);
11638
11639   /* Use a control ping for synchronization */
11640   M (CONTROL_PING, mp_ping);
11641   S (mp_ping);
11642
11643   W (ret);
11644   return ret;
11645 }
11646
11647 static int
11648 api_show_version (vat_main_t * vam)
11649 {
11650   vl_api_show_version_t *mp;
11651   int ret;
11652
11653   M (SHOW_VERSION, mp);
11654
11655   S (mp);
11656   W (ret);
11657   return ret;
11658 }
11659
11660
11661 static int
11662 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
11663 {
11664   unformat_input_t *line_input = vam->input;
11665   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
11666   ip4_address_t local4, remote4;
11667   ip6_address_t local6, remote6;
11668   u8 is_add = 1;
11669   u8 ipv4_set = 0, ipv6_set = 0;
11670   u8 local_set = 0;
11671   u8 remote_set = 0;
11672   u32 encap_vrf_id = 0;
11673   u32 decap_vrf_id = 0;
11674   u8 protocol = ~0;
11675   u32 vni;
11676   u8 vni_set = 0;
11677   int ret;
11678
11679   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11680     {
11681       if (unformat (line_input, "del"))
11682         is_add = 0;
11683       else if (unformat (line_input, "local %U",
11684                          unformat_ip4_address, &local4))
11685         {
11686           local_set = 1;
11687           ipv4_set = 1;
11688         }
11689       else if (unformat (line_input, "remote %U",
11690                          unformat_ip4_address, &remote4))
11691         {
11692           remote_set = 1;
11693           ipv4_set = 1;
11694         }
11695       else if (unformat (line_input, "local %U",
11696                          unformat_ip6_address, &local6))
11697         {
11698           local_set = 1;
11699           ipv6_set = 1;
11700         }
11701       else if (unformat (line_input, "remote %U",
11702                          unformat_ip6_address, &remote6))
11703         {
11704           remote_set = 1;
11705           ipv6_set = 1;
11706         }
11707       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
11708         ;
11709       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
11710         ;
11711       else if (unformat (line_input, "vni %d", &vni))
11712         vni_set = 1;
11713       else if (unformat (line_input, "next-ip4"))
11714         protocol = 1;
11715       else if (unformat (line_input, "next-ip6"))
11716         protocol = 2;
11717       else if (unformat (line_input, "next-ethernet"))
11718         protocol = 3;
11719       else if (unformat (line_input, "next-nsh"))
11720         protocol = 4;
11721       else
11722         {
11723           errmsg ("parse error '%U'", format_unformat_error, line_input);
11724           return -99;
11725         }
11726     }
11727
11728   if (local_set == 0)
11729     {
11730       errmsg ("tunnel local address not specified");
11731       return -99;
11732     }
11733   if (remote_set == 0)
11734     {
11735       errmsg ("tunnel remote address not specified");
11736       return -99;
11737     }
11738   if (ipv4_set && ipv6_set)
11739     {
11740       errmsg ("both IPv4 and IPv6 addresses specified");
11741       return -99;
11742     }
11743
11744   if (vni_set == 0)
11745     {
11746       errmsg ("vni not specified");
11747       return -99;
11748     }
11749
11750   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
11751
11752
11753   if (ipv6_set)
11754     {
11755       clib_memcpy (&mp->local, &local6, sizeof (local6));
11756       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
11757     }
11758   else
11759     {
11760       clib_memcpy (&mp->local, &local4, sizeof (local4));
11761       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
11762     }
11763
11764   mp->encap_vrf_id = ntohl (encap_vrf_id);
11765   mp->decap_vrf_id = ntohl (decap_vrf_id);
11766   mp->protocol = protocol;
11767   mp->vni = ntohl (vni);
11768   mp->is_add = is_add;
11769   mp->is_ipv6 = ipv6_set;
11770
11771   S (mp);
11772   W (ret);
11773   return ret;
11774 }
11775
11776 static void vl_api_vxlan_gpe_tunnel_details_t_handler
11777   (vl_api_vxlan_gpe_tunnel_details_t * mp)
11778 {
11779   vat_main_t *vam = &vat_main;
11780
11781   print (vam->ofp, "%11d%24U%24U%13d%12d%14d%14d",
11782          ntohl (mp->sw_if_index),
11783          format_ip46_address, &(mp->local[0]),
11784          format_ip46_address, &(mp->remote[0]),
11785          ntohl (mp->vni),
11786          ntohl (mp->protocol),
11787          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
11788 }
11789
11790 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
11791   (vl_api_vxlan_gpe_tunnel_details_t * mp)
11792 {
11793   vat_main_t *vam = &vat_main;
11794   vat_json_node_t *node = NULL;
11795   struct in_addr ip4;
11796   struct in6_addr ip6;
11797
11798   if (VAT_JSON_ARRAY != vam->json_tree.type)
11799     {
11800       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11801       vat_json_init_array (&vam->json_tree);
11802     }
11803   node = vat_json_array_add (&vam->json_tree);
11804
11805   vat_json_init_object (node);
11806   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11807   if (mp->is_ipv6)
11808     {
11809       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
11810       vat_json_object_add_ip6 (node, "local", ip6);
11811       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
11812       vat_json_object_add_ip6 (node, "remote", ip6);
11813     }
11814   else
11815     {
11816       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
11817       vat_json_object_add_ip4 (node, "local", ip4);
11818       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
11819       vat_json_object_add_ip4 (node, "remote", ip4);
11820     }
11821   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
11822   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
11823   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
11824   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
11825   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
11826 }
11827
11828 static int
11829 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
11830 {
11831   unformat_input_t *i = vam->input;
11832   vl_api_vxlan_gpe_tunnel_dump_t *mp;
11833   vl_api_control_ping_t *mp_ping;
11834   u32 sw_if_index;
11835   u8 sw_if_index_set = 0;
11836   int ret;
11837
11838   /* Parse args required to build the message */
11839   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11840     {
11841       if (unformat (i, "sw_if_index %d", &sw_if_index))
11842         sw_if_index_set = 1;
11843       else
11844         break;
11845     }
11846
11847   if (sw_if_index_set == 0)
11848     {
11849       sw_if_index = ~0;
11850     }
11851
11852   if (!vam->json_output)
11853     {
11854       print (vam->ofp, "%11s%24s%24s%13s%15s%14s%14s",
11855              "sw_if_index", "local", "remote", "vni",
11856              "protocol", "encap_vrf_id", "decap_vrf_id");
11857     }
11858
11859   /* Get list of vxlan-tunnel interfaces */
11860   M (VXLAN_GPE_TUNNEL_DUMP, mp);
11861
11862   mp->sw_if_index = htonl (sw_if_index);
11863
11864   S (mp);
11865
11866   /* Use a control ping for synchronization */
11867   M (CONTROL_PING, mp_ping);
11868   S (mp_ping);
11869
11870   W (ret);
11871   return ret;
11872 }
11873
11874 u8 *
11875 format_l2_fib_mac_address (u8 * s, va_list * args)
11876 {
11877   u8 *a = va_arg (*args, u8 *);
11878
11879   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
11880                  a[2], a[3], a[4], a[5], a[6], a[7]);
11881 }
11882
11883 static void vl_api_l2_fib_table_entry_t_handler
11884   (vl_api_l2_fib_table_entry_t * mp)
11885 {
11886   vat_main_t *vam = &vat_main;
11887
11888   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
11889          "       %d       %d     %d",
11890          ntohl (mp->bd_id), format_l2_fib_mac_address, &mp->mac,
11891          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
11892          mp->bvi_mac);
11893 }
11894
11895 static void vl_api_l2_fib_table_entry_t_handler_json
11896   (vl_api_l2_fib_table_entry_t * mp)
11897 {
11898   vat_main_t *vam = &vat_main;
11899   vat_json_node_t *node = NULL;
11900
11901   if (VAT_JSON_ARRAY != vam->json_tree.type)
11902     {
11903       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11904       vat_json_init_array (&vam->json_tree);
11905     }
11906   node = vat_json_array_add (&vam->json_tree);
11907
11908   vat_json_init_object (node);
11909   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
11910   vat_json_object_add_uint (node, "mac", clib_net_to_host_u64 (mp->mac));
11911   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11912   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
11913   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
11914   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
11915 }
11916
11917 static int
11918 api_l2_fib_table_dump (vat_main_t * vam)
11919 {
11920   unformat_input_t *i = vam->input;
11921   vl_api_l2_fib_table_dump_t *mp;
11922   vl_api_control_ping_t *mp_ping;
11923   u32 bd_id;
11924   u8 bd_id_set = 0;
11925   int ret;
11926
11927   /* Parse args required to build the message */
11928   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11929     {
11930       if (unformat (i, "bd_id %d", &bd_id))
11931         bd_id_set = 1;
11932       else
11933         break;
11934     }
11935
11936   if (bd_id_set == 0)
11937     {
11938       errmsg ("missing bridge domain");
11939       return -99;
11940     }
11941
11942   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
11943
11944   /* Get list of l2 fib entries */
11945   M (L2_FIB_TABLE_DUMP, mp);
11946
11947   mp->bd_id = ntohl (bd_id);
11948   S (mp);
11949
11950   /* Use a control ping for synchronization */
11951   M (CONTROL_PING, mp_ping);
11952   S (mp_ping);
11953
11954   W (ret);
11955   return ret;
11956 }
11957
11958
11959 static int
11960 api_interface_name_renumber (vat_main_t * vam)
11961 {
11962   unformat_input_t *line_input = vam->input;
11963   vl_api_interface_name_renumber_t *mp;
11964   u32 sw_if_index = ~0;
11965   u32 new_show_dev_instance = ~0;
11966   int ret;
11967
11968   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11969     {
11970       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
11971                     &sw_if_index))
11972         ;
11973       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
11974         ;
11975       else if (unformat (line_input, "new_show_dev_instance %d",
11976                          &new_show_dev_instance))
11977         ;
11978       else
11979         break;
11980     }
11981
11982   if (sw_if_index == ~0)
11983     {
11984       errmsg ("missing interface name or sw_if_index");
11985       return -99;
11986     }
11987
11988   if (new_show_dev_instance == ~0)
11989     {
11990       errmsg ("missing new_show_dev_instance");
11991       return -99;
11992     }
11993
11994   M (INTERFACE_NAME_RENUMBER, mp);
11995
11996   mp->sw_if_index = ntohl (sw_if_index);
11997   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
11998
11999   S (mp);
12000   W (ret);
12001   return ret;
12002 }
12003
12004 static int
12005 api_want_ip4_arp_events (vat_main_t * vam)
12006 {
12007   unformat_input_t *line_input = vam->input;
12008   vl_api_want_ip4_arp_events_t *mp;
12009   ip4_address_t address;
12010   int address_set = 0;
12011   u32 enable_disable = 1;
12012   int ret;
12013
12014   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12015     {
12016       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
12017         address_set = 1;
12018       else if (unformat (line_input, "del"))
12019         enable_disable = 0;
12020       else
12021         break;
12022     }
12023
12024   if (address_set == 0)
12025     {
12026       errmsg ("missing addresses");
12027       return -99;
12028     }
12029
12030   M (WANT_IP4_ARP_EVENTS, mp);
12031   mp->enable_disable = enable_disable;
12032   mp->pid = htonl (getpid ());
12033   mp->address = address.as_u32;
12034
12035   S (mp);
12036   W (ret);
12037   return ret;
12038 }
12039
12040 static int
12041 api_want_ip6_nd_events (vat_main_t * vam)
12042 {
12043   unformat_input_t *line_input = vam->input;
12044   vl_api_want_ip6_nd_events_t *mp;
12045   ip6_address_t address;
12046   int address_set = 0;
12047   u32 enable_disable = 1;
12048   int ret;
12049
12050   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12051     {
12052       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
12053         address_set = 1;
12054       else if (unformat (line_input, "del"))
12055         enable_disable = 0;
12056       else
12057         break;
12058     }
12059
12060   if (address_set == 0)
12061     {
12062       errmsg ("missing addresses");
12063       return -99;
12064     }
12065
12066   M (WANT_IP6_ND_EVENTS, mp);
12067   mp->enable_disable = enable_disable;
12068   mp->pid = htonl (getpid ());
12069   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
12070
12071   S (mp);
12072   W (ret);
12073   return ret;
12074 }
12075
12076 static int
12077 api_input_acl_set_interface (vat_main_t * vam)
12078 {
12079   unformat_input_t *i = vam->input;
12080   vl_api_input_acl_set_interface_t *mp;
12081   u32 sw_if_index;
12082   int sw_if_index_set;
12083   u32 ip4_table_index = ~0;
12084   u32 ip6_table_index = ~0;
12085   u32 l2_table_index = ~0;
12086   u8 is_add = 1;
12087   int ret;
12088
12089   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12090     {
12091       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12092         sw_if_index_set = 1;
12093       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12094         sw_if_index_set = 1;
12095       else if (unformat (i, "del"))
12096         is_add = 0;
12097       else if (unformat (i, "ip4-table %d", &ip4_table_index))
12098         ;
12099       else if (unformat (i, "ip6-table %d", &ip6_table_index))
12100         ;
12101       else if (unformat (i, "l2-table %d", &l2_table_index))
12102         ;
12103       else
12104         {
12105           clib_warning ("parse error '%U'", format_unformat_error, i);
12106           return -99;
12107         }
12108     }
12109
12110   if (sw_if_index_set == 0)
12111     {
12112       errmsg ("missing interface name or sw_if_index");
12113       return -99;
12114     }
12115
12116   M (INPUT_ACL_SET_INTERFACE, mp);
12117
12118   mp->sw_if_index = ntohl (sw_if_index);
12119   mp->ip4_table_index = ntohl (ip4_table_index);
12120   mp->ip6_table_index = ntohl (ip6_table_index);
12121   mp->l2_table_index = ntohl (l2_table_index);
12122   mp->is_add = is_add;
12123
12124   S (mp);
12125   W (ret);
12126   return ret;
12127 }
12128
12129 static int
12130 api_ip_address_dump (vat_main_t * vam)
12131 {
12132   unformat_input_t *i = vam->input;
12133   vl_api_ip_address_dump_t *mp;
12134   vl_api_control_ping_t *mp_ping;
12135   u32 sw_if_index = ~0;
12136   u8 sw_if_index_set = 0;
12137   u8 ipv4_set = 0;
12138   u8 ipv6_set = 0;
12139   int ret;
12140
12141   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12142     {
12143       if (unformat (i, "sw_if_index %d", &sw_if_index))
12144         sw_if_index_set = 1;
12145       else
12146         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12147         sw_if_index_set = 1;
12148       else if (unformat (i, "ipv4"))
12149         ipv4_set = 1;
12150       else if (unformat (i, "ipv6"))
12151         ipv6_set = 1;
12152       else
12153         break;
12154     }
12155
12156   if (ipv4_set && ipv6_set)
12157     {
12158       errmsg ("ipv4 and ipv6 flags cannot be both set");
12159       return -99;
12160     }
12161
12162   if ((!ipv4_set) && (!ipv6_set))
12163     {
12164       errmsg ("no ipv4 nor ipv6 flag set");
12165       return -99;
12166     }
12167
12168   if (sw_if_index_set == 0)
12169     {
12170       errmsg ("missing interface name or sw_if_index");
12171       return -99;
12172     }
12173
12174   vam->current_sw_if_index = sw_if_index;
12175   vam->is_ipv6 = ipv6_set;
12176
12177   M (IP_ADDRESS_DUMP, mp);
12178   mp->sw_if_index = ntohl (sw_if_index);
12179   mp->is_ipv6 = ipv6_set;
12180   S (mp);
12181
12182   /* Use a control ping for synchronization */
12183   M (CONTROL_PING, mp_ping);
12184   S (mp_ping);
12185
12186   W (ret);
12187   return ret;
12188 }
12189
12190 static int
12191 api_ip_dump (vat_main_t * vam)
12192 {
12193   vl_api_ip_dump_t *mp;
12194   vl_api_control_ping_t *mp_ping;
12195   unformat_input_t *in = vam->input;
12196   int ipv4_set = 0;
12197   int ipv6_set = 0;
12198   int is_ipv6;
12199   int i;
12200   int ret;
12201
12202   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
12203     {
12204       if (unformat (in, "ipv4"))
12205         ipv4_set = 1;
12206       else if (unformat (in, "ipv6"))
12207         ipv6_set = 1;
12208       else
12209         break;
12210     }
12211
12212   if (ipv4_set && ipv6_set)
12213     {
12214       errmsg ("ipv4 and ipv6 flags cannot be both set");
12215       return -99;
12216     }
12217
12218   if ((!ipv4_set) && (!ipv6_set))
12219     {
12220       errmsg ("no ipv4 nor ipv6 flag set");
12221       return -99;
12222     }
12223
12224   is_ipv6 = ipv6_set;
12225   vam->is_ipv6 = is_ipv6;
12226
12227   /* free old data */
12228   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
12229     {
12230       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
12231     }
12232   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
12233
12234   M (IP_DUMP, mp);
12235   mp->is_ipv6 = ipv6_set;
12236   S (mp);
12237
12238   /* Use a control ping for synchronization */
12239   M (CONTROL_PING, mp_ping);
12240   S (mp_ping);
12241
12242   W (ret);
12243   return ret;
12244 }
12245
12246 static int
12247 api_ipsec_spd_add_del (vat_main_t * vam)
12248 {
12249   unformat_input_t *i = vam->input;
12250   vl_api_ipsec_spd_add_del_t *mp;
12251   u32 spd_id = ~0;
12252   u8 is_add = 1;
12253   int ret;
12254
12255   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12256     {
12257       if (unformat (i, "spd_id %d", &spd_id))
12258         ;
12259       else if (unformat (i, "del"))
12260         is_add = 0;
12261       else
12262         {
12263           clib_warning ("parse error '%U'", format_unformat_error, i);
12264           return -99;
12265         }
12266     }
12267   if (spd_id == ~0)
12268     {
12269       errmsg ("spd_id must be set");
12270       return -99;
12271     }
12272
12273   M (IPSEC_SPD_ADD_DEL, mp);
12274
12275   mp->spd_id = ntohl (spd_id);
12276   mp->is_add = is_add;
12277
12278   S (mp);
12279   W (ret);
12280   return ret;
12281 }
12282
12283 static int
12284 api_ipsec_interface_add_del_spd (vat_main_t * vam)
12285 {
12286   unformat_input_t *i = vam->input;
12287   vl_api_ipsec_interface_add_del_spd_t *mp;
12288   u32 sw_if_index;
12289   u8 sw_if_index_set = 0;
12290   u32 spd_id = (u32) ~ 0;
12291   u8 is_add = 1;
12292   int ret;
12293
12294   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12295     {
12296       if (unformat (i, "del"))
12297         is_add = 0;
12298       else if (unformat (i, "spd_id %d", &spd_id))
12299         ;
12300       else
12301         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12302         sw_if_index_set = 1;
12303       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12304         sw_if_index_set = 1;
12305       else
12306         {
12307           clib_warning ("parse error '%U'", format_unformat_error, i);
12308           return -99;
12309         }
12310
12311     }
12312
12313   if (spd_id == (u32) ~ 0)
12314     {
12315       errmsg ("spd_id must be set");
12316       return -99;
12317     }
12318
12319   if (sw_if_index_set == 0)
12320     {
12321       errmsg ("missing interface name or sw_if_index");
12322       return -99;
12323     }
12324
12325   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
12326
12327   mp->spd_id = ntohl (spd_id);
12328   mp->sw_if_index = ntohl (sw_if_index);
12329   mp->is_add = is_add;
12330
12331   S (mp);
12332   W (ret);
12333   return ret;
12334 }
12335
12336 static int
12337 api_ipsec_spd_add_del_entry (vat_main_t * vam)
12338 {
12339   unformat_input_t *i = vam->input;
12340   vl_api_ipsec_spd_add_del_entry_t *mp;
12341   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
12342   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
12343   i32 priority = 0;
12344   u32 rport_start = 0, rport_stop = (u32) ~ 0;
12345   u32 lport_start = 0, lport_stop = (u32) ~ 0;
12346   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
12347   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
12348   int ret;
12349
12350   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
12351   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
12352   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
12353   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
12354   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
12355   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
12356
12357   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12358     {
12359       if (unformat (i, "del"))
12360         is_add = 0;
12361       if (unformat (i, "outbound"))
12362         is_outbound = 1;
12363       if (unformat (i, "inbound"))
12364         is_outbound = 0;
12365       else if (unformat (i, "spd_id %d", &spd_id))
12366         ;
12367       else if (unformat (i, "sa_id %d", &sa_id))
12368         ;
12369       else if (unformat (i, "priority %d", &priority))
12370         ;
12371       else if (unformat (i, "protocol %d", &protocol))
12372         ;
12373       else if (unformat (i, "lport_start %d", &lport_start))
12374         ;
12375       else if (unformat (i, "lport_stop %d", &lport_stop))
12376         ;
12377       else if (unformat (i, "rport_start %d", &rport_start))
12378         ;
12379       else if (unformat (i, "rport_stop %d", &rport_stop))
12380         ;
12381       else
12382         if (unformat
12383             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
12384         {
12385           is_ipv6 = 0;
12386           is_ip_any = 0;
12387         }
12388       else
12389         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
12390         {
12391           is_ipv6 = 0;
12392           is_ip_any = 0;
12393         }
12394       else
12395         if (unformat
12396             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
12397         {
12398           is_ipv6 = 0;
12399           is_ip_any = 0;
12400         }
12401       else
12402         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
12403         {
12404           is_ipv6 = 0;
12405           is_ip_any = 0;
12406         }
12407       else
12408         if (unformat
12409             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
12410         {
12411           is_ipv6 = 1;
12412           is_ip_any = 0;
12413         }
12414       else
12415         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
12416         {
12417           is_ipv6 = 1;
12418           is_ip_any = 0;
12419         }
12420       else
12421         if (unformat
12422             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
12423         {
12424           is_ipv6 = 1;
12425           is_ip_any = 0;
12426         }
12427       else
12428         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
12429         {
12430           is_ipv6 = 1;
12431           is_ip_any = 0;
12432         }
12433       else
12434         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
12435         {
12436           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
12437             {
12438               clib_warning ("unsupported action: 'resolve'");
12439               return -99;
12440             }
12441         }
12442       else
12443         {
12444           clib_warning ("parse error '%U'", format_unformat_error, i);
12445           return -99;
12446         }
12447
12448     }
12449
12450   M (IPSEC_SPD_ADD_DEL_ENTRY, mp);
12451
12452   mp->spd_id = ntohl (spd_id);
12453   mp->priority = ntohl (priority);
12454   mp->is_outbound = is_outbound;
12455
12456   mp->is_ipv6 = is_ipv6;
12457   if (is_ipv6 || is_ip_any)
12458     {
12459       clib_memcpy (mp->remote_address_start, &raddr6_start,
12460                    sizeof (ip6_address_t));
12461       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
12462                    sizeof (ip6_address_t));
12463       clib_memcpy (mp->local_address_start, &laddr6_start,
12464                    sizeof (ip6_address_t));
12465       clib_memcpy (mp->local_address_stop, &laddr6_stop,
12466                    sizeof (ip6_address_t));
12467     }
12468   else
12469     {
12470       clib_memcpy (mp->remote_address_start, &raddr4_start,
12471                    sizeof (ip4_address_t));
12472       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
12473                    sizeof (ip4_address_t));
12474       clib_memcpy (mp->local_address_start, &laddr4_start,
12475                    sizeof (ip4_address_t));
12476       clib_memcpy (mp->local_address_stop, &laddr4_stop,
12477                    sizeof (ip4_address_t));
12478     }
12479   mp->protocol = (u8) protocol;
12480   mp->local_port_start = ntohs ((u16) lport_start);
12481   mp->local_port_stop = ntohs ((u16) lport_stop);
12482   mp->remote_port_start = ntohs ((u16) rport_start);
12483   mp->remote_port_stop = ntohs ((u16) rport_stop);
12484   mp->policy = (u8) policy;
12485   mp->sa_id = ntohl (sa_id);
12486   mp->is_add = is_add;
12487   mp->is_ip_any = is_ip_any;
12488   S (mp);
12489   W (ret);
12490   return ret;
12491 }
12492
12493 static int
12494 api_ipsec_sad_add_del_entry (vat_main_t * vam)
12495 {
12496   unformat_input_t *i = vam->input;
12497   vl_api_ipsec_sad_add_del_entry_t *mp;
12498   u32 sad_id = 0, spi = 0;
12499   u8 *ck = 0, *ik = 0;
12500   u8 is_add = 1;
12501
12502   u8 protocol = IPSEC_PROTOCOL_AH;
12503   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
12504   u32 crypto_alg = 0, integ_alg = 0;
12505   ip4_address_t tun_src4;
12506   ip4_address_t tun_dst4;
12507   ip6_address_t tun_src6;
12508   ip6_address_t tun_dst6;
12509   int ret;
12510
12511   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12512     {
12513       if (unformat (i, "del"))
12514         is_add = 0;
12515       else if (unformat (i, "sad_id %d", &sad_id))
12516         ;
12517       else if (unformat (i, "spi %d", &spi))
12518         ;
12519       else if (unformat (i, "esp"))
12520         protocol = IPSEC_PROTOCOL_ESP;
12521       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
12522         {
12523           is_tunnel = 1;
12524           is_tunnel_ipv6 = 0;
12525         }
12526       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
12527         {
12528           is_tunnel = 1;
12529           is_tunnel_ipv6 = 0;
12530         }
12531       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
12532         {
12533           is_tunnel = 1;
12534           is_tunnel_ipv6 = 1;
12535         }
12536       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
12537         {
12538           is_tunnel = 1;
12539           is_tunnel_ipv6 = 1;
12540         }
12541       else
12542         if (unformat
12543             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
12544         {
12545           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
12546               crypto_alg >= IPSEC_CRYPTO_N_ALG)
12547             {
12548               clib_warning ("unsupported crypto-alg: '%U'",
12549                             format_ipsec_crypto_alg, crypto_alg);
12550               return -99;
12551             }
12552         }
12553       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
12554         ;
12555       else
12556         if (unformat
12557             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
12558         {
12559           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
12560               integ_alg >= IPSEC_INTEG_N_ALG)
12561             {
12562               clib_warning ("unsupported integ-alg: '%U'",
12563                             format_ipsec_integ_alg, integ_alg);
12564               return -99;
12565             }
12566         }
12567       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
12568         ;
12569       else
12570         {
12571           clib_warning ("parse error '%U'", format_unformat_error, i);
12572           return -99;
12573         }
12574
12575     }
12576
12577   M (IPSEC_SAD_ADD_DEL_ENTRY, mp);
12578
12579   mp->sad_id = ntohl (sad_id);
12580   mp->is_add = is_add;
12581   mp->protocol = protocol;
12582   mp->spi = ntohl (spi);
12583   mp->is_tunnel = is_tunnel;
12584   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
12585   mp->crypto_algorithm = crypto_alg;
12586   mp->integrity_algorithm = integ_alg;
12587   mp->crypto_key_length = vec_len (ck);
12588   mp->integrity_key_length = vec_len (ik);
12589
12590   if (mp->crypto_key_length > sizeof (mp->crypto_key))
12591     mp->crypto_key_length = sizeof (mp->crypto_key);
12592
12593   if (mp->integrity_key_length > sizeof (mp->integrity_key))
12594     mp->integrity_key_length = sizeof (mp->integrity_key);
12595
12596   if (ck)
12597     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
12598   if (ik)
12599     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
12600
12601   if (is_tunnel)
12602     {
12603       if (is_tunnel_ipv6)
12604         {
12605           clib_memcpy (mp->tunnel_src_address, &tun_src6,
12606                        sizeof (ip6_address_t));
12607           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
12608                        sizeof (ip6_address_t));
12609         }
12610       else
12611         {
12612           clib_memcpy (mp->tunnel_src_address, &tun_src4,
12613                        sizeof (ip4_address_t));
12614           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
12615                        sizeof (ip4_address_t));
12616         }
12617     }
12618
12619   S (mp);
12620   W (ret);
12621   return ret;
12622 }
12623
12624 static int
12625 api_ipsec_sa_set_key (vat_main_t * vam)
12626 {
12627   unformat_input_t *i = vam->input;
12628   vl_api_ipsec_sa_set_key_t *mp;
12629   u32 sa_id;
12630   u8 *ck = 0, *ik = 0;
12631   int ret;
12632
12633   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12634     {
12635       if (unformat (i, "sa_id %d", &sa_id))
12636         ;
12637       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
12638         ;
12639       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
12640         ;
12641       else
12642         {
12643           clib_warning ("parse error '%U'", format_unformat_error, i);
12644           return -99;
12645         }
12646     }
12647
12648   M (IPSEC_SA_SET_KEY, mp);
12649
12650   mp->sa_id = ntohl (sa_id);
12651   mp->crypto_key_length = vec_len (ck);
12652   mp->integrity_key_length = vec_len (ik);
12653
12654   if (mp->crypto_key_length > sizeof (mp->crypto_key))
12655     mp->crypto_key_length = sizeof (mp->crypto_key);
12656
12657   if (mp->integrity_key_length > sizeof (mp->integrity_key))
12658     mp->integrity_key_length = sizeof (mp->integrity_key);
12659
12660   if (ck)
12661     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
12662   if (ik)
12663     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
12664
12665   S (mp);
12666   W (ret);
12667   return ret;
12668 }
12669
12670 static int
12671 api_ikev2_profile_add_del (vat_main_t * vam)
12672 {
12673   unformat_input_t *i = vam->input;
12674   vl_api_ikev2_profile_add_del_t *mp;
12675   u8 is_add = 1;
12676   u8 *name = 0;
12677   int ret;
12678
12679   const char *valid_chars = "a-zA-Z0-9_";
12680
12681   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12682     {
12683       if (unformat (i, "del"))
12684         is_add = 0;
12685       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12686         vec_add1 (name, 0);
12687       else
12688         {
12689           errmsg ("parse error '%U'", format_unformat_error, i);
12690           return -99;
12691         }
12692     }
12693
12694   if (!vec_len (name))
12695     {
12696       errmsg ("profile name must be specified");
12697       return -99;
12698     }
12699
12700   if (vec_len (name) > 64)
12701     {
12702       errmsg ("profile name too long");
12703       return -99;
12704     }
12705
12706   M (IKEV2_PROFILE_ADD_DEL, mp);
12707
12708   clib_memcpy (mp->name, name, vec_len (name));
12709   mp->is_add = is_add;
12710   vec_free (name);
12711
12712   S (mp);
12713   W (ret);
12714   return ret;
12715 }
12716
12717 static int
12718 api_ikev2_profile_set_auth (vat_main_t * vam)
12719 {
12720   unformat_input_t *i = vam->input;
12721   vl_api_ikev2_profile_set_auth_t *mp;
12722   u8 *name = 0;
12723   u8 *data = 0;
12724   u32 auth_method = 0;
12725   u8 is_hex = 0;
12726   int ret;
12727
12728   const char *valid_chars = "a-zA-Z0-9_";
12729
12730   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12731     {
12732       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12733         vec_add1 (name, 0);
12734       else if (unformat (i, "auth_method %U",
12735                          unformat_ikev2_auth_method, &auth_method))
12736         ;
12737       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
12738         is_hex = 1;
12739       else if (unformat (i, "auth_data %v", &data))
12740         ;
12741       else
12742         {
12743           errmsg ("parse error '%U'", format_unformat_error, i);
12744           return -99;
12745         }
12746     }
12747
12748   if (!vec_len (name))
12749     {
12750       errmsg ("profile name must be specified");
12751       return -99;
12752     }
12753
12754   if (vec_len (name) > 64)
12755     {
12756       errmsg ("profile name too long");
12757       return -99;
12758     }
12759
12760   if (!vec_len (data))
12761     {
12762       errmsg ("auth_data must be specified");
12763       return -99;
12764     }
12765
12766   if (!auth_method)
12767     {
12768       errmsg ("auth_method must be specified");
12769       return -99;
12770     }
12771
12772   M (IKEV2_PROFILE_SET_AUTH, mp);
12773
12774   mp->is_hex = is_hex;
12775   mp->auth_method = (u8) auth_method;
12776   mp->data_len = vec_len (data);
12777   clib_memcpy (mp->name, name, vec_len (name));
12778   clib_memcpy (mp->data, data, vec_len (data));
12779   vec_free (name);
12780   vec_free (data);
12781
12782   S (mp);
12783   W (ret);
12784   return ret;
12785 }
12786
12787 static int
12788 api_ikev2_profile_set_id (vat_main_t * vam)
12789 {
12790   unformat_input_t *i = vam->input;
12791   vl_api_ikev2_profile_set_id_t *mp;
12792   u8 *name = 0;
12793   u8 *data = 0;
12794   u8 is_local = 0;
12795   u32 id_type = 0;
12796   ip4_address_t ip4;
12797   int ret;
12798
12799   const char *valid_chars = "a-zA-Z0-9_";
12800
12801   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12802     {
12803       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12804         vec_add1 (name, 0);
12805       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
12806         ;
12807       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
12808         {
12809           data = vec_new (u8, 4);
12810           clib_memcpy (data, ip4.as_u8, 4);
12811         }
12812       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
12813         ;
12814       else if (unformat (i, "id_data %v", &data))
12815         ;
12816       else if (unformat (i, "local"))
12817         is_local = 1;
12818       else if (unformat (i, "remote"))
12819         is_local = 0;
12820       else
12821         {
12822           errmsg ("parse error '%U'", format_unformat_error, i);
12823           return -99;
12824         }
12825     }
12826
12827   if (!vec_len (name))
12828     {
12829       errmsg ("profile name must be specified");
12830       return -99;
12831     }
12832
12833   if (vec_len (name) > 64)
12834     {
12835       errmsg ("profile name too long");
12836       return -99;
12837     }
12838
12839   if (!vec_len (data))
12840     {
12841       errmsg ("id_data must be specified");
12842       return -99;
12843     }
12844
12845   if (!id_type)
12846     {
12847       errmsg ("id_type must be specified");
12848       return -99;
12849     }
12850
12851   M (IKEV2_PROFILE_SET_ID, mp);
12852
12853   mp->is_local = is_local;
12854   mp->id_type = (u8) id_type;
12855   mp->data_len = vec_len (data);
12856   clib_memcpy (mp->name, name, vec_len (name));
12857   clib_memcpy (mp->data, data, vec_len (data));
12858   vec_free (name);
12859   vec_free (data);
12860
12861   S (mp);
12862   W (ret);
12863   return ret;
12864 }
12865
12866 static int
12867 api_ikev2_profile_set_ts (vat_main_t * vam)
12868 {
12869   unformat_input_t *i = vam->input;
12870   vl_api_ikev2_profile_set_ts_t *mp;
12871   u8 *name = 0;
12872   u8 is_local = 0;
12873   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
12874   ip4_address_t start_addr, end_addr;
12875
12876   const char *valid_chars = "a-zA-Z0-9_";
12877   int ret;
12878
12879   start_addr.as_u32 = 0;
12880   end_addr.as_u32 = (u32) ~ 0;
12881
12882   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12883     {
12884       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12885         vec_add1 (name, 0);
12886       else if (unformat (i, "protocol %d", &proto))
12887         ;
12888       else if (unformat (i, "start_port %d", &start_port))
12889         ;
12890       else if (unformat (i, "end_port %d", &end_port))
12891         ;
12892       else
12893         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
12894         ;
12895       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
12896         ;
12897       else if (unformat (i, "local"))
12898         is_local = 1;
12899       else if (unformat (i, "remote"))
12900         is_local = 0;
12901       else
12902         {
12903           errmsg ("parse error '%U'", format_unformat_error, i);
12904           return -99;
12905         }
12906     }
12907
12908   if (!vec_len (name))
12909     {
12910       errmsg ("profile name must be specified");
12911       return -99;
12912     }
12913
12914   if (vec_len (name) > 64)
12915     {
12916       errmsg ("profile name too long");
12917       return -99;
12918     }
12919
12920   M (IKEV2_PROFILE_SET_TS, mp);
12921
12922   mp->is_local = is_local;
12923   mp->proto = (u8) proto;
12924   mp->start_port = (u16) start_port;
12925   mp->end_port = (u16) end_port;
12926   mp->start_addr = start_addr.as_u32;
12927   mp->end_addr = end_addr.as_u32;
12928   clib_memcpy (mp->name, name, vec_len (name));
12929   vec_free (name);
12930
12931   S (mp);
12932   W (ret);
12933   return ret;
12934 }
12935
12936 static int
12937 api_ikev2_set_local_key (vat_main_t * vam)
12938 {
12939   unformat_input_t *i = vam->input;
12940   vl_api_ikev2_set_local_key_t *mp;
12941   u8 *file = 0;
12942   int ret;
12943
12944   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12945     {
12946       if (unformat (i, "file %v", &file))
12947         vec_add1 (file, 0);
12948       else
12949         {
12950           errmsg ("parse error '%U'", format_unformat_error, i);
12951           return -99;
12952         }
12953     }
12954
12955   if (!vec_len (file))
12956     {
12957       errmsg ("RSA key file must be specified");
12958       return -99;
12959     }
12960
12961   if (vec_len (file) > 256)
12962     {
12963       errmsg ("file name too long");
12964       return -99;
12965     }
12966
12967   M (IKEV2_SET_LOCAL_KEY, mp);
12968
12969   clib_memcpy (mp->key_file, file, vec_len (file));
12970   vec_free (file);
12971
12972   S (mp);
12973   W (ret);
12974   return ret;
12975 }
12976
12977 static int
12978 api_ikev2_set_responder (vat_main_t * vam)
12979 {
12980   unformat_input_t *i = vam->input;
12981   vl_api_ikev2_set_responder_t *mp;
12982   int ret;
12983   u8 *name = 0;
12984   u32 sw_if_index = ~0;
12985   ip4_address_t address;
12986
12987   const char *valid_chars = "a-zA-Z0-9_";
12988
12989   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12990     {
12991       if (unformat
12992           (i, "%U interface %d address %U", unformat_token, valid_chars,
12993            &name, &sw_if_index, unformat_ip4_address, &address))
12994         vec_add1 (name, 0);
12995       else
12996         {
12997           errmsg ("parse error '%U'", format_unformat_error, i);
12998           return -99;
12999         }
13000     }
13001
13002   if (!vec_len (name))
13003     {
13004       errmsg ("profile name must be specified");
13005       return -99;
13006     }
13007
13008   if (vec_len (name) > 64)
13009     {
13010       errmsg ("profile name too long");
13011       return -99;
13012     }
13013
13014   M (IKEV2_SET_RESPONDER, mp);
13015
13016   clib_memcpy (mp->name, name, vec_len (name));
13017   vec_free (name);
13018
13019   mp->sw_if_index = sw_if_index;
13020   clib_memcpy (mp->address, &address, sizeof (address));
13021
13022   S (mp);
13023   W (ret);
13024   return ret;
13025 }
13026
13027 static int
13028 api_ikev2_set_ike_transforms (vat_main_t * vam)
13029 {
13030   unformat_input_t *i = vam->input;
13031   vl_api_ikev2_set_ike_transforms_t *mp;
13032   int ret;
13033   u8 *name = 0;
13034   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
13035
13036   const char *valid_chars = "a-zA-Z0-9_";
13037
13038   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13039     {
13040       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
13041                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
13042         vec_add1 (name, 0);
13043       else
13044         {
13045           errmsg ("parse error '%U'", format_unformat_error, i);
13046           return -99;
13047         }
13048     }
13049
13050   if (!vec_len (name))
13051     {
13052       errmsg ("profile name must be specified");
13053       return -99;
13054     }
13055
13056   if (vec_len (name) > 64)
13057     {
13058       errmsg ("profile name too long");
13059       return -99;
13060     }
13061
13062   M (IKEV2_SET_IKE_TRANSFORMS, mp);
13063
13064   clib_memcpy (mp->name, name, vec_len (name));
13065   vec_free (name);
13066   mp->crypto_alg = crypto_alg;
13067   mp->crypto_key_size = crypto_key_size;
13068   mp->integ_alg = integ_alg;
13069   mp->dh_group = dh_group;
13070
13071   S (mp);
13072   W (ret);
13073   return ret;
13074 }
13075
13076
13077 static int
13078 api_ikev2_set_esp_transforms (vat_main_t * vam)
13079 {
13080   unformat_input_t *i = vam->input;
13081   vl_api_ikev2_set_esp_transforms_t *mp;
13082   int ret;
13083   u8 *name = 0;
13084   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
13085
13086   const char *valid_chars = "a-zA-Z0-9_";
13087
13088   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13089     {
13090       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
13091                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
13092         vec_add1 (name, 0);
13093       else
13094         {
13095           errmsg ("parse error '%U'", format_unformat_error, i);
13096           return -99;
13097         }
13098     }
13099
13100   if (!vec_len (name))
13101     {
13102       errmsg ("profile name must be specified");
13103       return -99;
13104     }
13105
13106   if (vec_len (name) > 64)
13107     {
13108       errmsg ("profile name too long");
13109       return -99;
13110     }
13111
13112   M (IKEV2_SET_ESP_TRANSFORMS, mp);
13113
13114   clib_memcpy (mp->name, name, vec_len (name));
13115   vec_free (name);
13116   mp->crypto_alg = crypto_alg;
13117   mp->crypto_key_size = crypto_key_size;
13118   mp->integ_alg = integ_alg;
13119   mp->dh_group = dh_group;
13120
13121   S (mp);
13122   W (ret);
13123   return ret;
13124 }
13125
13126 static int
13127 api_ikev2_set_sa_lifetime (vat_main_t * vam)
13128 {
13129   unformat_input_t *i = vam->input;
13130   vl_api_ikev2_set_sa_lifetime_t *mp;
13131   int ret;
13132   u8 *name = 0;
13133   u64 lifetime, lifetime_maxdata;
13134   u32 lifetime_jitter, handover;
13135
13136   const char *valid_chars = "a-zA-Z0-9_";
13137
13138   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13139     {
13140       if (unformat (i, "%U %lu %u %u %lu", unformat_token, valid_chars, &name,
13141                     &lifetime, &lifetime_jitter, &handover,
13142                     &lifetime_maxdata))
13143         vec_add1 (name, 0);
13144       else
13145         {
13146           errmsg ("parse error '%U'", format_unformat_error, i);
13147           return -99;
13148         }
13149     }
13150
13151   if (!vec_len (name))
13152     {
13153       errmsg ("profile name must be specified");
13154       return -99;
13155     }
13156
13157   if (vec_len (name) > 64)
13158     {
13159       errmsg ("profile name too long");
13160       return -99;
13161     }
13162
13163   M (IKEV2_SET_SA_LIFETIME, mp);
13164
13165   clib_memcpy (mp->name, name, vec_len (name));
13166   vec_free (name);
13167   mp->lifetime = lifetime;
13168   mp->lifetime_jitter = lifetime_jitter;
13169   mp->handover = handover;
13170   mp->lifetime_maxdata = lifetime_maxdata;
13171
13172   S (mp);
13173   W (ret);
13174   return ret;
13175 }
13176
13177 static int
13178 api_ikev2_initiate_sa_init (vat_main_t * vam)
13179 {
13180   unformat_input_t *i = vam->input;
13181   vl_api_ikev2_initiate_sa_init_t *mp;
13182   int ret;
13183   u8 *name = 0;
13184
13185   const char *valid_chars = "a-zA-Z0-9_";
13186
13187   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13188     {
13189       if (unformat (i, "%U", unformat_token, valid_chars, &name))
13190         vec_add1 (name, 0);
13191       else
13192         {
13193           errmsg ("parse error '%U'", format_unformat_error, i);
13194           return -99;
13195         }
13196     }
13197
13198   if (!vec_len (name))
13199     {
13200       errmsg ("profile name must be specified");
13201       return -99;
13202     }
13203
13204   if (vec_len (name) > 64)
13205     {
13206       errmsg ("profile name too long");
13207       return -99;
13208     }
13209
13210   M (IKEV2_INITIATE_SA_INIT, mp);
13211
13212   clib_memcpy (mp->name, name, vec_len (name));
13213   vec_free (name);
13214
13215   S (mp);
13216   W (ret);
13217   return ret;
13218 }
13219
13220 static int
13221 api_ikev2_initiate_del_ike_sa (vat_main_t * vam)
13222 {
13223   unformat_input_t *i = vam->input;
13224   vl_api_ikev2_initiate_del_ike_sa_t *mp;
13225   int ret;
13226   u64 ispi;
13227
13228
13229   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13230     {
13231       if (unformat (i, "%lx", &ispi))
13232         ;
13233       else
13234         {
13235           errmsg ("parse error '%U'", format_unformat_error, i);
13236           return -99;
13237         }
13238     }
13239
13240   M (IKEV2_INITIATE_DEL_IKE_SA, mp);
13241
13242   mp->ispi = ispi;
13243
13244   S (mp);
13245   W (ret);
13246   return ret;
13247 }
13248
13249 static int
13250 api_ikev2_initiate_del_child_sa (vat_main_t * vam)
13251 {
13252   unformat_input_t *i = vam->input;
13253   vl_api_ikev2_initiate_del_child_sa_t *mp;
13254   int ret;
13255   u32 ispi;
13256
13257
13258   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13259     {
13260       if (unformat (i, "%x", &ispi))
13261         ;
13262       else
13263         {
13264           errmsg ("parse error '%U'", format_unformat_error, i);
13265           return -99;
13266         }
13267     }
13268
13269   M (IKEV2_INITIATE_DEL_CHILD_SA, mp);
13270
13271   mp->ispi = ispi;
13272
13273   S (mp);
13274   W (ret);
13275   return ret;
13276 }
13277
13278 static int
13279 api_ikev2_initiate_rekey_child_sa (vat_main_t * vam)
13280 {
13281   unformat_input_t *i = vam->input;
13282   vl_api_ikev2_initiate_rekey_child_sa_t *mp;
13283   int ret;
13284   u32 ispi;
13285
13286
13287   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13288     {
13289       if (unformat (i, "%x", &ispi))
13290         ;
13291       else
13292         {
13293           errmsg ("parse error '%U'", format_unformat_error, i);
13294           return -99;
13295         }
13296     }
13297
13298   M (IKEV2_INITIATE_REKEY_CHILD_SA, mp);
13299
13300   mp->ispi = ispi;
13301
13302   S (mp);
13303   W (ret);
13304   return ret;
13305 }
13306
13307 /*
13308  * MAP
13309  */
13310 static int
13311 api_map_add_domain (vat_main_t * vam)
13312 {
13313   unformat_input_t *i = vam->input;
13314   vl_api_map_add_domain_t *mp;
13315
13316   ip4_address_t ip4_prefix;
13317   ip6_address_t ip6_prefix;
13318   ip6_address_t ip6_src;
13319   u32 num_m_args = 0;
13320   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
13321     0, psid_length = 0;
13322   u8 is_translation = 0;
13323   u32 mtu = 0;
13324   u32 ip6_src_len = 128;
13325   int ret;
13326
13327   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13328     {
13329       if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
13330                     &ip4_prefix, &ip4_prefix_len))
13331         num_m_args++;
13332       else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
13333                          &ip6_prefix, &ip6_prefix_len))
13334         num_m_args++;
13335       else
13336         if (unformat
13337             (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
13338              &ip6_src_len))
13339         num_m_args++;
13340       else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
13341         num_m_args++;
13342       else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
13343         num_m_args++;
13344       else if (unformat (i, "psid-offset %d", &psid_offset))
13345         num_m_args++;
13346       else if (unformat (i, "psid-len %d", &psid_length))
13347         num_m_args++;
13348       else if (unformat (i, "mtu %d", &mtu))
13349         num_m_args++;
13350       else if (unformat (i, "map-t"))
13351         is_translation = 1;
13352       else
13353         {
13354           clib_warning ("parse error '%U'", format_unformat_error, i);
13355           return -99;
13356         }
13357     }
13358
13359   if (num_m_args < 3)
13360     {
13361       errmsg ("mandatory argument(s) missing");
13362       return -99;
13363     }
13364
13365   /* Construct the API message */
13366   M (MAP_ADD_DOMAIN, mp);
13367
13368   clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
13369   mp->ip4_prefix_len = ip4_prefix_len;
13370
13371   clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
13372   mp->ip6_prefix_len = ip6_prefix_len;
13373
13374   clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
13375   mp->ip6_src_prefix_len = ip6_src_len;
13376
13377   mp->ea_bits_len = ea_bits_len;
13378   mp->psid_offset = psid_offset;
13379   mp->psid_length = psid_length;
13380   mp->is_translation = is_translation;
13381   mp->mtu = htons (mtu);
13382
13383   /* send it... */
13384   S (mp);
13385
13386   /* Wait for a reply, return good/bad news  */
13387   W (ret);
13388   return ret;
13389 }
13390
13391 static int
13392 api_map_del_domain (vat_main_t * vam)
13393 {
13394   unformat_input_t *i = vam->input;
13395   vl_api_map_del_domain_t *mp;
13396
13397   u32 num_m_args = 0;
13398   u32 index;
13399   int ret;
13400
13401   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13402     {
13403       if (unformat (i, "index %d", &index))
13404         num_m_args++;
13405       else
13406         {
13407           clib_warning ("parse error '%U'", format_unformat_error, i);
13408           return -99;
13409         }
13410     }
13411
13412   if (num_m_args != 1)
13413     {
13414       errmsg ("mandatory argument(s) missing");
13415       return -99;
13416     }
13417
13418   /* Construct the API message */
13419   M (MAP_DEL_DOMAIN, mp);
13420
13421   mp->index = ntohl (index);
13422
13423   /* send it... */
13424   S (mp);
13425
13426   /* Wait for a reply, return good/bad news  */
13427   W (ret);
13428   return ret;
13429 }
13430
13431 static int
13432 api_map_add_del_rule (vat_main_t * vam)
13433 {
13434   unformat_input_t *i = vam->input;
13435   vl_api_map_add_del_rule_t *mp;
13436   u8 is_add = 1;
13437   ip6_address_t ip6_dst;
13438   u32 num_m_args = 0, index, psid = 0;
13439   int ret;
13440
13441   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13442     {
13443       if (unformat (i, "index %d", &index))
13444         num_m_args++;
13445       else if (unformat (i, "psid %d", &psid))
13446         num_m_args++;
13447       else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
13448         num_m_args++;
13449       else if (unformat (i, "del"))
13450         {
13451           is_add = 0;
13452         }
13453       else
13454         {
13455           clib_warning ("parse error '%U'", format_unformat_error, i);
13456           return -99;
13457         }
13458     }
13459
13460   /* Construct the API message */
13461   M (MAP_ADD_DEL_RULE, mp);
13462
13463   mp->index = ntohl (index);
13464   mp->is_add = is_add;
13465   clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
13466   mp->psid = ntohs (psid);
13467
13468   /* send it... */
13469   S (mp);
13470
13471   /* Wait for a reply, return good/bad news  */
13472   W (ret);
13473   return ret;
13474 }
13475
13476 static int
13477 api_map_domain_dump (vat_main_t * vam)
13478 {
13479   vl_api_map_domain_dump_t *mp;
13480   vl_api_control_ping_t *mp_ping;
13481   int ret;
13482
13483   /* Construct the API message */
13484   M (MAP_DOMAIN_DUMP, mp);
13485
13486   /* send it... */
13487   S (mp);
13488
13489   /* Use a control ping for synchronization */
13490   M (CONTROL_PING, mp_ping);
13491   S (mp_ping);
13492
13493   W (ret);
13494   return ret;
13495 }
13496
13497 static int
13498 api_map_rule_dump (vat_main_t * vam)
13499 {
13500   unformat_input_t *i = vam->input;
13501   vl_api_map_rule_dump_t *mp;
13502   vl_api_control_ping_t *mp_ping;
13503   u32 domain_index = ~0;
13504   int ret;
13505
13506   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13507     {
13508       if (unformat (i, "index %u", &domain_index))
13509         ;
13510       else
13511         break;
13512     }
13513
13514   if (domain_index == ~0)
13515     {
13516       clib_warning ("parse error: domain index expected");
13517       return -99;
13518     }
13519
13520   /* Construct the API message */
13521   M (MAP_RULE_DUMP, mp);
13522
13523   mp->domain_index = htonl (domain_index);
13524
13525   /* send it... */
13526   S (mp);
13527
13528   /* Use a control ping for synchronization */
13529   M (CONTROL_PING, mp_ping);
13530   S (mp_ping);
13531
13532   W (ret);
13533   return ret;
13534 }
13535
13536 static void vl_api_map_add_domain_reply_t_handler
13537   (vl_api_map_add_domain_reply_t * mp)
13538 {
13539   vat_main_t *vam = &vat_main;
13540   i32 retval = ntohl (mp->retval);
13541
13542   if (vam->async_mode)
13543     {
13544       vam->async_errors += (retval < 0);
13545     }
13546   else
13547     {
13548       vam->retval = retval;
13549       vam->result_ready = 1;
13550     }
13551 }
13552
13553 static void vl_api_map_add_domain_reply_t_handler_json
13554   (vl_api_map_add_domain_reply_t * mp)
13555 {
13556   vat_main_t *vam = &vat_main;
13557   vat_json_node_t node;
13558
13559   vat_json_init_object (&node);
13560   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
13561   vat_json_object_add_uint (&node, "index", ntohl (mp->index));
13562
13563   vat_json_print (vam->ofp, &node);
13564   vat_json_free (&node);
13565
13566   vam->retval = ntohl (mp->retval);
13567   vam->result_ready = 1;
13568 }
13569
13570 static int
13571 api_get_first_msg_id (vat_main_t * vam)
13572 {
13573   vl_api_get_first_msg_id_t *mp;
13574   unformat_input_t *i = vam->input;
13575   u8 *name;
13576   u8 name_set = 0;
13577   int ret;
13578
13579   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13580     {
13581       if (unformat (i, "client %s", &name))
13582         name_set = 1;
13583       else
13584         break;
13585     }
13586
13587   if (name_set == 0)
13588     {
13589       errmsg ("missing client name");
13590       return -99;
13591     }
13592   vec_add1 (name, 0);
13593
13594   if (vec_len (name) > 63)
13595     {
13596       errmsg ("client name too long");
13597       return -99;
13598     }
13599
13600   M (GET_FIRST_MSG_ID, mp);
13601   clib_memcpy (mp->name, name, vec_len (name));
13602   S (mp);
13603   W (ret);
13604   return ret;
13605 }
13606
13607 static int
13608 api_cop_interface_enable_disable (vat_main_t * vam)
13609 {
13610   unformat_input_t *line_input = vam->input;
13611   vl_api_cop_interface_enable_disable_t *mp;
13612   u32 sw_if_index = ~0;
13613   u8 enable_disable = 1;
13614   int ret;
13615
13616   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13617     {
13618       if (unformat (line_input, "disable"))
13619         enable_disable = 0;
13620       if (unformat (line_input, "enable"))
13621         enable_disable = 1;
13622       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
13623                          vam, &sw_if_index))
13624         ;
13625       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13626         ;
13627       else
13628         break;
13629     }
13630
13631   if (sw_if_index == ~0)
13632     {
13633       errmsg ("missing interface name or sw_if_index");
13634       return -99;
13635     }
13636
13637   /* Construct the API message */
13638   M (COP_INTERFACE_ENABLE_DISABLE, mp);
13639   mp->sw_if_index = ntohl (sw_if_index);
13640   mp->enable_disable = enable_disable;
13641
13642   /* send it... */
13643   S (mp);
13644   /* Wait for the reply */
13645   W (ret);
13646   return ret;
13647 }
13648
13649 static int
13650 api_cop_whitelist_enable_disable (vat_main_t * vam)
13651 {
13652   unformat_input_t *line_input = vam->input;
13653   vl_api_cop_whitelist_enable_disable_t *mp;
13654   u32 sw_if_index = ~0;
13655   u8 ip4 = 0, ip6 = 0, default_cop = 0;
13656   u32 fib_id = 0;
13657   int ret;
13658
13659   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13660     {
13661       if (unformat (line_input, "ip4"))
13662         ip4 = 1;
13663       else if (unformat (line_input, "ip6"))
13664         ip6 = 1;
13665       else if (unformat (line_input, "default"))
13666         default_cop = 1;
13667       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
13668                          vam, &sw_if_index))
13669         ;
13670       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13671         ;
13672       else if (unformat (line_input, "fib-id %d", &fib_id))
13673         ;
13674       else
13675         break;
13676     }
13677
13678   if (sw_if_index == ~0)
13679     {
13680       errmsg ("missing interface name or sw_if_index");
13681       return -99;
13682     }
13683
13684   /* Construct the API message */
13685   M (COP_WHITELIST_ENABLE_DISABLE, mp);
13686   mp->sw_if_index = ntohl (sw_if_index);
13687   mp->fib_id = ntohl (fib_id);
13688   mp->ip4 = ip4;
13689   mp->ip6 = ip6;
13690   mp->default_cop = default_cop;
13691
13692   /* send it... */
13693   S (mp);
13694   /* Wait for the reply */
13695   W (ret);
13696   return ret;
13697 }
13698
13699 static int
13700 api_get_node_graph (vat_main_t * vam)
13701 {
13702   vl_api_get_node_graph_t *mp;
13703   int ret;
13704
13705   M (GET_NODE_GRAPH, mp);
13706
13707   /* send it... */
13708   S (mp);
13709   /* Wait for the reply */
13710   W (ret);
13711   return ret;
13712 }
13713
13714 /* *INDENT-OFF* */
13715 /** Used for parsing LISP eids */
13716 typedef CLIB_PACKED(struct{
13717   u8 addr[16];   /**< eid address */
13718   u32 len;       /**< prefix length if IP */
13719   u8 type;      /**< type of eid */
13720 }) lisp_eid_vat_t;
13721 /* *INDENT-ON* */
13722
13723 static uword
13724 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
13725 {
13726   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
13727
13728   memset (a, 0, sizeof (a[0]));
13729
13730   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
13731     {
13732       a->type = 0;              /* ipv4 type */
13733     }
13734   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
13735     {
13736       a->type = 1;              /* ipv6 type */
13737     }
13738   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
13739     {
13740       a->type = 2;              /* mac type */
13741     }
13742   else
13743     {
13744       return 0;
13745     }
13746
13747   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
13748     {
13749       return 0;
13750     }
13751
13752   return 1;
13753 }
13754
13755 static int
13756 lisp_eid_size_vat (u8 type)
13757 {
13758   switch (type)
13759     {
13760     case 0:
13761       return 4;
13762     case 1:
13763       return 16;
13764     case 2:
13765       return 6;
13766     }
13767   return 0;
13768 }
13769
13770 static void
13771 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
13772 {
13773   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
13774 }
13775
13776 static int
13777 api_one_add_del_locator_set (vat_main_t * vam)
13778 {
13779   unformat_input_t *input = vam->input;
13780   vl_api_one_add_del_locator_set_t *mp;
13781   u8 is_add = 1;
13782   u8 *locator_set_name = NULL;
13783   u8 locator_set_name_set = 0;
13784   vl_api_local_locator_t locator, *locators = 0;
13785   u32 sw_if_index, priority, weight;
13786   u32 data_len = 0;
13787
13788   int ret;
13789   /* Parse args required to build the message */
13790   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13791     {
13792       if (unformat (input, "del"))
13793         {
13794           is_add = 0;
13795         }
13796       else if (unformat (input, "locator-set %s", &locator_set_name))
13797         {
13798           locator_set_name_set = 1;
13799         }
13800       else if (unformat (input, "sw_if_index %u p %u w %u",
13801                          &sw_if_index, &priority, &weight))
13802         {
13803           locator.sw_if_index = htonl (sw_if_index);
13804           locator.priority = priority;
13805           locator.weight = weight;
13806           vec_add1 (locators, locator);
13807         }
13808       else
13809         if (unformat
13810             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
13811              &sw_if_index, &priority, &weight))
13812         {
13813           locator.sw_if_index = htonl (sw_if_index);
13814           locator.priority = priority;
13815           locator.weight = weight;
13816           vec_add1 (locators, locator);
13817         }
13818       else
13819         break;
13820     }
13821
13822   if (locator_set_name_set == 0)
13823     {
13824       errmsg ("missing locator-set name");
13825       vec_free (locators);
13826       return -99;
13827     }
13828
13829   if (vec_len (locator_set_name) > 64)
13830     {
13831       errmsg ("locator-set name too long");
13832       vec_free (locator_set_name);
13833       vec_free (locators);
13834       return -99;
13835     }
13836   vec_add1 (locator_set_name, 0);
13837
13838   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
13839
13840   /* Construct the API message */
13841   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
13842
13843   mp->is_add = is_add;
13844   clib_memcpy (mp->locator_set_name, locator_set_name,
13845                vec_len (locator_set_name));
13846   vec_free (locator_set_name);
13847
13848   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
13849   if (locators)
13850     clib_memcpy (mp->locators, locators, data_len);
13851   vec_free (locators);
13852
13853   /* send it... */
13854   S (mp);
13855
13856   /* Wait for a reply... */
13857   W (ret);
13858   return ret;
13859 }
13860
13861 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
13862
13863 static int
13864 api_one_add_del_locator (vat_main_t * vam)
13865 {
13866   unformat_input_t *input = vam->input;
13867   vl_api_one_add_del_locator_t *mp;
13868   u32 tmp_if_index = ~0;
13869   u32 sw_if_index = ~0;
13870   u8 sw_if_index_set = 0;
13871   u8 sw_if_index_if_name_set = 0;
13872   u32 priority = ~0;
13873   u8 priority_set = 0;
13874   u32 weight = ~0;
13875   u8 weight_set = 0;
13876   u8 is_add = 1;
13877   u8 *locator_set_name = NULL;
13878   u8 locator_set_name_set = 0;
13879   int ret;
13880
13881   /* Parse args required to build the message */
13882   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13883     {
13884       if (unformat (input, "del"))
13885         {
13886           is_add = 0;
13887         }
13888       else if (unformat (input, "locator-set %s", &locator_set_name))
13889         {
13890           locator_set_name_set = 1;
13891         }
13892       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
13893                          &tmp_if_index))
13894         {
13895           sw_if_index_if_name_set = 1;
13896           sw_if_index = tmp_if_index;
13897         }
13898       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
13899         {
13900           sw_if_index_set = 1;
13901           sw_if_index = tmp_if_index;
13902         }
13903       else if (unformat (input, "p %d", &priority))
13904         {
13905           priority_set = 1;
13906         }
13907       else if (unformat (input, "w %d", &weight))
13908         {
13909           weight_set = 1;
13910         }
13911       else
13912         break;
13913     }
13914
13915   if (locator_set_name_set == 0)
13916     {
13917       errmsg ("missing locator-set name");
13918       return -99;
13919     }
13920
13921   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
13922     {
13923       errmsg ("missing sw_if_index");
13924       vec_free (locator_set_name);
13925       return -99;
13926     }
13927
13928   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
13929     {
13930       errmsg ("cannot use both params interface name and sw_if_index");
13931       vec_free (locator_set_name);
13932       return -99;
13933     }
13934
13935   if (priority_set == 0)
13936     {
13937       errmsg ("missing locator-set priority");
13938       vec_free (locator_set_name);
13939       return -99;
13940     }
13941
13942   if (weight_set == 0)
13943     {
13944       errmsg ("missing locator-set weight");
13945       vec_free (locator_set_name);
13946       return -99;
13947     }
13948
13949   if (vec_len (locator_set_name) > 64)
13950     {
13951       errmsg ("locator-set name too long");
13952       vec_free (locator_set_name);
13953       return -99;
13954     }
13955   vec_add1 (locator_set_name, 0);
13956
13957   /* Construct the API message */
13958   M (ONE_ADD_DEL_LOCATOR, mp);
13959
13960   mp->is_add = is_add;
13961   mp->sw_if_index = ntohl (sw_if_index);
13962   mp->priority = priority;
13963   mp->weight = weight;
13964   clib_memcpy (mp->locator_set_name, locator_set_name,
13965                vec_len (locator_set_name));
13966   vec_free (locator_set_name);
13967
13968   /* send it... */
13969   S (mp);
13970
13971   /* Wait for a reply... */
13972   W (ret);
13973   return ret;
13974 }
13975
13976 #define api_lisp_add_del_locator api_one_add_del_locator
13977
13978 uword
13979 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
13980 {
13981   u32 *key_id = va_arg (*args, u32 *);
13982   u8 *s = 0;
13983
13984   if (unformat (input, "%s", &s))
13985     {
13986       if (!strcmp ((char *) s, "sha1"))
13987         key_id[0] = HMAC_SHA_1_96;
13988       else if (!strcmp ((char *) s, "sha256"))
13989         key_id[0] = HMAC_SHA_256_128;
13990       else
13991         {
13992           clib_warning ("invalid key_id: '%s'", s);
13993           key_id[0] = HMAC_NO_KEY;
13994         }
13995     }
13996   else
13997     return 0;
13998
13999   vec_free (s);
14000   return 1;
14001 }
14002
14003 static int
14004 api_one_add_del_local_eid (vat_main_t * vam)
14005 {
14006   unformat_input_t *input = vam->input;
14007   vl_api_one_add_del_local_eid_t *mp;
14008   u8 is_add = 1;
14009   u8 eid_set = 0;
14010   lisp_eid_vat_t _eid, *eid = &_eid;
14011   u8 *locator_set_name = 0;
14012   u8 locator_set_name_set = 0;
14013   u32 vni = 0;
14014   u16 key_id = 0;
14015   u8 *key = 0;
14016   int ret;
14017
14018   /* Parse args required to build the message */
14019   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14020     {
14021       if (unformat (input, "del"))
14022         {
14023           is_add = 0;
14024         }
14025       else if (unformat (input, "vni %d", &vni))
14026         {
14027           ;
14028         }
14029       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
14030         {
14031           eid_set = 1;
14032         }
14033       else if (unformat (input, "locator-set %s", &locator_set_name))
14034         {
14035           locator_set_name_set = 1;
14036         }
14037       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
14038         ;
14039       else if (unformat (input, "secret-key %_%v%_", &key))
14040         ;
14041       else
14042         break;
14043     }
14044
14045   if (locator_set_name_set == 0)
14046     {
14047       errmsg ("missing locator-set name");
14048       return -99;
14049     }
14050
14051   if (0 == eid_set)
14052     {
14053       errmsg ("EID address not set!");
14054       vec_free (locator_set_name);
14055       return -99;
14056     }
14057
14058   if (key && (0 == key_id))
14059     {
14060       errmsg ("invalid key_id!");
14061       return -99;
14062     }
14063
14064   if (vec_len (key) > 64)
14065     {
14066       errmsg ("key too long");
14067       vec_free (key);
14068       return -99;
14069     }
14070
14071   if (vec_len (locator_set_name) > 64)
14072     {
14073       errmsg ("locator-set name too long");
14074       vec_free (locator_set_name);
14075       return -99;
14076     }
14077   vec_add1 (locator_set_name, 0);
14078
14079   /* Construct the API message */
14080   M (ONE_ADD_DEL_LOCAL_EID, mp);
14081
14082   mp->is_add = is_add;
14083   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
14084   mp->eid_type = eid->type;
14085   mp->prefix_len = eid->len;
14086   mp->vni = clib_host_to_net_u32 (vni);
14087   mp->key_id = clib_host_to_net_u16 (key_id);
14088   clib_memcpy (mp->locator_set_name, locator_set_name,
14089                vec_len (locator_set_name));
14090   clib_memcpy (mp->key, key, vec_len (key));
14091
14092   vec_free (locator_set_name);
14093   vec_free (key);
14094
14095   /* send it... */
14096   S (mp);
14097
14098   /* Wait for a reply... */
14099   W (ret);
14100   return ret;
14101 }
14102
14103 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
14104
14105 static int
14106 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
14107 {
14108   u32 dp_table = 0, vni = 0;;
14109   unformat_input_t *input = vam->input;
14110   vl_api_gpe_add_del_fwd_entry_t *mp;
14111   u8 is_add = 1;
14112   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
14113   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
14114   u8 rmt_eid_set = 0, lcl_eid_set = 0;
14115   u32 action = ~0, w;
14116   ip4_address_t rmt_rloc4, lcl_rloc4;
14117   ip6_address_t rmt_rloc6, lcl_rloc6;
14118   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
14119   int ret;
14120
14121   memset (&rloc, 0, sizeof (rloc));
14122
14123   /* Parse args required to build the message */
14124   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14125     {
14126       if (unformat (input, "del"))
14127         is_add = 0;
14128       else if (unformat (input, "add"))
14129         is_add = 1;
14130       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
14131         {
14132           rmt_eid_set = 1;
14133         }
14134       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
14135         {
14136           lcl_eid_set = 1;
14137         }
14138       else if (unformat (input, "vrf %d", &dp_table))
14139         ;
14140       else if (unformat (input, "bd %d", &dp_table))
14141         ;
14142       else if (unformat (input, "vni %d", &vni))
14143         ;
14144       else if (unformat (input, "w %d", &w))
14145         {
14146           if (!curr_rloc)
14147             {
14148               errmsg ("No RLOC configured for setting priority/weight!");
14149               return -99;
14150             }
14151           curr_rloc->weight = w;
14152         }
14153       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
14154                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
14155         {
14156           rloc.is_ip4 = 1;
14157
14158           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
14159           rloc.weight = 0;
14160           vec_add1 (lcl_locs, rloc);
14161
14162           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
14163           vec_add1 (rmt_locs, rloc);
14164           /* weight saved in rmt loc */
14165           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
14166         }
14167       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
14168                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
14169         {
14170           rloc.is_ip4 = 0;
14171           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
14172           rloc.weight = 0;
14173           vec_add1 (lcl_locs, rloc);
14174
14175           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
14176           vec_add1 (rmt_locs, rloc);
14177           /* weight saved in rmt loc */
14178           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
14179         }
14180       else if (unformat (input, "action %d", &action))
14181         {
14182           ;
14183         }
14184       else
14185         {
14186           clib_warning ("parse error '%U'", format_unformat_error, input);
14187           return -99;
14188         }
14189     }
14190
14191   if (!rmt_eid_set)
14192     {
14193       errmsg ("remote eid addresses not set");
14194       return -99;
14195     }
14196
14197   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
14198     {
14199       errmsg ("eid types don't match");
14200       return -99;
14201     }
14202
14203   if (0 == rmt_locs && (u32) ~ 0 == action)
14204     {
14205       errmsg ("action not set for negative mapping");
14206       return -99;
14207     }
14208
14209   /* Construct the API message */
14210   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
14211       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
14212
14213   mp->is_add = is_add;
14214   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
14215   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
14216   mp->eid_type = rmt_eid->type;
14217   mp->dp_table = clib_host_to_net_u32 (dp_table);
14218   mp->vni = clib_host_to_net_u32 (vni);
14219   mp->rmt_len = rmt_eid->len;
14220   mp->lcl_len = lcl_eid->len;
14221   mp->action = action;
14222
14223   if (0 != rmt_locs && 0 != lcl_locs)
14224     {
14225       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
14226       clib_memcpy (mp->locs, lcl_locs,
14227                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
14228
14229       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
14230       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
14231                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
14232     }
14233   vec_free (lcl_locs);
14234   vec_free (rmt_locs);
14235
14236   /* send it... */
14237   S (mp);
14238
14239   /* Wait for a reply... */
14240   W (ret);
14241   return ret;
14242 }
14243
14244 static int
14245 api_one_add_del_map_server (vat_main_t * vam)
14246 {
14247   unformat_input_t *input = vam->input;
14248   vl_api_one_add_del_map_server_t *mp;
14249   u8 is_add = 1;
14250   u8 ipv4_set = 0;
14251   u8 ipv6_set = 0;
14252   ip4_address_t ipv4;
14253   ip6_address_t ipv6;
14254   int ret;
14255
14256   /* Parse args required to build the message */
14257   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14258     {
14259       if (unformat (input, "del"))
14260         {
14261           is_add = 0;
14262         }
14263       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
14264         {
14265           ipv4_set = 1;
14266         }
14267       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
14268         {
14269           ipv6_set = 1;
14270         }
14271       else
14272         break;
14273     }
14274
14275   if (ipv4_set && ipv6_set)
14276     {
14277       errmsg ("both eid v4 and v6 addresses set");
14278       return -99;
14279     }
14280
14281   if (!ipv4_set && !ipv6_set)
14282     {
14283       errmsg ("eid addresses not set");
14284       return -99;
14285     }
14286
14287   /* Construct the API message */
14288   M (ONE_ADD_DEL_MAP_SERVER, mp);
14289
14290   mp->is_add = is_add;
14291   if (ipv6_set)
14292     {
14293       mp->is_ipv6 = 1;
14294       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
14295     }
14296   else
14297     {
14298       mp->is_ipv6 = 0;
14299       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
14300     }
14301
14302   /* send it... */
14303   S (mp);
14304
14305   /* Wait for a reply... */
14306   W (ret);
14307   return ret;
14308 }
14309
14310 #define api_lisp_add_del_map_server api_one_add_del_map_server
14311
14312 static int
14313 api_one_add_del_map_resolver (vat_main_t * vam)
14314 {
14315   unformat_input_t *input = vam->input;
14316   vl_api_one_add_del_map_resolver_t *mp;
14317   u8 is_add = 1;
14318   u8 ipv4_set = 0;
14319   u8 ipv6_set = 0;
14320   ip4_address_t ipv4;
14321   ip6_address_t ipv6;
14322   int ret;
14323
14324   /* Parse args required to build the message */
14325   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14326     {
14327       if (unformat (input, "del"))
14328         {
14329           is_add = 0;
14330         }
14331       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
14332         {
14333           ipv4_set = 1;
14334         }
14335       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
14336         {
14337           ipv6_set = 1;
14338         }
14339       else
14340         break;
14341     }
14342
14343   if (ipv4_set && ipv6_set)
14344     {
14345       errmsg ("both eid v4 and v6 addresses set");
14346       return -99;
14347     }
14348
14349   if (!ipv4_set && !ipv6_set)
14350     {
14351       errmsg ("eid addresses not set");
14352       return -99;
14353     }
14354
14355   /* Construct the API message */
14356   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
14357
14358   mp->is_add = is_add;
14359   if (ipv6_set)
14360     {
14361       mp->is_ipv6 = 1;
14362       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
14363     }
14364   else
14365     {
14366       mp->is_ipv6 = 0;
14367       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
14368     }
14369
14370   /* send it... */
14371   S (mp);
14372
14373   /* Wait for a reply... */
14374   W (ret);
14375   return ret;
14376 }
14377
14378 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
14379
14380 static int
14381 api_lisp_gpe_enable_disable (vat_main_t * vam)
14382 {
14383   unformat_input_t *input = vam->input;
14384   vl_api_gpe_enable_disable_t *mp;
14385   u8 is_set = 0;
14386   u8 is_en = 1;
14387   int ret;
14388
14389   /* Parse args required to build the message */
14390   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14391     {
14392       if (unformat (input, "enable"))
14393         {
14394           is_set = 1;
14395           is_en = 1;
14396         }
14397       else if (unformat (input, "disable"))
14398         {
14399           is_set = 1;
14400           is_en = 0;
14401         }
14402       else
14403         break;
14404     }
14405
14406   if (is_set == 0)
14407     {
14408       errmsg ("Value not set");
14409       return -99;
14410     }
14411
14412   /* Construct the API message */
14413   M (GPE_ENABLE_DISABLE, mp);
14414
14415   mp->is_en = is_en;
14416
14417   /* send it... */
14418   S (mp);
14419
14420   /* Wait for a reply... */
14421   W (ret);
14422   return ret;
14423 }
14424
14425 static int
14426 api_one_rloc_probe_enable_disable (vat_main_t * vam)
14427 {
14428   unformat_input_t *input = vam->input;
14429   vl_api_one_rloc_probe_enable_disable_t *mp;
14430   u8 is_set = 0;
14431   u8 is_en = 0;
14432   int ret;
14433
14434   /* Parse args required to build the message */
14435   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14436     {
14437       if (unformat (input, "enable"))
14438         {
14439           is_set = 1;
14440           is_en = 1;
14441         }
14442       else if (unformat (input, "disable"))
14443         is_set = 1;
14444       else
14445         break;
14446     }
14447
14448   if (!is_set)
14449     {
14450       errmsg ("Value not set");
14451       return -99;
14452     }
14453
14454   /* Construct the API message */
14455   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
14456
14457   mp->is_enabled = is_en;
14458
14459   /* send it... */
14460   S (mp);
14461
14462   /* Wait for a reply... */
14463   W (ret);
14464   return ret;
14465 }
14466
14467 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
14468
14469 static int
14470 api_one_map_register_enable_disable (vat_main_t * vam)
14471 {
14472   unformat_input_t *input = vam->input;
14473   vl_api_one_map_register_enable_disable_t *mp;
14474   u8 is_set = 0;
14475   u8 is_en = 0;
14476   int ret;
14477
14478   /* Parse args required to build the message */
14479   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14480     {
14481       if (unformat (input, "enable"))
14482         {
14483           is_set = 1;
14484           is_en = 1;
14485         }
14486       else if (unformat (input, "disable"))
14487         is_set = 1;
14488       else
14489         break;
14490     }
14491
14492   if (!is_set)
14493     {
14494       errmsg ("Value not set");
14495       return -99;
14496     }
14497
14498   /* Construct the API message */
14499   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
14500
14501   mp->is_enabled = is_en;
14502
14503   /* send it... */
14504   S (mp);
14505
14506   /* Wait for a reply... */
14507   W (ret);
14508   return ret;
14509 }
14510
14511 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
14512
14513 static int
14514 api_one_enable_disable (vat_main_t * vam)
14515 {
14516   unformat_input_t *input = vam->input;
14517   vl_api_one_enable_disable_t *mp;
14518   u8 is_set = 0;
14519   u8 is_en = 0;
14520   int ret;
14521
14522   /* Parse args required to build the message */
14523   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14524     {
14525       if (unformat (input, "enable"))
14526         {
14527           is_set = 1;
14528           is_en = 1;
14529         }
14530       else if (unformat (input, "disable"))
14531         {
14532           is_set = 1;
14533         }
14534       else
14535         break;
14536     }
14537
14538   if (!is_set)
14539     {
14540       errmsg ("Value not set");
14541       return -99;
14542     }
14543
14544   /* Construct the API message */
14545   M (ONE_ENABLE_DISABLE, mp);
14546
14547   mp->is_en = is_en;
14548
14549   /* send it... */
14550   S (mp);
14551
14552   /* Wait for a reply... */
14553   W (ret);
14554   return ret;
14555 }
14556
14557 #define api_lisp_enable_disable api_one_enable_disable
14558
14559 static int
14560 api_show_one_map_register_state (vat_main_t * vam)
14561 {
14562   vl_api_show_one_map_register_state_t *mp;
14563   int ret;
14564
14565   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
14566
14567   /* send */
14568   S (mp);
14569
14570   /* wait for reply */
14571   W (ret);
14572   return ret;
14573 }
14574
14575 #define api_show_lisp_map_register_state api_show_one_map_register_state
14576
14577 static int
14578 api_show_one_rloc_probe_state (vat_main_t * vam)
14579 {
14580   vl_api_show_one_rloc_probe_state_t *mp;
14581   int ret;
14582
14583   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
14584
14585   /* send */
14586   S (mp);
14587
14588   /* wait for reply */
14589   W (ret);
14590   return ret;
14591 }
14592
14593 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
14594
14595 static int
14596 api_one_stats_enable_disable (vat_main_t * vam)
14597 {
14598   vl_api_one_stats_enable_disable_t *mp;
14599   unformat_input_t *input = vam->input;
14600   u8 is_set = 0;
14601   u8 is_en = 0;
14602   int ret;
14603
14604   /* Parse args required to build the message */
14605   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14606     {
14607       if (unformat (input, "enable"))
14608         {
14609           is_set = 1;
14610           is_en = 1;
14611         }
14612       else if (unformat (input, "disable"))
14613         {
14614           is_set = 1;
14615         }
14616       else
14617         break;
14618     }
14619
14620   if (!is_set)
14621     {
14622       errmsg ("Value not set");
14623       return -99;
14624     }
14625
14626   M (ONE_STATS_ENABLE_DISABLE, mp);
14627   mp->is_en = is_en;
14628
14629   /* send */
14630   S (mp);
14631
14632   /* wait for reply */
14633   W (ret);
14634   return ret;
14635 }
14636
14637 static int
14638 api_show_one_stats_enable_disable (vat_main_t * vam)
14639 {
14640   vl_api_show_one_stats_enable_disable_t *mp;
14641   int ret;
14642
14643   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
14644
14645   /* send */
14646   S (mp);
14647
14648   /* wait for reply */
14649   W (ret);
14650   return ret;
14651 }
14652
14653 static int
14654 api_show_one_map_request_mode (vat_main_t * vam)
14655 {
14656   vl_api_show_one_map_request_mode_t *mp;
14657   int ret;
14658
14659   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
14660
14661   /* send */
14662   S (mp);
14663
14664   /* wait for reply */
14665   W (ret);
14666   return ret;
14667 }
14668
14669 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
14670
14671 static int
14672 api_one_map_request_mode (vat_main_t * vam)
14673 {
14674   unformat_input_t *input = vam->input;
14675   vl_api_one_map_request_mode_t *mp;
14676   u8 mode = 0;
14677   int ret;
14678
14679   /* Parse args required to build the message */
14680   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14681     {
14682       if (unformat (input, "dst-only"))
14683         mode = 0;
14684       else if (unformat (input, "src-dst"))
14685         mode = 1;
14686       else
14687         {
14688           errmsg ("parse error '%U'", format_unformat_error, input);
14689           return -99;
14690         }
14691     }
14692
14693   M (ONE_MAP_REQUEST_MODE, mp);
14694
14695   mp->mode = mode;
14696
14697   /* send */
14698   S (mp);
14699
14700   /* wait for reply */
14701   W (ret);
14702   return ret;
14703 }
14704
14705 #define api_lisp_map_request_mode api_one_map_request_mode
14706
14707 /**
14708  * Enable/disable ONE proxy ITR.
14709  *
14710  * @param vam vpp API test context
14711  * @return return code
14712  */
14713 static int
14714 api_one_pitr_set_locator_set (vat_main_t * vam)
14715 {
14716   u8 ls_name_set = 0;
14717   unformat_input_t *input = vam->input;
14718   vl_api_one_pitr_set_locator_set_t *mp;
14719   u8 is_add = 1;
14720   u8 *ls_name = 0;
14721   int ret;
14722
14723   /* Parse args required to build the message */
14724   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14725     {
14726       if (unformat (input, "del"))
14727         is_add = 0;
14728       else if (unformat (input, "locator-set %s", &ls_name))
14729         ls_name_set = 1;
14730       else
14731         {
14732           errmsg ("parse error '%U'", format_unformat_error, input);
14733           return -99;
14734         }
14735     }
14736
14737   if (!ls_name_set)
14738     {
14739       errmsg ("locator-set name not set!");
14740       return -99;
14741     }
14742
14743   M (ONE_PITR_SET_LOCATOR_SET, mp);
14744
14745   mp->is_add = is_add;
14746   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
14747   vec_free (ls_name);
14748
14749   /* send */
14750   S (mp);
14751
14752   /* wait for reply */
14753   W (ret);
14754   return ret;
14755 }
14756
14757 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
14758
14759 static int
14760 api_show_one_pitr (vat_main_t * vam)
14761 {
14762   vl_api_show_one_pitr_t *mp;
14763   int ret;
14764
14765   if (!vam->json_output)
14766     {
14767       print (vam->ofp, "%=20s", "lisp status:");
14768     }
14769
14770   M (SHOW_ONE_PITR, mp);
14771   /* send it... */
14772   S (mp);
14773
14774   /* Wait for a reply... */
14775   W (ret);
14776   return ret;
14777 }
14778
14779 #define api_show_lisp_pitr api_show_one_pitr
14780
14781 static int
14782 api_one_use_petr (vat_main_t * vam)
14783 {
14784   unformat_input_t *input = vam->input;
14785   vl_api_one_use_petr_t *mp;
14786   u8 is_add = 0;
14787   ip_address_t ip;
14788   int ret;
14789
14790   memset (&ip, 0, sizeof (ip));
14791
14792   /* Parse args required to build the message */
14793   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14794     {
14795       if (unformat (input, "disable"))
14796         is_add = 0;
14797       else
14798         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
14799         {
14800           is_add = 1;
14801           ip_addr_version (&ip) = IP4;
14802         }
14803       else
14804         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
14805         {
14806           is_add = 1;
14807           ip_addr_version (&ip) = IP6;
14808         }
14809       else
14810         {
14811           errmsg ("parse error '%U'", format_unformat_error, input);
14812           return -99;
14813         }
14814     }
14815
14816   M (ONE_USE_PETR, mp);
14817
14818   mp->is_add = is_add;
14819   if (is_add)
14820     {
14821       mp->is_ip4 = ip_addr_version (&ip) == IP4 ? 1 : 0;
14822       if (mp->is_ip4)
14823         clib_memcpy (mp->address, &ip, 4);
14824       else
14825         clib_memcpy (mp->address, &ip, 16);
14826     }
14827
14828   /* send */
14829   S (mp);
14830
14831   /* wait for reply */
14832   W (ret);
14833   return ret;
14834 }
14835
14836 #define api_lisp_use_petr api_one_use_petr
14837
14838 static int
14839 api_show_one_use_petr (vat_main_t * vam)
14840 {
14841   vl_api_show_one_use_petr_t *mp;
14842   int ret;
14843
14844   if (!vam->json_output)
14845     {
14846       print (vam->ofp, "%=20s", "Proxy-ETR status:");
14847     }
14848
14849   M (SHOW_ONE_USE_PETR, mp);
14850   /* send it... */
14851   S (mp);
14852
14853   /* Wait for a reply... */
14854   W (ret);
14855   return ret;
14856 }
14857
14858 #define api_show_lisp_use_petr api_show_one_use_petr
14859
14860 /**
14861  * Add/delete mapping between vni and vrf
14862  */
14863 static int
14864 api_one_eid_table_add_del_map (vat_main_t * vam)
14865 {
14866   unformat_input_t *input = vam->input;
14867   vl_api_one_eid_table_add_del_map_t *mp;
14868   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
14869   u32 vni, vrf, bd_index;
14870   int ret;
14871
14872   /* Parse args required to build the message */
14873   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14874     {
14875       if (unformat (input, "del"))
14876         is_add = 0;
14877       else if (unformat (input, "vrf %d", &vrf))
14878         vrf_set = 1;
14879       else if (unformat (input, "bd_index %d", &bd_index))
14880         bd_index_set = 1;
14881       else if (unformat (input, "vni %d", &vni))
14882         vni_set = 1;
14883       else
14884         break;
14885     }
14886
14887   if (!vni_set || (!vrf_set && !bd_index_set))
14888     {
14889       errmsg ("missing arguments!");
14890       return -99;
14891     }
14892
14893   if (vrf_set && bd_index_set)
14894     {
14895       errmsg ("error: both vrf and bd entered!");
14896       return -99;
14897     }
14898
14899   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
14900
14901   mp->is_add = is_add;
14902   mp->vni = htonl (vni);
14903   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
14904   mp->is_l2 = bd_index_set;
14905
14906   /* send */
14907   S (mp);
14908
14909   /* wait for reply */
14910   W (ret);
14911   return ret;
14912 }
14913
14914 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
14915
14916 uword
14917 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
14918 {
14919   u32 *action = va_arg (*args, u32 *);
14920   u8 *s = 0;
14921
14922   if (unformat (input, "%s", &s))
14923     {
14924       if (!strcmp ((char *) s, "no-action"))
14925         action[0] = 0;
14926       else if (!strcmp ((char *) s, "natively-forward"))
14927         action[0] = 1;
14928       else if (!strcmp ((char *) s, "send-map-request"))
14929         action[0] = 2;
14930       else if (!strcmp ((char *) s, "drop"))
14931         action[0] = 3;
14932       else
14933         {
14934           clib_warning ("invalid action: '%s'", s);
14935           action[0] = 3;
14936         }
14937     }
14938   else
14939     return 0;
14940
14941   vec_free (s);
14942   return 1;
14943 }
14944
14945 /**
14946  * Add/del remote mapping to/from ONE control plane
14947  *
14948  * @param vam vpp API test context
14949  * @return return code
14950  */
14951 static int
14952 api_one_add_del_remote_mapping (vat_main_t * vam)
14953 {
14954   unformat_input_t *input = vam->input;
14955   vl_api_one_add_del_remote_mapping_t *mp;
14956   u32 vni = 0;
14957   lisp_eid_vat_t _eid, *eid = &_eid;
14958   lisp_eid_vat_t _seid, *seid = &_seid;
14959   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
14960   u32 action = ~0, p, w, data_len;
14961   ip4_address_t rloc4;
14962   ip6_address_t rloc6;
14963   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
14964   int ret;
14965
14966   memset (&rloc, 0, sizeof (rloc));
14967
14968   /* Parse args required to build the message */
14969   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14970     {
14971       if (unformat (input, "del-all"))
14972         {
14973           del_all = 1;
14974         }
14975       else if (unformat (input, "del"))
14976         {
14977           is_add = 0;
14978         }
14979       else if (unformat (input, "add"))
14980         {
14981           is_add = 1;
14982         }
14983       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
14984         {
14985           eid_set = 1;
14986         }
14987       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
14988         {
14989           seid_set = 1;
14990         }
14991       else if (unformat (input, "vni %d", &vni))
14992         {
14993           ;
14994         }
14995       else if (unformat (input, "p %d w %d", &p, &w))
14996         {
14997           if (!curr_rloc)
14998             {
14999               errmsg ("No RLOC configured for setting priority/weight!");
15000               return -99;
15001             }
15002           curr_rloc->priority = p;
15003           curr_rloc->weight = w;
15004         }
15005       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
15006         {
15007           rloc.is_ip4 = 1;
15008           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
15009           vec_add1 (rlocs, rloc);
15010           curr_rloc = &rlocs[vec_len (rlocs) - 1];
15011         }
15012       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
15013         {
15014           rloc.is_ip4 = 0;
15015           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
15016           vec_add1 (rlocs, rloc);
15017           curr_rloc = &rlocs[vec_len (rlocs) - 1];
15018         }
15019       else if (unformat (input, "action %U",
15020                          unformat_negative_mapping_action, &action))
15021         {
15022           ;
15023         }
15024       else
15025         {
15026           clib_warning ("parse error '%U'", format_unformat_error, input);
15027           return -99;
15028         }
15029     }
15030
15031   if (0 == eid_set)
15032     {
15033       errmsg ("missing params!");
15034       return -99;
15035     }
15036
15037   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
15038     {
15039       errmsg ("no action set for negative map-reply!");
15040       return -99;
15041     }
15042
15043   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
15044
15045   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
15046   mp->is_add = is_add;
15047   mp->vni = htonl (vni);
15048   mp->action = (u8) action;
15049   mp->is_src_dst = seid_set;
15050   mp->eid_len = eid->len;
15051   mp->seid_len = seid->len;
15052   mp->del_all = del_all;
15053   mp->eid_type = eid->type;
15054   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
15055   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
15056
15057   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
15058   clib_memcpy (mp->rlocs, rlocs, data_len);
15059   vec_free (rlocs);
15060
15061   /* send it... */
15062   S (mp);
15063
15064   /* Wait for a reply... */
15065   W (ret);
15066   return ret;
15067 }
15068
15069 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
15070
15071 /**
15072  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
15073  * forwarding entries in data-plane accordingly.
15074  *
15075  * @param vam vpp API test context
15076  * @return return code
15077  */
15078 static int
15079 api_one_add_del_adjacency (vat_main_t * vam)
15080 {
15081   unformat_input_t *input = vam->input;
15082   vl_api_one_add_del_adjacency_t *mp;
15083   u32 vni = 0;
15084   ip4_address_t leid4, reid4;
15085   ip6_address_t leid6, reid6;
15086   u8 reid_mac[6] = { 0 };
15087   u8 leid_mac[6] = { 0 };
15088   u8 reid_type, leid_type;
15089   u32 leid_len = 0, reid_len = 0, len;
15090   u8 is_add = 1;
15091   int ret;
15092
15093   leid_type = reid_type = (u8) ~ 0;
15094
15095   /* Parse args required to build the message */
15096   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15097     {
15098       if (unformat (input, "del"))
15099         {
15100           is_add = 0;
15101         }
15102       else if (unformat (input, "add"))
15103         {
15104           is_add = 1;
15105         }
15106       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
15107                          &reid4, &len))
15108         {
15109           reid_type = 0;        /* ipv4 */
15110           reid_len = len;
15111         }
15112       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
15113                          &reid6, &len))
15114         {
15115           reid_type = 1;        /* ipv6 */
15116           reid_len = len;
15117         }
15118       else if (unformat (input, "reid %U", unformat_ethernet_address,
15119                          reid_mac))
15120         {
15121           reid_type = 2;        /* mac */
15122         }
15123       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
15124                          &leid4, &len))
15125         {
15126           leid_type = 0;        /* ipv4 */
15127           leid_len = len;
15128         }
15129       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
15130                          &leid6, &len))
15131         {
15132           leid_type = 1;        /* ipv6 */
15133           leid_len = len;
15134         }
15135       else if (unformat (input, "leid %U", unformat_ethernet_address,
15136                          leid_mac))
15137         {
15138           leid_type = 2;        /* mac */
15139         }
15140       else if (unformat (input, "vni %d", &vni))
15141         {
15142           ;
15143         }
15144       else
15145         {
15146           errmsg ("parse error '%U'", format_unformat_error, input);
15147           return -99;
15148         }
15149     }
15150
15151   if ((u8) ~ 0 == reid_type)
15152     {
15153       errmsg ("missing params!");
15154       return -99;
15155     }
15156
15157   if (leid_type != reid_type)
15158     {
15159       errmsg ("remote and local EIDs are of different types!");
15160       return -99;
15161     }
15162
15163   M (ONE_ADD_DEL_ADJACENCY, mp);
15164   mp->is_add = is_add;
15165   mp->vni = htonl (vni);
15166   mp->leid_len = leid_len;
15167   mp->reid_len = reid_len;
15168   mp->eid_type = reid_type;
15169
15170   switch (mp->eid_type)
15171     {
15172     case 0:
15173       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
15174       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
15175       break;
15176     case 1:
15177       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
15178       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
15179       break;
15180     case 2:
15181       clib_memcpy (mp->leid, leid_mac, 6);
15182       clib_memcpy (mp->reid, reid_mac, 6);
15183       break;
15184     default:
15185       errmsg ("unknown EID type %d!", mp->eid_type);
15186       return 0;
15187     }
15188
15189   /* send it... */
15190   S (mp);
15191
15192   /* Wait for a reply... */
15193   W (ret);
15194   return ret;
15195 }
15196
15197 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
15198
15199 uword
15200 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
15201 {
15202   u32 *mode = va_arg (*args, u32 *);
15203
15204   if (unformat (input, "lisp"))
15205     *mode = 0;
15206   else if (unformat (input, "vxlan"))
15207     *mode = 1;
15208   else
15209     return 0;
15210
15211   return 1;
15212 }
15213
15214 static int
15215 api_gpe_get_encap_mode (vat_main_t * vam)
15216 {
15217   vl_api_gpe_get_encap_mode_t *mp;
15218   int ret;
15219
15220   /* Construct the API message */
15221   M (GPE_GET_ENCAP_MODE, mp);
15222
15223   /* send it... */
15224   S (mp);
15225
15226   /* Wait for a reply... */
15227   W (ret);
15228   return ret;
15229 }
15230
15231 static int
15232 api_gpe_set_encap_mode (vat_main_t * vam)
15233 {
15234   unformat_input_t *input = vam->input;
15235   vl_api_gpe_set_encap_mode_t *mp;
15236   int ret;
15237   u32 mode = 0;
15238
15239   /* Parse args required to build the message */
15240   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15241     {
15242       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
15243         ;
15244       else
15245         break;
15246     }
15247
15248   /* Construct the API message */
15249   M (GPE_SET_ENCAP_MODE, mp);
15250
15251   mp->mode = mode;
15252
15253   /* send it... */
15254   S (mp);
15255
15256   /* Wait for a reply... */
15257   W (ret);
15258   return ret;
15259 }
15260
15261 static int
15262 api_lisp_gpe_add_del_iface (vat_main_t * vam)
15263 {
15264   unformat_input_t *input = vam->input;
15265   vl_api_gpe_add_del_iface_t *mp;
15266   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
15267   u32 dp_table = 0, vni = 0;
15268   int ret;
15269
15270   /* Parse args required to build the message */
15271   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15272     {
15273       if (unformat (input, "up"))
15274         {
15275           action_set = 1;
15276           is_add = 1;
15277         }
15278       else if (unformat (input, "down"))
15279         {
15280           action_set = 1;
15281           is_add = 0;
15282         }
15283       else if (unformat (input, "table_id %d", &dp_table))
15284         {
15285           dp_table_set = 1;
15286         }
15287       else if (unformat (input, "bd_id %d", &dp_table))
15288         {
15289           dp_table_set = 1;
15290           is_l2 = 1;
15291         }
15292       else if (unformat (input, "vni %d", &vni))
15293         {
15294           vni_set = 1;
15295         }
15296       else
15297         break;
15298     }
15299
15300   if (action_set == 0)
15301     {
15302       errmsg ("Action not set");
15303       return -99;
15304     }
15305   if (dp_table_set == 0 || vni_set == 0)
15306     {
15307       errmsg ("vni and dp_table must be set");
15308       return -99;
15309     }
15310
15311   /* Construct the API message */
15312   M (GPE_ADD_DEL_IFACE, mp);
15313
15314   mp->is_add = is_add;
15315   mp->dp_table = dp_table;
15316   mp->is_l2 = is_l2;
15317   mp->vni = vni;
15318
15319   /* send it... */
15320   S (mp);
15321
15322   /* Wait for a reply... */
15323   W (ret);
15324   return ret;
15325 }
15326
15327 /**
15328  * Add/del map request itr rlocs from ONE control plane and updates
15329  *
15330  * @param vam vpp API test context
15331  * @return return code
15332  */
15333 static int
15334 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
15335 {
15336   unformat_input_t *input = vam->input;
15337   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
15338   u8 *locator_set_name = 0;
15339   u8 locator_set_name_set = 0;
15340   u8 is_add = 1;
15341   int ret;
15342
15343   /* Parse args required to build the message */
15344   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15345     {
15346       if (unformat (input, "del"))
15347         {
15348           is_add = 0;
15349         }
15350       else if (unformat (input, "%_%v%_", &locator_set_name))
15351         {
15352           locator_set_name_set = 1;
15353         }
15354       else
15355         {
15356           clib_warning ("parse error '%U'", format_unformat_error, input);
15357           return -99;
15358         }
15359     }
15360
15361   if (is_add && !locator_set_name_set)
15362     {
15363       errmsg ("itr-rloc is not set!");
15364       return -99;
15365     }
15366
15367   if (is_add && vec_len (locator_set_name) > 64)
15368     {
15369       errmsg ("itr-rloc locator-set name too long");
15370       vec_free (locator_set_name);
15371       return -99;
15372     }
15373
15374   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
15375   mp->is_add = is_add;
15376   if (is_add)
15377     {
15378       clib_memcpy (mp->locator_set_name, locator_set_name,
15379                    vec_len (locator_set_name));
15380     }
15381   else
15382     {
15383       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
15384     }
15385   vec_free (locator_set_name);
15386
15387   /* send it... */
15388   S (mp);
15389
15390   /* Wait for a reply... */
15391   W (ret);
15392   return ret;
15393 }
15394
15395 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
15396
15397 static int
15398 api_one_locator_dump (vat_main_t * vam)
15399 {
15400   unformat_input_t *input = vam->input;
15401   vl_api_one_locator_dump_t *mp;
15402   vl_api_control_ping_t *mp_ping;
15403   u8 is_index_set = 0, is_name_set = 0;
15404   u8 *ls_name = 0;
15405   u32 ls_index = ~0;
15406   int ret;
15407
15408   /* Parse args required to build the message */
15409   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15410     {
15411       if (unformat (input, "ls_name %_%v%_", &ls_name))
15412         {
15413           is_name_set = 1;
15414         }
15415       else if (unformat (input, "ls_index %d", &ls_index))
15416         {
15417           is_index_set = 1;
15418         }
15419       else
15420         {
15421           errmsg ("parse error '%U'", format_unformat_error, input);
15422           return -99;
15423         }
15424     }
15425
15426   if (!is_index_set && !is_name_set)
15427     {
15428       errmsg ("error: expected one of index or name!");
15429       return -99;
15430     }
15431
15432   if (is_index_set && is_name_set)
15433     {
15434       errmsg ("error: only one param expected!");
15435       return -99;
15436     }
15437
15438   if (vec_len (ls_name) > 62)
15439     {
15440       errmsg ("error: locator set name too long!");
15441       return -99;
15442     }
15443
15444   if (!vam->json_output)
15445     {
15446       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
15447     }
15448
15449   M (ONE_LOCATOR_DUMP, mp);
15450   mp->is_index_set = is_index_set;
15451
15452   if (is_index_set)
15453     mp->ls_index = clib_host_to_net_u32 (ls_index);
15454   else
15455     {
15456       vec_add1 (ls_name, 0);
15457       strncpy ((char *) mp->ls_name, (char *) ls_name,
15458                sizeof (mp->ls_name) - 1);
15459     }
15460
15461   /* send it... */
15462   S (mp);
15463
15464   /* Use a control ping for synchronization */
15465   M (CONTROL_PING, mp_ping);
15466   S (mp_ping);
15467
15468   /* Wait for a reply... */
15469   W (ret);
15470   return ret;
15471 }
15472
15473 #define api_lisp_locator_dump api_one_locator_dump
15474
15475 static int
15476 api_one_locator_set_dump (vat_main_t * vam)
15477 {
15478   vl_api_one_locator_set_dump_t *mp;
15479   vl_api_control_ping_t *mp_ping;
15480   unformat_input_t *input = vam->input;
15481   u8 filter = 0;
15482   int ret;
15483
15484   /* Parse args required to build the message */
15485   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15486     {
15487       if (unformat (input, "local"))
15488         {
15489           filter = 1;
15490         }
15491       else if (unformat (input, "remote"))
15492         {
15493           filter = 2;
15494         }
15495       else
15496         {
15497           errmsg ("parse error '%U'", format_unformat_error, input);
15498           return -99;
15499         }
15500     }
15501
15502   if (!vam->json_output)
15503     {
15504       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
15505     }
15506
15507   M (ONE_LOCATOR_SET_DUMP, mp);
15508
15509   mp->filter = filter;
15510
15511   /* send it... */
15512   S (mp);
15513
15514   /* Use a control ping for synchronization */
15515   M (CONTROL_PING, mp_ping);
15516   S (mp_ping);
15517
15518   /* Wait for a reply... */
15519   W (ret);
15520   return ret;
15521 }
15522
15523 #define api_lisp_locator_set_dump api_one_locator_set_dump
15524
15525 static int
15526 api_one_eid_table_map_dump (vat_main_t * vam)
15527 {
15528   u8 is_l2 = 0;
15529   u8 mode_set = 0;
15530   unformat_input_t *input = vam->input;
15531   vl_api_one_eid_table_map_dump_t *mp;
15532   vl_api_control_ping_t *mp_ping;
15533   int ret;
15534
15535   /* Parse args required to build the message */
15536   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15537     {
15538       if (unformat (input, "l2"))
15539         {
15540           is_l2 = 1;
15541           mode_set = 1;
15542         }
15543       else if (unformat (input, "l3"))
15544         {
15545           is_l2 = 0;
15546           mode_set = 1;
15547         }
15548       else
15549         {
15550           errmsg ("parse error '%U'", format_unformat_error, input);
15551           return -99;
15552         }
15553     }
15554
15555   if (!mode_set)
15556     {
15557       errmsg ("expected one of 'l2' or 'l3' parameter!");
15558       return -99;
15559     }
15560
15561   if (!vam->json_output)
15562     {
15563       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
15564     }
15565
15566   M (ONE_EID_TABLE_MAP_DUMP, mp);
15567   mp->is_l2 = is_l2;
15568
15569   /* send it... */
15570   S (mp);
15571
15572   /* Use a control ping for synchronization */
15573   M (CONTROL_PING, mp_ping);
15574   S (mp_ping);
15575
15576   /* Wait for a reply... */
15577   W (ret);
15578   return ret;
15579 }
15580
15581 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
15582
15583 static int
15584 api_one_eid_table_vni_dump (vat_main_t * vam)
15585 {
15586   vl_api_one_eid_table_vni_dump_t *mp;
15587   vl_api_control_ping_t *mp_ping;
15588   int ret;
15589
15590   if (!vam->json_output)
15591     {
15592       print (vam->ofp, "VNI");
15593     }
15594
15595   M (ONE_EID_TABLE_VNI_DUMP, mp);
15596
15597   /* send it... */
15598   S (mp);
15599
15600   /* Use a control ping for synchronization */
15601   M (CONTROL_PING, mp_ping);
15602   S (mp_ping);
15603
15604   /* Wait for a reply... */
15605   W (ret);
15606   return ret;
15607 }
15608
15609 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
15610
15611 static int
15612 api_one_eid_table_dump (vat_main_t * vam)
15613 {
15614   unformat_input_t *i = vam->input;
15615   vl_api_one_eid_table_dump_t *mp;
15616   vl_api_control_ping_t *mp_ping;
15617   struct in_addr ip4;
15618   struct in6_addr ip6;
15619   u8 mac[6];
15620   u8 eid_type = ~0, eid_set = 0;
15621   u32 prefix_length = ~0, t, vni = 0;
15622   u8 filter = 0;
15623   int ret;
15624
15625   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15626     {
15627       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
15628         {
15629           eid_set = 1;
15630           eid_type = 0;
15631           prefix_length = t;
15632         }
15633       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
15634         {
15635           eid_set = 1;
15636           eid_type = 1;
15637           prefix_length = t;
15638         }
15639       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
15640         {
15641           eid_set = 1;
15642           eid_type = 2;
15643         }
15644       else if (unformat (i, "vni %d", &t))
15645         {
15646           vni = t;
15647         }
15648       else if (unformat (i, "local"))
15649         {
15650           filter = 1;
15651         }
15652       else if (unformat (i, "remote"))
15653         {
15654           filter = 2;
15655         }
15656       else
15657         {
15658           errmsg ("parse error '%U'", format_unformat_error, i);
15659           return -99;
15660         }
15661     }
15662
15663   if (!vam->json_output)
15664     {
15665       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
15666              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
15667     }
15668
15669   M (ONE_EID_TABLE_DUMP, mp);
15670
15671   mp->filter = filter;
15672   if (eid_set)
15673     {
15674       mp->eid_set = 1;
15675       mp->vni = htonl (vni);
15676       mp->eid_type = eid_type;
15677       switch (eid_type)
15678         {
15679         case 0:
15680           mp->prefix_length = prefix_length;
15681           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
15682           break;
15683         case 1:
15684           mp->prefix_length = prefix_length;
15685           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
15686           break;
15687         case 2:
15688           clib_memcpy (mp->eid, mac, sizeof (mac));
15689           break;
15690         default:
15691           errmsg ("unknown EID type %d!", eid_type);
15692           return -99;
15693         }
15694     }
15695
15696   /* send it... */
15697   S (mp);
15698
15699   /* Use a control ping for synchronization */
15700   M (CONTROL_PING, mp_ping);
15701   S (mp_ping);
15702
15703   /* Wait for a reply... */
15704   W (ret);
15705   return ret;
15706 }
15707
15708 #define api_lisp_eid_table_dump api_one_eid_table_dump
15709
15710 static int
15711 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
15712 {
15713   unformat_input_t *i = vam->input;
15714   vl_api_gpe_fwd_entries_get_t *mp;
15715   u8 vni_set = 0;
15716   u32 vni = ~0;
15717   int ret;
15718
15719   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15720     {
15721       if (unformat (i, "vni %d", &vni))
15722         {
15723           vni_set = 1;
15724         }
15725       else
15726         {
15727           errmsg ("parse error '%U'", format_unformat_error, i);
15728           return -99;
15729         }
15730     }
15731
15732   if (!vni_set)
15733     {
15734       errmsg ("vni not set!");
15735       return -99;
15736     }
15737
15738   if (!vam->json_output)
15739     {
15740       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
15741              "leid", "reid");
15742     }
15743
15744   M (GPE_FWD_ENTRIES_GET, mp);
15745   mp->vni = clib_host_to_net_u32 (vni);
15746
15747   /* send it... */
15748   S (mp);
15749
15750   /* Wait for a reply... */
15751   W (ret);
15752   return ret;
15753 }
15754
15755 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
15756 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
15757 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
15758 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
15759
15760 static int
15761 api_one_adjacencies_get (vat_main_t * vam)
15762 {
15763   unformat_input_t *i = vam->input;
15764   vl_api_one_adjacencies_get_t *mp;
15765   u8 vni_set = 0;
15766   u32 vni = ~0;
15767   int ret;
15768
15769   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15770     {
15771       if (unformat (i, "vni %d", &vni))
15772         {
15773           vni_set = 1;
15774         }
15775       else
15776         {
15777           errmsg ("parse error '%U'", format_unformat_error, i);
15778           return -99;
15779         }
15780     }
15781
15782   if (!vni_set)
15783     {
15784       errmsg ("vni not set!");
15785       return -99;
15786     }
15787
15788   if (!vam->json_output)
15789     {
15790       print (vam->ofp, "%s %40s", "leid", "reid");
15791     }
15792
15793   M (ONE_ADJACENCIES_GET, mp);
15794   mp->vni = clib_host_to_net_u32 (vni);
15795
15796   /* send it... */
15797   S (mp);
15798
15799   /* Wait for a reply... */
15800   W (ret);
15801   return ret;
15802 }
15803
15804 #define api_lisp_adjacencies_get api_one_adjacencies_get
15805
15806 static int
15807 api_one_map_server_dump (vat_main_t * vam)
15808 {
15809   vl_api_one_map_server_dump_t *mp;
15810   vl_api_control_ping_t *mp_ping;
15811   int ret;
15812
15813   if (!vam->json_output)
15814     {
15815       print (vam->ofp, "%=20s", "Map server");
15816     }
15817
15818   M (ONE_MAP_SERVER_DUMP, mp);
15819   /* send it... */
15820   S (mp);
15821
15822   /* Use a control ping for synchronization */
15823   M (CONTROL_PING, mp_ping);
15824   S (mp_ping);
15825
15826   /* Wait for a reply... */
15827   W (ret);
15828   return ret;
15829 }
15830
15831 #define api_lisp_map_server_dump api_one_map_server_dump
15832
15833 static int
15834 api_one_map_resolver_dump (vat_main_t * vam)
15835 {
15836   vl_api_one_map_resolver_dump_t *mp;
15837   vl_api_control_ping_t *mp_ping;
15838   int ret;
15839
15840   if (!vam->json_output)
15841     {
15842       print (vam->ofp, "%=20s", "Map resolver");
15843     }
15844
15845   M (ONE_MAP_RESOLVER_DUMP, mp);
15846   /* send it... */
15847   S (mp);
15848
15849   /* Use a control ping for synchronization */
15850   M (CONTROL_PING, mp_ping);
15851   S (mp_ping);
15852
15853   /* Wait for a reply... */
15854   W (ret);
15855   return ret;
15856 }
15857
15858 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
15859
15860 static int
15861 api_one_stats_flush (vat_main_t * vam)
15862 {
15863   vl_api_one_stats_flush_t *mp;
15864   int ret = 0;
15865
15866   M (ONE_STATS_FLUSH, mp);
15867   S (mp);
15868   W (ret);
15869   return ret;
15870 }
15871
15872 static int
15873 api_one_stats_dump (vat_main_t * vam)
15874 {
15875   vl_api_one_stats_dump_t *mp;
15876   vl_api_control_ping_t *mp_ping;
15877   int ret;
15878
15879   M (ONE_STATS_DUMP, mp);
15880   /* send it... */
15881   S (mp);
15882
15883   /* Use a control ping for synchronization */
15884   M (CONTROL_PING, mp_ping);
15885   S (mp_ping);
15886
15887   /* Wait for a reply... */
15888   W (ret);
15889   return ret;
15890 }
15891
15892 static int
15893 api_show_one_status (vat_main_t * vam)
15894 {
15895   vl_api_show_one_status_t *mp;
15896   int ret;
15897
15898   if (!vam->json_output)
15899     {
15900       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
15901     }
15902
15903   M (SHOW_ONE_STATUS, mp);
15904   /* send it... */
15905   S (mp);
15906   /* Wait for a reply... */
15907   W (ret);
15908   return ret;
15909 }
15910
15911 #define api_show_lisp_status api_show_one_status
15912
15913 static int
15914 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
15915 {
15916   vl_api_gpe_fwd_entry_path_dump_t *mp;
15917   vl_api_control_ping_t *mp_ping;
15918   unformat_input_t *i = vam->input;
15919   u32 fwd_entry_index = ~0;
15920   int ret;
15921
15922   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15923     {
15924       if (unformat (i, "index %d", &fwd_entry_index))
15925         ;
15926       else
15927         break;
15928     }
15929
15930   if (~0 == fwd_entry_index)
15931     {
15932       errmsg ("no index specified!");
15933       return -99;
15934     }
15935
15936   if (!vam->json_output)
15937     {
15938       print (vam->ofp, "first line");
15939     }
15940
15941   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
15942
15943   /* send it... */
15944   S (mp);
15945   /* Use a control ping for synchronization */
15946   M (CONTROL_PING, mp_ping);
15947   S (mp_ping);
15948
15949   /* Wait for a reply... */
15950   W (ret);
15951   return ret;
15952 }
15953
15954 static int
15955 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
15956 {
15957   vl_api_one_get_map_request_itr_rlocs_t *mp;
15958   int ret;
15959
15960   if (!vam->json_output)
15961     {
15962       print (vam->ofp, "%=20s", "itr-rlocs:");
15963     }
15964
15965   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
15966   /* send it... */
15967   S (mp);
15968   /* Wait for a reply... */
15969   W (ret);
15970   return ret;
15971 }
15972
15973 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
15974
15975 static int
15976 api_af_packet_create (vat_main_t * vam)
15977 {
15978   unformat_input_t *i = vam->input;
15979   vl_api_af_packet_create_t *mp;
15980   u8 *host_if_name = 0;
15981   u8 hw_addr[6];
15982   u8 random_hw_addr = 1;
15983   int ret;
15984
15985   memset (hw_addr, 0, sizeof (hw_addr));
15986
15987   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15988     {
15989       if (unformat (i, "name %s", &host_if_name))
15990         vec_add1 (host_if_name, 0);
15991       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
15992         random_hw_addr = 0;
15993       else
15994         break;
15995     }
15996
15997   if (!vec_len (host_if_name))
15998     {
15999       errmsg ("host-interface name must be specified");
16000       return -99;
16001     }
16002
16003   if (vec_len (host_if_name) > 64)
16004     {
16005       errmsg ("host-interface name too long");
16006       return -99;
16007     }
16008
16009   M (AF_PACKET_CREATE, mp);
16010
16011   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
16012   clib_memcpy (mp->hw_addr, hw_addr, 6);
16013   mp->use_random_hw_addr = random_hw_addr;
16014   vec_free (host_if_name);
16015
16016   S (mp);
16017
16018   /* *INDENT-OFF* */
16019   W2 (ret,
16020       ({
16021         if (ret == 0)
16022           fprintf (vam->ofp ? vam->ofp : stderr,
16023                    " new sw_if_index = %d\n", vam->sw_if_index);
16024       }));
16025   /* *INDENT-ON* */
16026   return ret;
16027 }
16028
16029 static int
16030 api_af_packet_delete (vat_main_t * vam)
16031 {
16032   unformat_input_t *i = vam->input;
16033   vl_api_af_packet_delete_t *mp;
16034   u8 *host_if_name = 0;
16035   int ret;
16036
16037   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16038     {
16039       if (unformat (i, "name %s", &host_if_name))
16040         vec_add1 (host_if_name, 0);
16041       else
16042         break;
16043     }
16044
16045   if (!vec_len (host_if_name))
16046     {
16047       errmsg ("host-interface name must be specified");
16048       return -99;
16049     }
16050
16051   if (vec_len (host_if_name) > 64)
16052     {
16053       errmsg ("host-interface name too long");
16054       return -99;
16055     }
16056
16057   M (AF_PACKET_DELETE, mp);
16058
16059   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
16060   vec_free (host_if_name);
16061
16062   S (mp);
16063   W (ret);
16064   return ret;
16065 }
16066
16067 static int
16068 api_policer_add_del (vat_main_t * vam)
16069 {
16070   unformat_input_t *i = vam->input;
16071   vl_api_policer_add_del_t *mp;
16072   u8 is_add = 1;
16073   u8 *name = 0;
16074   u32 cir = 0;
16075   u32 eir = 0;
16076   u64 cb = 0;
16077   u64 eb = 0;
16078   u8 rate_type = 0;
16079   u8 round_type = 0;
16080   u8 type = 0;
16081   u8 color_aware = 0;
16082   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
16083   int ret;
16084
16085   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
16086   conform_action.dscp = 0;
16087   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
16088   exceed_action.dscp = 0;
16089   violate_action.action_type = SSE2_QOS_ACTION_DROP;
16090   violate_action.dscp = 0;
16091
16092   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16093     {
16094       if (unformat (i, "del"))
16095         is_add = 0;
16096       else if (unformat (i, "name %s", &name))
16097         vec_add1 (name, 0);
16098       else if (unformat (i, "cir %u", &cir))
16099         ;
16100       else if (unformat (i, "eir %u", &eir))
16101         ;
16102       else if (unformat (i, "cb %u", &cb))
16103         ;
16104       else if (unformat (i, "eb %u", &eb))
16105         ;
16106       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
16107                          &rate_type))
16108         ;
16109       else if (unformat (i, "round_type %U", unformat_policer_round_type,
16110                          &round_type))
16111         ;
16112       else if (unformat (i, "type %U", unformat_policer_type, &type))
16113         ;
16114       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
16115                          &conform_action))
16116         ;
16117       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
16118                          &exceed_action))
16119         ;
16120       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
16121                          &violate_action))
16122         ;
16123       else if (unformat (i, "color-aware"))
16124         color_aware = 1;
16125       else
16126         break;
16127     }
16128
16129   if (!vec_len (name))
16130     {
16131       errmsg ("policer name must be specified");
16132       return -99;
16133     }
16134
16135   if (vec_len (name) > 64)
16136     {
16137       errmsg ("policer name too long");
16138       return -99;
16139     }
16140
16141   M (POLICER_ADD_DEL, mp);
16142
16143   clib_memcpy (mp->name, name, vec_len (name));
16144   vec_free (name);
16145   mp->is_add = is_add;
16146   mp->cir = cir;
16147   mp->eir = eir;
16148   mp->cb = cb;
16149   mp->eb = eb;
16150   mp->rate_type = rate_type;
16151   mp->round_type = round_type;
16152   mp->type = type;
16153   mp->conform_action_type = conform_action.action_type;
16154   mp->conform_dscp = conform_action.dscp;
16155   mp->exceed_action_type = exceed_action.action_type;
16156   mp->exceed_dscp = exceed_action.dscp;
16157   mp->violate_action_type = violate_action.action_type;
16158   mp->violate_dscp = violate_action.dscp;
16159   mp->color_aware = color_aware;
16160
16161   S (mp);
16162   W (ret);
16163   return ret;
16164 }
16165
16166 static int
16167 api_policer_dump (vat_main_t * vam)
16168 {
16169   unformat_input_t *i = vam->input;
16170   vl_api_policer_dump_t *mp;
16171   vl_api_control_ping_t *mp_ping;
16172   u8 *match_name = 0;
16173   u8 match_name_valid = 0;
16174   int ret;
16175
16176   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16177     {
16178       if (unformat (i, "name %s", &match_name))
16179         {
16180           vec_add1 (match_name, 0);
16181           match_name_valid = 1;
16182         }
16183       else
16184         break;
16185     }
16186
16187   M (POLICER_DUMP, mp);
16188   mp->match_name_valid = match_name_valid;
16189   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
16190   vec_free (match_name);
16191   /* send it... */
16192   S (mp);
16193
16194   /* Use a control ping for synchronization */
16195   M (CONTROL_PING, mp_ping);
16196   S (mp_ping);
16197
16198   /* Wait for a reply... */
16199   W (ret);
16200   return ret;
16201 }
16202
16203 static int
16204 api_policer_classify_set_interface (vat_main_t * vam)
16205 {
16206   unformat_input_t *i = vam->input;
16207   vl_api_policer_classify_set_interface_t *mp;
16208   u32 sw_if_index;
16209   int sw_if_index_set;
16210   u32 ip4_table_index = ~0;
16211   u32 ip6_table_index = ~0;
16212   u32 l2_table_index = ~0;
16213   u8 is_add = 1;
16214   int ret;
16215
16216   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16217     {
16218       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16219         sw_if_index_set = 1;
16220       else if (unformat (i, "sw_if_index %d", &sw_if_index))
16221         sw_if_index_set = 1;
16222       else if (unformat (i, "del"))
16223         is_add = 0;
16224       else if (unformat (i, "ip4-table %d", &ip4_table_index))
16225         ;
16226       else if (unformat (i, "ip6-table %d", &ip6_table_index))
16227         ;
16228       else if (unformat (i, "l2-table %d", &l2_table_index))
16229         ;
16230       else
16231         {
16232           clib_warning ("parse error '%U'", format_unformat_error, i);
16233           return -99;
16234         }
16235     }
16236
16237   if (sw_if_index_set == 0)
16238     {
16239       errmsg ("missing interface name or sw_if_index");
16240       return -99;
16241     }
16242
16243   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
16244
16245   mp->sw_if_index = ntohl (sw_if_index);
16246   mp->ip4_table_index = ntohl (ip4_table_index);
16247   mp->ip6_table_index = ntohl (ip6_table_index);
16248   mp->l2_table_index = ntohl (l2_table_index);
16249   mp->is_add = is_add;
16250
16251   S (mp);
16252   W (ret);
16253   return ret;
16254 }
16255
16256 static int
16257 api_policer_classify_dump (vat_main_t * vam)
16258 {
16259   unformat_input_t *i = vam->input;
16260   vl_api_policer_classify_dump_t *mp;
16261   vl_api_control_ping_t *mp_ping;
16262   u8 type = POLICER_CLASSIFY_N_TABLES;
16263   int ret;
16264
16265   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
16266     ;
16267   else
16268     {
16269       errmsg ("classify table type must be specified");
16270       return -99;
16271     }
16272
16273   if (!vam->json_output)
16274     {
16275       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
16276     }
16277
16278   M (POLICER_CLASSIFY_DUMP, mp);
16279   mp->type = type;
16280   /* send it... */
16281   S (mp);
16282
16283   /* Use a control ping for synchronization */
16284   M (CONTROL_PING, mp_ping);
16285   S (mp_ping);
16286
16287   /* Wait for a reply... */
16288   W (ret);
16289   return ret;
16290 }
16291
16292 static int
16293 api_netmap_create (vat_main_t * vam)
16294 {
16295   unformat_input_t *i = vam->input;
16296   vl_api_netmap_create_t *mp;
16297   u8 *if_name = 0;
16298   u8 hw_addr[6];
16299   u8 random_hw_addr = 1;
16300   u8 is_pipe = 0;
16301   u8 is_master = 0;
16302   int ret;
16303
16304   memset (hw_addr, 0, sizeof (hw_addr));
16305
16306   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16307     {
16308       if (unformat (i, "name %s", &if_name))
16309         vec_add1 (if_name, 0);
16310       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
16311         random_hw_addr = 0;
16312       else if (unformat (i, "pipe"))
16313         is_pipe = 1;
16314       else if (unformat (i, "master"))
16315         is_master = 1;
16316       else if (unformat (i, "slave"))
16317         is_master = 0;
16318       else
16319         break;
16320     }
16321
16322   if (!vec_len (if_name))
16323     {
16324       errmsg ("interface name must be specified");
16325       return -99;
16326     }
16327
16328   if (vec_len (if_name) > 64)
16329     {
16330       errmsg ("interface name too long");
16331       return -99;
16332     }
16333
16334   M (NETMAP_CREATE, mp);
16335
16336   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
16337   clib_memcpy (mp->hw_addr, hw_addr, 6);
16338   mp->use_random_hw_addr = random_hw_addr;
16339   mp->is_pipe = is_pipe;
16340   mp->is_master = is_master;
16341   vec_free (if_name);
16342
16343   S (mp);
16344   W (ret);
16345   return ret;
16346 }
16347
16348 static int
16349 api_netmap_delete (vat_main_t * vam)
16350 {
16351   unformat_input_t *i = vam->input;
16352   vl_api_netmap_delete_t *mp;
16353   u8 *if_name = 0;
16354   int ret;
16355
16356   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16357     {
16358       if (unformat (i, "name %s", &if_name))
16359         vec_add1 (if_name, 0);
16360       else
16361         break;
16362     }
16363
16364   if (!vec_len (if_name))
16365     {
16366       errmsg ("interface name must be specified");
16367       return -99;
16368     }
16369
16370   if (vec_len (if_name) > 64)
16371     {
16372       errmsg ("interface name too long");
16373       return -99;
16374     }
16375
16376   M (NETMAP_DELETE, mp);
16377
16378   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
16379   vec_free (if_name);
16380
16381   S (mp);
16382   W (ret);
16383   return ret;
16384 }
16385
16386 static void
16387 vl_api_mpls_fib_path_print (vat_main_t * vam, vl_api_fib_path2_t * fp)
16388 {
16389   if (fp->afi == IP46_TYPE_IP6)
16390     print (vam->ofp,
16391            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16392            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16393            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16394            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16395            format_ip6_address, fp->next_hop);
16396   else if (fp->afi == IP46_TYPE_IP4)
16397     print (vam->ofp,
16398            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16399            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16400            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16401            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16402            format_ip4_address, fp->next_hop);
16403 }
16404
16405 static void
16406 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
16407                                  vl_api_fib_path2_t * fp)
16408 {
16409   struct in_addr ip4;
16410   struct in6_addr ip6;
16411
16412   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
16413   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
16414   vat_json_object_add_uint (node, "is_local", fp->is_local);
16415   vat_json_object_add_uint (node, "is_drop", fp->is_drop);
16416   vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
16417   vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
16418   vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
16419   if (fp->afi == IP46_TYPE_IP4)
16420     {
16421       clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
16422       vat_json_object_add_ip4 (node, "next_hop", ip4);
16423     }
16424   else if (fp->afi == IP46_TYPE_IP6)
16425     {
16426       clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
16427       vat_json_object_add_ip6 (node, "next_hop", ip6);
16428     }
16429 }
16430
16431 static void
16432 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
16433 {
16434   vat_main_t *vam = &vat_main;
16435   int count = ntohl (mp->mt_count);
16436   vl_api_fib_path2_t *fp;
16437   i32 i;
16438
16439   print (vam->ofp, "[%d]: sw_if_index %d via:",
16440          ntohl (mp->mt_tunnel_index), ntohl (mp->mt_sw_if_index));
16441   fp = mp->mt_paths;
16442   for (i = 0; i < count; i++)
16443     {
16444       vl_api_mpls_fib_path_print (vam, fp);
16445       fp++;
16446     }
16447
16448   print (vam->ofp, "");
16449 }
16450
16451 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
16452 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
16453
16454 static void
16455 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
16456 {
16457   vat_main_t *vam = &vat_main;
16458   vat_json_node_t *node = NULL;
16459   int count = ntohl (mp->mt_count);
16460   vl_api_fib_path2_t *fp;
16461   i32 i;
16462
16463   if (VAT_JSON_ARRAY != vam->json_tree.type)
16464     {
16465       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16466       vat_json_init_array (&vam->json_tree);
16467     }
16468   node = vat_json_array_add (&vam->json_tree);
16469
16470   vat_json_init_object (node);
16471   vat_json_object_add_uint (node, "tunnel_index",
16472                             ntohl (mp->mt_tunnel_index));
16473   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->mt_sw_if_index));
16474
16475   vat_json_object_add_uint (node, "l2_only", mp->mt_l2_only);
16476
16477   fp = mp->mt_paths;
16478   for (i = 0; i < count; i++)
16479     {
16480       vl_api_mpls_fib_path_json_print (node, fp);
16481       fp++;
16482     }
16483 }
16484
16485 static int
16486 api_mpls_tunnel_dump (vat_main_t * vam)
16487 {
16488   vl_api_mpls_tunnel_dump_t *mp;
16489   vl_api_control_ping_t *mp_ping;
16490   i32 index = -1;
16491   int ret;
16492
16493   /* Parse args required to build the message */
16494   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
16495     {
16496       if (!unformat (vam->input, "tunnel_index %d", &index))
16497         {
16498           index = -1;
16499           break;
16500         }
16501     }
16502
16503   print (vam->ofp, "  tunnel_index %d", index);
16504
16505   M (MPLS_TUNNEL_DUMP, mp);
16506   mp->tunnel_index = htonl (index);
16507   S (mp);
16508
16509   /* Use a control ping for synchronization */
16510   M (CONTROL_PING, mp_ping);
16511   S (mp_ping);
16512
16513   W (ret);
16514   return ret;
16515 }
16516
16517 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
16518 #define vl_api_mpls_fib_details_t_print vl_noop_handler
16519
16520
16521 static void
16522 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
16523 {
16524   vat_main_t *vam = &vat_main;
16525   int count = ntohl (mp->count);
16526   vl_api_fib_path2_t *fp;
16527   int i;
16528
16529   print (vam->ofp,
16530          "table-id %d, label %u, ess_bit %u",
16531          ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
16532   fp = mp->path;
16533   for (i = 0; i < count; i++)
16534     {
16535       vl_api_mpls_fib_path_print (vam, fp);
16536       fp++;
16537     }
16538 }
16539
16540 static void vl_api_mpls_fib_details_t_handler_json
16541   (vl_api_mpls_fib_details_t * mp)
16542 {
16543   vat_main_t *vam = &vat_main;
16544   int count = ntohl (mp->count);
16545   vat_json_node_t *node = NULL;
16546   vl_api_fib_path2_t *fp;
16547   int i;
16548
16549   if (VAT_JSON_ARRAY != vam->json_tree.type)
16550     {
16551       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16552       vat_json_init_array (&vam->json_tree);
16553     }
16554   node = vat_json_array_add (&vam->json_tree);
16555
16556   vat_json_init_object (node);
16557   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
16558   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
16559   vat_json_object_add_uint (node, "label", ntohl (mp->label));
16560   vat_json_object_add_uint (node, "path_count", count);
16561   fp = mp->path;
16562   for (i = 0; i < count; i++)
16563     {
16564       vl_api_mpls_fib_path_json_print (node, fp);
16565       fp++;
16566     }
16567 }
16568
16569 static int
16570 api_mpls_fib_dump (vat_main_t * vam)
16571 {
16572   vl_api_mpls_fib_dump_t *mp;
16573   vl_api_control_ping_t *mp_ping;
16574   int ret;
16575
16576   M (MPLS_FIB_DUMP, mp);
16577   S (mp);
16578
16579   /* Use a control ping for synchronization */
16580   M (CONTROL_PING, mp_ping);
16581   S (mp_ping);
16582
16583   W (ret);
16584   return ret;
16585 }
16586
16587 #define vl_api_ip_fib_details_t_endian vl_noop_handler
16588 #define vl_api_ip_fib_details_t_print vl_noop_handler
16589
16590 static void
16591 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
16592 {
16593   vat_main_t *vam = &vat_main;
16594   int count = ntohl (mp->count);
16595   vl_api_fib_path_t *fp;
16596   int i;
16597
16598   print (vam->ofp,
16599          "table-id %d, prefix %U/%d",
16600          ntohl (mp->table_id), format_ip4_address, mp->address,
16601          mp->address_length);
16602   fp = mp->path;
16603   for (i = 0; i < count; i++)
16604     {
16605       if (fp->afi == IP46_TYPE_IP6)
16606         print (vam->ofp,
16607                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16608                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16609                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16610                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16611                format_ip6_address, fp->next_hop);
16612       else if (fp->afi == IP46_TYPE_IP4)
16613         print (vam->ofp,
16614                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16615                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16616                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16617                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16618                format_ip4_address, fp->next_hop);
16619       fp++;
16620     }
16621 }
16622
16623 static void vl_api_ip_fib_details_t_handler_json
16624   (vl_api_ip_fib_details_t * mp)
16625 {
16626   vat_main_t *vam = &vat_main;
16627   int count = ntohl (mp->count);
16628   vat_json_node_t *node = NULL;
16629   struct in_addr ip4;
16630   struct in6_addr ip6;
16631   vl_api_fib_path_t *fp;
16632   int i;
16633
16634   if (VAT_JSON_ARRAY != vam->json_tree.type)
16635     {
16636       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16637       vat_json_init_array (&vam->json_tree);
16638     }
16639   node = vat_json_array_add (&vam->json_tree);
16640
16641   vat_json_init_object (node);
16642   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
16643   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
16644   vat_json_object_add_ip4 (node, "prefix", ip4);
16645   vat_json_object_add_uint (node, "mask_length", mp->address_length);
16646   vat_json_object_add_uint (node, "path_count", count);
16647   fp = mp->path;
16648   for (i = 0; i < count; i++)
16649     {
16650       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
16651       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
16652       vat_json_object_add_uint (node, "is_local", fp->is_local);
16653       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
16654       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
16655       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
16656       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
16657       if (fp->afi == IP46_TYPE_IP4)
16658         {
16659           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
16660           vat_json_object_add_ip4 (node, "next_hop", ip4);
16661         }
16662       else if (fp->afi == IP46_TYPE_IP6)
16663         {
16664           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
16665           vat_json_object_add_ip6 (node, "next_hop", ip6);
16666         }
16667     }
16668 }
16669
16670 static int
16671 api_ip_fib_dump (vat_main_t * vam)
16672 {
16673   vl_api_ip_fib_dump_t *mp;
16674   vl_api_control_ping_t *mp_ping;
16675   int ret;
16676
16677   M (IP_FIB_DUMP, mp);
16678   S (mp);
16679
16680   /* Use a control ping for synchronization */
16681   M (CONTROL_PING, mp_ping);
16682   S (mp_ping);
16683
16684   W (ret);
16685   return ret;
16686 }
16687
16688 static int
16689 api_ip_mfib_dump (vat_main_t * vam)
16690 {
16691   vl_api_ip_mfib_dump_t *mp;
16692   vl_api_control_ping_t *mp_ping;
16693   int ret;
16694
16695   M (IP_MFIB_DUMP, mp);
16696   S (mp);
16697
16698   /* Use a control ping for synchronization */
16699   M (CONTROL_PING, mp_ping);
16700   S (mp_ping);
16701
16702   W (ret);
16703   return ret;
16704 }
16705
16706 static void vl_api_ip_neighbor_details_t_handler
16707   (vl_api_ip_neighbor_details_t * mp)
16708 {
16709   vat_main_t *vam = &vat_main;
16710
16711   print (vam->ofp, "%c %U %U",
16712          (mp->is_static) ? 'S' : 'D',
16713          format_ethernet_address, &mp->mac_address,
16714          (mp->is_ipv6) ? format_ip6_address : format_ip4_address,
16715          &mp->ip_address);
16716 }
16717
16718 static void vl_api_ip_neighbor_details_t_handler_json
16719   (vl_api_ip_neighbor_details_t * mp)
16720 {
16721
16722   vat_main_t *vam = &vat_main;
16723   vat_json_node_t *node;
16724   struct in_addr ip4;
16725   struct in6_addr ip6;
16726
16727   if (VAT_JSON_ARRAY != vam->json_tree.type)
16728     {
16729       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16730       vat_json_init_array (&vam->json_tree);
16731     }
16732   node = vat_json_array_add (&vam->json_tree);
16733
16734   vat_json_init_object (node);
16735   vat_json_object_add_string_copy (node, "flag",
16736                                    (mp->is_static) ? (u8 *) "static" : (u8 *)
16737                                    "dynamic");
16738
16739   vat_json_object_add_string_copy (node, "link_layer",
16740                                    format (0, "%U", format_ethernet_address,
16741                                            &mp->mac_address));
16742
16743   if (mp->is_ipv6)
16744     {
16745       clib_memcpy (&ip6, &mp->ip_address, sizeof (ip6));
16746       vat_json_object_add_ip6 (node, "ip_address", ip6);
16747     }
16748   else
16749     {
16750       clib_memcpy (&ip4, &mp->ip_address, sizeof (ip4));
16751       vat_json_object_add_ip4 (node, "ip_address", ip4);
16752     }
16753 }
16754
16755 static int
16756 api_ip_neighbor_dump (vat_main_t * vam)
16757 {
16758   unformat_input_t *i = vam->input;
16759   vl_api_ip_neighbor_dump_t *mp;
16760   vl_api_control_ping_t *mp_ping;
16761   u8 is_ipv6 = 0;
16762   u32 sw_if_index = ~0;
16763   int ret;
16764
16765   /* Parse args required to build the message */
16766   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16767     {
16768       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16769         ;
16770       else if (unformat (i, "sw_if_index %d", &sw_if_index))
16771         ;
16772       else if (unformat (i, "ip6"))
16773         is_ipv6 = 1;
16774       else
16775         break;
16776     }
16777
16778   if (sw_if_index == ~0)
16779     {
16780       errmsg ("missing interface name or sw_if_index");
16781       return -99;
16782     }
16783
16784   M (IP_NEIGHBOR_DUMP, mp);
16785   mp->is_ipv6 = (u8) is_ipv6;
16786   mp->sw_if_index = ntohl (sw_if_index);
16787   S (mp);
16788
16789   /* Use a control ping for synchronization */
16790   M (CONTROL_PING, mp_ping);
16791   S (mp_ping);
16792
16793   W (ret);
16794   return ret;
16795 }
16796
16797 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
16798 #define vl_api_ip6_fib_details_t_print vl_noop_handler
16799
16800 static void
16801 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
16802 {
16803   vat_main_t *vam = &vat_main;
16804   int count = ntohl (mp->count);
16805   vl_api_fib_path_t *fp;
16806   int i;
16807
16808   print (vam->ofp,
16809          "table-id %d, prefix %U/%d",
16810          ntohl (mp->table_id), format_ip6_address, mp->address,
16811          mp->address_length);
16812   fp = mp->path;
16813   for (i = 0; i < count; i++)
16814     {
16815       if (fp->afi == IP46_TYPE_IP6)
16816         print (vam->ofp,
16817                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16818                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16819                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16820                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16821                format_ip6_address, fp->next_hop);
16822       else if (fp->afi == IP46_TYPE_IP4)
16823         print (vam->ofp,
16824                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16825                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16826                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16827                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16828                format_ip4_address, fp->next_hop);
16829       fp++;
16830     }
16831 }
16832
16833 static void vl_api_ip6_fib_details_t_handler_json
16834   (vl_api_ip6_fib_details_t * mp)
16835 {
16836   vat_main_t *vam = &vat_main;
16837   int count = ntohl (mp->count);
16838   vat_json_node_t *node = NULL;
16839   struct in_addr ip4;
16840   struct in6_addr ip6;
16841   vl_api_fib_path_t *fp;
16842   int i;
16843
16844   if (VAT_JSON_ARRAY != vam->json_tree.type)
16845     {
16846       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16847       vat_json_init_array (&vam->json_tree);
16848     }
16849   node = vat_json_array_add (&vam->json_tree);
16850
16851   vat_json_init_object (node);
16852   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
16853   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
16854   vat_json_object_add_ip6 (node, "prefix", ip6);
16855   vat_json_object_add_uint (node, "mask_length", mp->address_length);
16856   vat_json_object_add_uint (node, "path_count", count);
16857   fp = mp->path;
16858   for (i = 0; i < count; i++)
16859     {
16860       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
16861       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
16862       vat_json_object_add_uint (node, "is_local", fp->is_local);
16863       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
16864       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
16865       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
16866       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
16867       if (fp->afi == IP46_TYPE_IP4)
16868         {
16869           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
16870           vat_json_object_add_ip4 (node, "next_hop", ip4);
16871         }
16872       else if (fp->afi == IP46_TYPE_IP6)
16873         {
16874           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
16875           vat_json_object_add_ip6 (node, "next_hop", ip6);
16876         }
16877     }
16878 }
16879
16880 static int
16881 api_ip6_fib_dump (vat_main_t * vam)
16882 {
16883   vl_api_ip6_fib_dump_t *mp;
16884   vl_api_control_ping_t *mp_ping;
16885   int ret;
16886
16887   M (IP6_FIB_DUMP, mp);
16888   S (mp);
16889
16890   /* Use a control ping for synchronization */
16891   M (CONTROL_PING, mp_ping);
16892   S (mp_ping);
16893
16894   W (ret);
16895   return ret;
16896 }
16897
16898 static int
16899 api_ip6_mfib_dump (vat_main_t * vam)
16900 {
16901   vl_api_ip6_mfib_dump_t *mp;
16902   vl_api_control_ping_t *mp_ping;
16903   int ret;
16904
16905   M (IP6_MFIB_DUMP, mp);
16906   S (mp);
16907
16908   /* Use a control ping for synchronization */
16909   M (CONTROL_PING, mp_ping);
16910   S (mp_ping);
16911
16912   W (ret);
16913   return ret;
16914 }
16915
16916 int
16917 api_classify_table_ids (vat_main_t * vam)
16918 {
16919   vl_api_classify_table_ids_t *mp;
16920   int ret;
16921
16922   /* Construct the API message */
16923   M (CLASSIFY_TABLE_IDS, mp);
16924   mp->context = 0;
16925
16926   S (mp);
16927   W (ret);
16928   return ret;
16929 }
16930
16931 int
16932 api_classify_table_by_interface (vat_main_t * vam)
16933 {
16934   unformat_input_t *input = vam->input;
16935   vl_api_classify_table_by_interface_t *mp;
16936
16937   u32 sw_if_index = ~0;
16938   int ret;
16939   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16940     {
16941       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16942         ;
16943       else if (unformat (input, "sw_if_index %d", &sw_if_index))
16944         ;
16945       else
16946         break;
16947     }
16948   if (sw_if_index == ~0)
16949     {
16950       errmsg ("missing interface name or sw_if_index");
16951       return -99;
16952     }
16953
16954   /* Construct the API message */
16955   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
16956   mp->context = 0;
16957   mp->sw_if_index = ntohl (sw_if_index);
16958
16959   S (mp);
16960   W (ret);
16961   return ret;
16962 }
16963
16964 int
16965 api_classify_table_info (vat_main_t * vam)
16966 {
16967   unformat_input_t *input = vam->input;
16968   vl_api_classify_table_info_t *mp;
16969
16970   u32 table_id = ~0;
16971   int ret;
16972   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16973     {
16974       if (unformat (input, "table_id %d", &table_id))
16975         ;
16976       else
16977         break;
16978     }
16979   if (table_id == ~0)
16980     {
16981       errmsg ("missing table id");
16982       return -99;
16983     }
16984
16985   /* Construct the API message */
16986   M (CLASSIFY_TABLE_INFO, mp);
16987   mp->context = 0;
16988   mp->table_id = ntohl (table_id);
16989
16990   S (mp);
16991   W (ret);
16992   return ret;
16993 }
16994
16995 int
16996 api_classify_session_dump (vat_main_t * vam)
16997 {
16998   unformat_input_t *input = vam->input;
16999   vl_api_classify_session_dump_t *mp;
17000   vl_api_control_ping_t *mp_ping;
17001
17002   u32 table_id = ~0;
17003   int ret;
17004   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17005     {
17006       if (unformat (input, "table_id %d", &table_id))
17007         ;
17008       else
17009         break;
17010     }
17011   if (table_id == ~0)
17012     {
17013       errmsg ("missing table id");
17014       return -99;
17015     }
17016
17017   /* Construct the API message */
17018   M (CLASSIFY_SESSION_DUMP, mp);
17019   mp->context = 0;
17020   mp->table_id = ntohl (table_id);
17021   S (mp);
17022
17023   /* Use a control ping for synchronization */
17024   M (CONTROL_PING, mp_ping);
17025   S (mp_ping);
17026
17027   W (ret);
17028   return ret;
17029 }
17030
17031 static void
17032 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
17033 {
17034   vat_main_t *vam = &vat_main;
17035
17036   print (vam->ofp, "collector_address %U, collector_port %d, "
17037          "src_address %U, vrf_id %d, path_mtu %u, "
17038          "template_interval %u, udp_checksum %d",
17039          format_ip4_address, mp->collector_address,
17040          ntohs (mp->collector_port),
17041          format_ip4_address, mp->src_address,
17042          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
17043          ntohl (mp->template_interval), mp->udp_checksum);
17044
17045   vam->retval = 0;
17046   vam->result_ready = 1;
17047 }
17048
17049 static void
17050   vl_api_ipfix_exporter_details_t_handler_json
17051   (vl_api_ipfix_exporter_details_t * mp)
17052 {
17053   vat_main_t *vam = &vat_main;
17054   vat_json_node_t node;
17055   struct in_addr collector_address;
17056   struct in_addr src_address;
17057
17058   vat_json_init_object (&node);
17059   clib_memcpy (&collector_address, &mp->collector_address,
17060                sizeof (collector_address));
17061   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
17062   vat_json_object_add_uint (&node, "collector_port",
17063                             ntohs (mp->collector_port));
17064   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
17065   vat_json_object_add_ip4 (&node, "src_address", src_address);
17066   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
17067   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
17068   vat_json_object_add_uint (&node, "template_interval",
17069                             ntohl (mp->template_interval));
17070   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
17071
17072   vat_json_print (vam->ofp, &node);
17073   vat_json_free (&node);
17074   vam->retval = 0;
17075   vam->result_ready = 1;
17076 }
17077
17078 int
17079 api_ipfix_exporter_dump (vat_main_t * vam)
17080 {
17081   vl_api_ipfix_exporter_dump_t *mp;
17082   int ret;
17083
17084   /* Construct the API message */
17085   M (IPFIX_EXPORTER_DUMP, mp);
17086   mp->context = 0;
17087
17088   S (mp);
17089   W (ret);
17090   return ret;
17091 }
17092
17093 static int
17094 api_ipfix_classify_stream_dump (vat_main_t * vam)
17095 {
17096   vl_api_ipfix_classify_stream_dump_t *mp;
17097   int ret;
17098
17099   /* Construct the API message */
17100   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
17101   mp->context = 0;
17102
17103   S (mp);
17104   W (ret);
17105   return ret;
17106   /* NOTREACHED */
17107   return 0;
17108 }
17109
17110 static void
17111   vl_api_ipfix_classify_stream_details_t_handler
17112   (vl_api_ipfix_classify_stream_details_t * mp)
17113 {
17114   vat_main_t *vam = &vat_main;
17115   print (vam->ofp, "domain_id %d, src_port %d",
17116          ntohl (mp->domain_id), ntohs (mp->src_port));
17117   vam->retval = 0;
17118   vam->result_ready = 1;
17119 }
17120
17121 static void
17122   vl_api_ipfix_classify_stream_details_t_handler_json
17123   (vl_api_ipfix_classify_stream_details_t * mp)
17124 {
17125   vat_main_t *vam = &vat_main;
17126   vat_json_node_t node;
17127
17128   vat_json_init_object (&node);
17129   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
17130   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
17131
17132   vat_json_print (vam->ofp, &node);
17133   vat_json_free (&node);
17134   vam->retval = 0;
17135   vam->result_ready = 1;
17136 }
17137
17138 static int
17139 api_ipfix_classify_table_dump (vat_main_t * vam)
17140 {
17141   vl_api_ipfix_classify_table_dump_t *mp;
17142   vl_api_control_ping_t *mp_ping;
17143   int ret;
17144
17145   if (!vam->json_output)
17146     {
17147       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
17148              "transport_protocol");
17149     }
17150
17151   /* Construct the API message */
17152   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
17153
17154   /* send it... */
17155   S (mp);
17156
17157   /* Use a control ping for synchronization */
17158   M (CONTROL_PING, mp_ping);
17159   S (mp_ping);
17160
17161   W (ret);
17162   return ret;
17163 }
17164
17165 static void
17166   vl_api_ipfix_classify_table_details_t_handler
17167   (vl_api_ipfix_classify_table_details_t * mp)
17168 {
17169   vat_main_t *vam = &vat_main;
17170   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
17171          mp->transport_protocol);
17172 }
17173
17174 static void
17175   vl_api_ipfix_classify_table_details_t_handler_json
17176   (vl_api_ipfix_classify_table_details_t * mp)
17177 {
17178   vat_json_node_t *node = NULL;
17179   vat_main_t *vam = &vat_main;
17180
17181   if (VAT_JSON_ARRAY != vam->json_tree.type)
17182     {
17183       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17184       vat_json_init_array (&vam->json_tree);
17185     }
17186
17187   node = vat_json_array_add (&vam->json_tree);
17188   vat_json_init_object (node);
17189
17190   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
17191   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
17192   vat_json_object_add_uint (node, "transport_protocol",
17193                             mp->transport_protocol);
17194 }
17195
17196 static int
17197 api_sw_interface_span_enable_disable (vat_main_t * vam)
17198 {
17199   unformat_input_t *i = vam->input;
17200   vl_api_sw_interface_span_enable_disable_t *mp;
17201   u32 src_sw_if_index = ~0;
17202   u32 dst_sw_if_index = ~0;
17203   u8 state = 3;
17204   int ret;
17205
17206   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17207     {
17208       if (unformat
17209           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
17210         ;
17211       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
17212         ;
17213       else
17214         if (unformat
17215             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
17216         ;
17217       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
17218         ;
17219       else if (unformat (i, "disable"))
17220         state = 0;
17221       else if (unformat (i, "rx"))
17222         state = 1;
17223       else if (unformat (i, "tx"))
17224         state = 2;
17225       else if (unformat (i, "both"))
17226         state = 3;
17227       else
17228         break;
17229     }
17230
17231   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
17232
17233   mp->sw_if_index_from = htonl (src_sw_if_index);
17234   mp->sw_if_index_to = htonl (dst_sw_if_index);
17235   mp->state = state;
17236
17237   S (mp);
17238   W (ret);
17239   return ret;
17240 }
17241
17242 static void
17243 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
17244                                             * mp)
17245 {
17246   vat_main_t *vam = &vat_main;
17247   u8 *sw_if_from_name = 0;
17248   u8 *sw_if_to_name = 0;
17249   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
17250   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
17251   char *states[] = { "none", "rx", "tx", "both" };
17252   hash_pair_t *p;
17253
17254   /* *INDENT-OFF* */
17255   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
17256   ({
17257     if ((u32) p->value[0] == sw_if_index_from)
17258       {
17259         sw_if_from_name = (u8 *)(p->key);
17260         if (sw_if_to_name)
17261           break;
17262       }
17263     if ((u32) p->value[0] == sw_if_index_to)
17264       {
17265         sw_if_to_name = (u8 *)(p->key);
17266         if (sw_if_from_name)
17267           break;
17268       }
17269   }));
17270   /* *INDENT-ON* */
17271   print (vam->ofp, "%20s => %20s (%s)",
17272          sw_if_from_name, sw_if_to_name, states[mp->state]);
17273 }
17274
17275 static void
17276   vl_api_sw_interface_span_details_t_handler_json
17277   (vl_api_sw_interface_span_details_t * mp)
17278 {
17279   vat_main_t *vam = &vat_main;
17280   vat_json_node_t *node = NULL;
17281   u8 *sw_if_from_name = 0;
17282   u8 *sw_if_to_name = 0;
17283   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
17284   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
17285   hash_pair_t *p;
17286
17287   /* *INDENT-OFF* */
17288   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
17289   ({
17290     if ((u32) p->value[0] == sw_if_index_from)
17291       {
17292         sw_if_from_name = (u8 *)(p->key);
17293         if (sw_if_to_name)
17294           break;
17295       }
17296     if ((u32) p->value[0] == sw_if_index_to)
17297       {
17298         sw_if_to_name = (u8 *)(p->key);
17299         if (sw_if_from_name)
17300           break;
17301       }
17302   }));
17303   /* *INDENT-ON* */
17304
17305   if (VAT_JSON_ARRAY != vam->json_tree.type)
17306     {
17307       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17308       vat_json_init_array (&vam->json_tree);
17309     }
17310   node = vat_json_array_add (&vam->json_tree);
17311
17312   vat_json_init_object (node);
17313   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
17314   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
17315   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
17316   if (0 != sw_if_to_name)
17317     {
17318       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
17319     }
17320   vat_json_object_add_uint (node, "state", mp->state);
17321 }
17322
17323 static int
17324 api_sw_interface_span_dump (vat_main_t * vam)
17325 {
17326   vl_api_sw_interface_span_dump_t *mp;
17327   vl_api_control_ping_t *mp_ping;
17328   int ret;
17329
17330   M (SW_INTERFACE_SPAN_DUMP, mp);
17331   S (mp);
17332
17333   /* Use a control ping for synchronization */
17334   M (CONTROL_PING, mp_ping);
17335   S (mp_ping);
17336
17337   W (ret);
17338   return ret;
17339 }
17340
17341 int
17342 api_pg_create_interface (vat_main_t * vam)
17343 {
17344   unformat_input_t *input = vam->input;
17345   vl_api_pg_create_interface_t *mp;
17346
17347   u32 if_id = ~0;
17348   int ret;
17349   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17350     {
17351       if (unformat (input, "if_id %d", &if_id))
17352         ;
17353       else
17354         break;
17355     }
17356   if (if_id == ~0)
17357     {
17358       errmsg ("missing pg interface index");
17359       return -99;
17360     }
17361
17362   /* Construct the API message */
17363   M (PG_CREATE_INTERFACE, mp);
17364   mp->context = 0;
17365   mp->interface_id = ntohl (if_id);
17366
17367   S (mp);
17368   W (ret);
17369   return ret;
17370 }
17371
17372 int
17373 api_pg_capture (vat_main_t * vam)
17374 {
17375   unformat_input_t *input = vam->input;
17376   vl_api_pg_capture_t *mp;
17377
17378   u32 if_id = ~0;
17379   u8 enable = 1;
17380   u32 count = 1;
17381   u8 pcap_file_set = 0;
17382   u8 *pcap_file = 0;
17383   int ret;
17384   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17385     {
17386       if (unformat (input, "if_id %d", &if_id))
17387         ;
17388       else if (unformat (input, "pcap %s", &pcap_file))
17389         pcap_file_set = 1;
17390       else if (unformat (input, "count %d", &count))
17391         ;
17392       else if (unformat (input, "disable"))
17393         enable = 0;
17394       else
17395         break;
17396     }
17397   if (if_id == ~0)
17398     {
17399       errmsg ("missing pg interface index");
17400       return -99;
17401     }
17402   if (pcap_file_set > 0)
17403     {
17404       if (vec_len (pcap_file) > 255)
17405         {
17406           errmsg ("pcap file name is too long");
17407           return -99;
17408         }
17409     }
17410
17411   u32 name_len = vec_len (pcap_file);
17412   /* Construct the API message */
17413   M (PG_CAPTURE, mp);
17414   mp->context = 0;
17415   mp->interface_id = ntohl (if_id);
17416   mp->is_enabled = enable;
17417   mp->count = ntohl (count);
17418   mp->pcap_name_length = ntohl (name_len);
17419   if (pcap_file_set != 0)
17420     {
17421       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
17422     }
17423   vec_free (pcap_file);
17424
17425   S (mp);
17426   W (ret);
17427   return ret;
17428 }
17429
17430 int
17431 api_pg_enable_disable (vat_main_t * vam)
17432 {
17433   unformat_input_t *input = vam->input;
17434   vl_api_pg_enable_disable_t *mp;
17435
17436   u8 enable = 1;
17437   u8 stream_name_set = 0;
17438   u8 *stream_name = 0;
17439   int ret;
17440   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17441     {
17442       if (unformat (input, "stream %s", &stream_name))
17443         stream_name_set = 1;
17444       else if (unformat (input, "disable"))
17445         enable = 0;
17446       else
17447         break;
17448     }
17449
17450   if (stream_name_set > 0)
17451     {
17452       if (vec_len (stream_name) > 255)
17453         {
17454           errmsg ("stream name too long");
17455           return -99;
17456         }
17457     }
17458
17459   u32 name_len = vec_len (stream_name);
17460   /* Construct the API message */
17461   M (PG_ENABLE_DISABLE, mp);
17462   mp->context = 0;
17463   mp->is_enabled = enable;
17464   if (stream_name_set != 0)
17465     {
17466       mp->stream_name_length = ntohl (name_len);
17467       clib_memcpy (mp->stream_name, stream_name, name_len);
17468     }
17469   vec_free (stream_name);
17470
17471   S (mp);
17472   W (ret);
17473   return ret;
17474 }
17475
17476 int
17477 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
17478 {
17479   unformat_input_t *input = vam->input;
17480   vl_api_ip_source_and_port_range_check_add_del_t *mp;
17481
17482   u16 *low_ports = 0;
17483   u16 *high_ports = 0;
17484   u16 this_low;
17485   u16 this_hi;
17486   ip4_address_t ip4_addr;
17487   ip6_address_t ip6_addr;
17488   u32 length;
17489   u32 tmp, tmp2;
17490   u8 prefix_set = 0;
17491   u32 vrf_id = ~0;
17492   u8 is_add = 1;
17493   u8 is_ipv6 = 0;
17494   int ret;
17495
17496   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17497     {
17498       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
17499         {
17500           prefix_set = 1;
17501         }
17502       else
17503         if (unformat
17504             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
17505         {
17506           prefix_set = 1;
17507           is_ipv6 = 1;
17508         }
17509       else if (unformat (input, "vrf %d", &vrf_id))
17510         ;
17511       else if (unformat (input, "del"))
17512         is_add = 0;
17513       else if (unformat (input, "port %d", &tmp))
17514         {
17515           if (tmp == 0 || tmp > 65535)
17516             {
17517               errmsg ("port %d out of range", tmp);
17518               return -99;
17519             }
17520           this_low = tmp;
17521           this_hi = this_low + 1;
17522           vec_add1 (low_ports, this_low);
17523           vec_add1 (high_ports, this_hi);
17524         }
17525       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
17526         {
17527           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
17528             {
17529               errmsg ("incorrect range parameters");
17530               return -99;
17531             }
17532           this_low = tmp;
17533           /* Note: in debug CLI +1 is added to high before
17534              passing to real fn that does "the work"
17535              (ip_source_and_port_range_check_add_del).
17536              This fn is a wrapper around the binary API fn a
17537              control plane will call, which expects this increment
17538              to have occurred. Hence letting the binary API control
17539              plane fn do the increment for consistency between VAT
17540              and other control planes.
17541            */
17542           this_hi = tmp2;
17543           vec_add1 (low_ports, this_low);
17544           vec_add1 (high_ports, this_hi);
17545         }
17546       else
17547         break;
17548     }
17549
17550   if (prefix_set == 0)
17551     {
17552       errmsg ("<address>/<mask> not specified");
17553       return -99;
17554     }
17555
17556   if (vrf_id == ~0)
17557     {
17558       errmsg ("VRF ID required, not specified");
17559       return -99;
17560     }
17561
17562   if (vrf_id == 0)
17563     {
17564       errmsg
17565         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
17566       return -99;
17567     }
17568
17569   if (vec_len (low_ports) == 0)
17570     {
17571       errmsg ("At least one port or port range required");
17572       return -99;
17573     }
17574
17575   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
17576
17577   mp->is_add = is_add;
17578
17579   if (is_ipv6)
17580     {
17581       mp->is_ipv6 = 1;
17582       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
17583     }
17584   else
17585     {
17586       mp->is_ipv6 = 0;
17587       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
17588     }
17589
17590   mp->mask_length = length;
17591   mp->number_of_ranges = vec_len (low_ports);
17592
17593   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
17594   vec_free (low_ports);
17595
17596   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
17597   vec_free (high_ports);
17598
17599   mp->vrf_id = ntohl (vrf_id);
17600
17601   S (mp);
17602   W (ret);
17603   return ret;
17604 }
17605
17606 int
17607 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
17608 {
17609   unformat_input_t *input = vam->input;
17610   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
17611   u32 sw_if_index = ~0;
17612   int vrf_set = 0;
17613   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
17614   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
17615   u8 is_add = 1;
17616   int ret;
17617
17618   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17619     {
17620       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17621         ;
17622       else if (unformat (input, "sw_if_index %d", &sw_if_index))
17623         ;
17624       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
17625         vrf_set = 1;
17626       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
17627         vrf_set = 1;
17628       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
17629         vrf_set = 1;
17630       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
17631         vrf_set = 1;
17632       else if (unformat (input, "del"))
17633         is_add = 0;
17634       else
17635         break;
17636     }
17637
17638   if (sw_if_index == ~0)
17639     {
17640       errmsg ("Interface required but not specified");
17641       return -99;
17642     }
17643
17644   if (vrf_set == 0)
17645     {
17646       errmsg ("VRF ID required but not specified");
17647       return -99;
17648     }
17649
17650   if (tcp_out_vrf_id == 0
17651       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
17652     {
17653       errmsg
17654         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
17655       return -99;
17656     }
17657
17658   /* Construct the API message */
17659   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
17660
17661   mp->sw_if_index = ntohl (sw_if_index);
17662   mp->is_add = is_add;
17663   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
17664   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
17665   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
17666   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
17667
17668   /* send it... */
17669   S (mp);
17670
17671   /* Wait for a reply... */
17672   W (ret);
17673   return ret;
17674 }
17675
17676 static int
17677 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
17678 {
17679   unformat_input_t *i = vam->input;
17680   vl_api_ipsec_gre_add_del_tunnel_t *mp;
17681   u32 local_sa_id = 0;
17682   u32 remote_sa_id = 0;
17683   ip4_address_t src_address;
17684   ip4_address_t dst_address;
17685   u8 is_add = 1;
17686   int ret;
17687
17688   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17689     {
17690       if (unformat (i, "local_sa %d", &local_sa_id))
17691         ;
17692       else if (unformat (i, "remote_sa %d", &remote_sa_id))
17693         ;
17694       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
17695         ;
17696       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
17697         ;
17698       else if (unformat (i, "del"))
17699         is_add = 0;
17700       else
17701         {
17702           clib_warning ("parse error '%U'", format_unformat_error, i);
17703           return -99;
17704         }
17705     }
17706
17707   M (IPSEC_GRE_ADD_DEL_TUNNEL, mp);
17708
17709   mp->local_sa_id = ntohl (local_sa_id);
17710   mp->remote_sa_id = ntohl (remote_sa_id);
17711   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
17712   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
17713   mp->is_add = is_add;
17714
17715   S (mp);
17716   W (ret);
17717   return ret;
17718 }
17719
17720 static int
17721 api_punt (vat_main_t * vam)
17722 {
17723   unformat_input_t *i = vam->input;
17724   vl_api_punt_t *mp;
17725   u32 ipv = ~0;
17726   u32 protocol = ~0;
17727   u32 port = ~0;
17728   int is_add = 1;
17729   int ret;
17730
17731   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17732     {
17733       if (unformat (i, "ip %d", &ipv))
17734         ;
17735       else if (unformat (i, "protocol %d", &protocol))
17736         ;
17737       else if (unformat (i, "port %d", &port))
17738         ;
17739       else if (unformat (i, "del"))
17740         is_add = 0;
17741       else
17742         {
17743           clib_warning ("parse error '%U'", format_unformat_error, i);
17744           return -99;
17745         }
17746     }
17747
17748   M (PUNT, mp);
17749
17750   mp->is_add = (u8) is_add;
17751   mp->ipv = (u8) ipv;
17752   mp->l4_protocol = (u8) protocol;
17753   mp->l4_port = htons ((u16) port);
17754
17755   S (mp);
17756   W (ret);
17757   return ret;
17758 }
17759
17760 static void vl_api_ipsec_gre_tunnel_details_t_handler
17761   (vl_api_ipsec_gre_tunnel_details_t * mp)
17762 {
17763   vat_main_t *vam = &vat_main;
17764
17765   print (vam->ofp, "%11d%15U%15U%14d%14d",
17766          ntohl (mp->sw_if_index),
17767          format_ip4_address, &mp->src_address,
17768          format_ip4_address, &mp->dst_address,
17769          ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
17770 }
17771
17772 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
17773   (vl_api_ipsec_gre_tunnel_details_t * mp)
17774 {
17775   vat_main_t *vam = &vat_main;
17776   vat_json_node_t *node = NULL;
17777   struct in_addr ip4;
17778
17779   if (VAT_JSON_ARRAY != vam->json_tree.type)
17780     {
17781       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17782       vat_json_init_array (&vam->json_tree);
17783     }
17784   node = vat_json_array_add (&vam->json_tree);
17785
17786   vat_json_init_object (node);
17787   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
17788   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
17789   vat_json_object_add_ip4 (node, "src_address", ip4);
17790   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
17791   vat_json_object_add_ip4 (node, "dst_address", ip4);
17792   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
17793   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
17794 }
17795
17796 static int
17797 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
17798 {
17799   unformat_input_t *i = vam->input;
17800   vl_api_ipsec_gre_tunnel_dump_t *mp;
17801   vl_api_control_ping_t *mp_ping;
17802   u32 sw_if_index;
17803   u8 sw_if_index_set = 0;
17804   int ret;
17805
17806   /* Parse args required to build the message */
17807   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17808     {
17809       if (unformat (i, "sw_if_index %d", &sw_if_index))
17810         sw_if_index_set = 1;
17811       else
17812         break;
17813     }
17814
17815   if (sw_if_index_set == 0)
17816     {
17817       sw_if_index = ~0;
17818     }
17819
17820   if (!vam->json_output)
17821     {
17822       print (vam->ofp, "%11s%15s%15s%14s%14s",
17823              "sw_if_index", "src_address", "dst_address",
17824              "local_sa_id", "remote_sa_id");
17825     }
17826
17827   /* Get list of gre-tunnel interfaces */
17828   M (IPSEC_GRE_TUNNEL_DUMP, mp);
17829
17830   mp->sw_if_index = htonl (sw_if_index);
17831
17832   S (mp);
17833
17834   /* Use a control ping for synchronization */
17835   M (CONTROL_PING, mp_ping);
17836   S (mp_ping);
17837
17838   W (ret);
17839   return ret;
17840 }
17841
17842 static int
17843 api_delete_subif (vat_main_t * vam)
17844 {
17845   unformat_input_t *i = vam->input;
17846   vl_api_delete_subif_t *mp;
17847   u32 sw_if_index = ~0;
17848   int ret;
17849
17850   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17851     {
17852       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17853         ;
17854       if (unformat (i, "sw_if_index %d", &sw_if_index))
17855         ;
17856       else
17857         break;
17858     }
17859
17860   if (sw_if_index == ~0)
17861     {
17862       errmsg ("missing sw_if_index");
17863       return -99;
17864     }
17865
17866   /* Construct the API message */
17867   M (DELETE_SUBIF, mp);
17868   mp->sw_if_index = ntohl (sw_if_index);
17869
17870   S (mp);
17871   W (ret);
17872   return ret;
17873 }
17874
17875 #define foreach_pbb_vtr_op      \
17876 _("disable",  L2_VTR_DISABLED)  \
17877 _("pop",  L2_VTR_POP_2)         \
17878 _("push",  L2_VTR_PUSH_2)
17879
17880 static int
17881 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
17882 {
17883   unformat_input_t *i = vam->input;
17884   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
17885   u32 sw_if_index = ~0, vtr_op = ~0;
17886   u16 outer_tag = ~0;
17887   u8 dmac[6], smac[6];
17888   u8 dmac_set = 0, smac_set = 0;
17889   u16 vlanid = 0;
17890   u32 sid = ~0;
17891   u32 tmp;
17892   int ret;
17893
17894   /* Shut up coverity */
17895   memset (dmac, 0, sizeof (dmac));
17896   memset (smac, 0, sizeof (smac));
17897
17898   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17899     {
17900       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17901         ;
17902       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17903         ;
17904       else if (unformat (i, "vtr_op %d", &vtr_op))
17905         ;
17906 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
17907       foreach_pbb_vtr_op
17908 #undef _
17909         else if (unformat (i, "translate_pbb_stag"))
17910         {
17911           if (unformat (i, "%d", &tmp))
17912             {
17913               vtr_op = L2_VTR_TRANSLATE_2_1;
17914               outer_tag = tmp;
17915             }
17916           else
17917             {
17918               errmsg
17919                 ("translate_pbb_stag operation requires outer tag definition");
17920               return -99;
17921             }
17922         }
17923       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
17924         dmac_set++;
17925       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
17926         smac_set++;
17927       else if (unformat (i, "sid %d", &sid))
17928         ;
17929       else if (unformat (i, "vlanid %d", &tmp))
17930         vlanid = tmp;
17931       else
17932         {
17933           clib_warning ("parse error '%U'", format_unformat_error, i);
17934           return -99;
17935         }
17936     }
17937
17938   if ((sw_if_index == ~0) || (vtr_op == ~0))
17939     {
17940       errmsg ("missing sw_if_index or vtr operation");
17941       return -99;
17942     }
17943   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
17944       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
17945     {
17946       errmsg
17947         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
17948       return -99;
17949     }
17950
17951   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
17952   mp->sw_if_index = ntohl (sw_if_index);
17953   mp->vtr_op = ntohl (vtr_op);
17954   mp->outer_tag = ntohs (outer_tag);
17955   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
17956   clib_memcpy (mp->b_smac, smac, sizeof (smac));
17957   mp->b_vlanid = ntohs (vlanid);
17958   mp->i_sid = ntohl (sid);
17959
17960   S (mp);
17961   W (ret);
17962   return ret;
17963 }
17964
17965 static int
17966 api_flow_classify_set_interface (vat_main_t * vam)
17967 {
17968   unformat_input_t *i = vam->input;
17969   vl_api_flow_classify_set_interface_t *mp;
17970   u32 sw_if_index;
17971   int sw_if_index_set;
17972   u32 ip4_table_index = ~0;
17973   u32 ip6_table_index = ~0;
17974   u8 is_add = 1;
17975   int ret;
17976
17977   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17978     {
17979       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17980         sw_if_index_set = 1;
17981       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17982         sw_if_index_set = 1;
17983       else if (unformat (i, "del"))
17984         is_add = 0;
17985       else if (unformat (i, "ip4-table %d", &ip4_table_index))
17986         ;
17987       else if (unformat (i, "ip6-table %d", &ip6_table_index))
17988         ;
17989       else
17990         {
17991           clib_warning ("parse error '%U'", format_unformat_error, i);
17992           return -99;
17993         }
17994     }
17995
17996   if (sw_if_index_set == 0)
17997     {
17998       errmsg ("missing interface name or sw_if_index");
17999       return -99;
18000     }
18001
18002   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
18003
18004   mp->sw_if_index = ntohl (sw_if_index);
18005   mp->ip4_table_index = ntohl (ip4_table_index);
18006   mp->ip6_table_index = ntohl (ip6_table_index);
18007   mp->is_add = is_add;
18008
18009   S (mp);
18010   W (ret);
18011   return ret;
18012 }
18013
18014 static int
18015 api_flow_classify_dump (vat_main_t * vam)
18016 {
18017   unformat_input_t *i = vam->input;
18018   vl_api_flow_classify_dump_t *mp;
18019   vl_api_control_ping_t *mp_ping;
18020   u8 type = FLOW_CLASSIFY_N_TABLES;
18021   int ret;
18022
18023   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
18024     ;
18025   else
18026     {
18027       errmsg ("classify table type must be specified");
18028       return -99;
18029     }
18030
18031   if (!vam->json_output)
18032     {
18033       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
18034     }
18035
18036   M (FLOW_CLASSIFY_DUMP, mp);
18037   mp->type = type;
18038   /* send it... */
18039   S (mp);
18040
18041   /* Use a control ping for synchronization */
18042   M (CONTROL_PING, mp_ping);
18043   S (mp_ping);
18044
18045   /* Wait for a reply... */
18046   W (ret);
18047   return ret;
18048 }
18049
18050 static int
18051 api_feature_enable_disable (vat_main_t * vam)
18052 {
18053   unformat_input_t *i = vam->input;
18054   vl_api_feature_enable_disable_t *mp;
18055   u8 *arc_name = 0;
18056   u8 *feature_name = 0;
18057   u32 sw_if_index = ~0;
18058   u8 enable = 1;
18059   int ret;
18060
18061   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18062     {
18063       if (unformat (i, "arc_name %s", &arc_name))
18064         ;
18065       else if (unformat (i, "feature_name %s", &feature_name))
18066         ;
18067       else
18068         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18069         ;
18070       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18071         ;
18072       else if (unformat (i, "disable"))
18073         enable = 0;
18074       else
18075         break;
18076     }
18077
18078   if (arc_name == 0)
18079     {
18080       errmsg ("missing arc name");
18081       return -99;
18082     }
18083   if (vec_len (arc_name) > 63)
18084     {
18085       errmsg ("arc name too long");
18086     }
18087
18088   if (feature_name == 0)
18089     {
18090       errmsg ("missing feature name");
18091       return -99;
18092     }
18093   if (vec_len (feature_name) > 63)
18094     {
18095       errmsg ("feature name too long");
18096     }
18097
18098   if (sw_if_index == ~0)
18099     {
18100       errmsg ("missing interface name or sw_if_index");
18101       return -99;
18102     }
18103
18104   /* Construct the API message */
18105   M (FEATURE_ENABLE_DISABLE, mp);
18106   mp->sw_if_index = ntohl (sw_if_index);
18107   mp->enable = enable;
18108   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
18109   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
18110   vec_free (arc_name);
18111   vec_free (feature_name);
18112
18113   S (mp);
18114   W (ret);
18115   return ret;
18116 }
18117
18118 static int
18119 api_sw_interface_tag_add_del (vat_main_t * vam)
18120 {
18121   unformat_input_t *i = vam->input;
18122   vl_api_sw_interface_tag_add_del_t *mp;
18123   u32 sw_if_index = ~0;
18124   u8 *tag = 0;
18125   u8 enable = 1;
18126   int ret;
18127
18128   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18129     {
18130       if (unformat (i, "tag %s", &tag))
18131         ;
18132       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18133         ;
18134       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18135         ;
18136       else if (unformat (i, "del"))
18137         enable = 0;
18138       else
18139         break;
18140     }
18141
18142   if (sw_if_index == ~0)
18143     {
18144       errmsg ("missing interface name or sw_if_index");
18145       return -99;
18146     }
18147
18148   if (enable && (tag == 0))
18149     {
18150       errmsg ("no tag specified");
18151       return -99;
18152     }
18153
18154   /* Construct the API message */
18155   M (SW_INTERFACE_TAG_ADD_DEL, mp);
18156   mp->sw_if_index = ntohl (sw_if_index);
18157   mp->is_add = enable;
18158   if (enable)
18159     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
18160   vec_free (tag);
18161
18162   S (mp);
18163   W (ret);
18164   return ret;
18165 }
18166
18167 static void vl_api_l2_xconnect_details_t_handler
18168   (vl_api_l2_xconnect_details_t * mp)
18169 {
18170   vat_main_t *vam = &vat_main;
18171
18172   print (vam->ofp, "%15d%15d",
18173          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
18174 }
18175
18176 static void vl_api_l2_xconnect_details_t_handler_json
18177   (vl_api_l2_xconnect_details_t * mp)
18178 {
18179   vat_main_t *vam = &vat_main;
18180   vat_json_node_t *node = NULL;
18181
18182   if (VAT_JSON_ARRAY != vam->json_tree.type)
18183     {
18184       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18185       vat_json_init_array (&vam->json_tree);
18186     }
18187   node = vat_json_array_add (&vam->json_tree);
18188
18189   vat_json_init_object (node);
18190   vat_json_object_add_uint (node, "rx_sw_if_index",
18191                             ntohl (mp->rx_sw_if_index));
18192   vat_json_object_add_uint (node, "tx_sw_if_index",
18193                             ntohl (mp->tx_sw_if_index));
18194 }
18195
18196 static int
18197 api_l2_xconnect_dump (vat_main_t * vam)
18198 {
18199   vl_api_l2_xconnect_dump_t *mp;
18200   vl_api_control_ping_t *mp_ping;
18201   int ret;
18202
18203   if (!vam->json_output)
18204     {
18205       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
18206     }
18207
18208   M (L2_XCONNECT_DUMP, mp);
18209
18210   S (mp);
18211
18212   /* Use a control ping for synchronization */
18213   M (CONTROL_PING, mp_ping);
18214   S (mp_ping);
18215
18216   W (ret);
18217   return ret;
18218 }
18219
18220 static int
18221 api_sw_interface_set_mtu (vat_main_t * vam)
18222 {
18223   unformat_input_t *i = vam->input;
18224   vl_api_sw_interface_set_mtu_t *mp;
18225   u32 sw_if_index = ~0;
18226   u32 mtu = 0;
18227   int ret;
18228
18229   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18230     {
18231       if (unformat (i, "mtu %d", &mtu))
18232         ;
18233       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18234         ;
18235       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18236         ;
18237       else
18238         break;
18239     }
18240
18241   if (sw_if_index == ~0)
18242     {
18243       errmsg ("missing interface name or sw_if_index");
18244       return -99;
18245     }
18246
18247   if (mtu == 0)
18248     {
18249       errmsg ("no mtu specified");
18250       return -99;
18251     }
18252
18253   /* Construct the API message */
18254   M (SW_INTERFACE_SET_MTU, mp);
18255   mp->sw_if_index = ntohl (sw_if_index);
18256   mp->mtu = ntohs ((u16) mtu);
18257
18258   S (mp);
18259   W (ret);
18260   return ret;
18261 }
18262
18263
18264 static int
18265 q_or_quit (vat_main_t * vam)
18266 {
18267 #if VPP_API_TEST_BUILTIN == 0
18268   longjmp (vam->jump_buf, 1);
18269 #endif
18270   return 0;                     /* not so much */
18271 }
18272
18273 static int
18274 q (vat_main_t * vam)
18275 {
18276   return q_or_quit (vam);
18277 }
18278
18279 static int
18280 quit (vat_main_t * vam)
18281 {
18282   return q_or_quit (vam);
18283 }
18284
18285 static int
18286 comment (vat_main_t * vam)
18287 {
18288   return 0;
18289 }
18290
18291 static int
18292 cmd_cmp (void *a1, void *a2)
18293 {
18294   u8 **c1 = a1;
18295   u8 **c2 = a2;
18296
18297   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
18298 }
18299
18300 static int
18301 help (vat_main_t * vam)
18302 {
18303   u8 **cmds = 0;
18304   u8 *name = 0;
18305   hash_pair_t *p;
18306   unformat_input_t *i = vam->input;
18307   int j;
18308
18309   if (unformat (i, "%s", &name))
18310     {
18311       uword *hs;
18312
18313       vec_add1 (name, 0);
18314
18315       hs = hash_get_mem (vam->help_by_name, name);
18316       if (hs)
18317         print (vam->ofp, "usage: %s %s", name, hs[0]);
18318       else
18319         print (vam->ofp, "No such msg / command '%s'", name);
18320       vec_free (name);
18321       return 0;
18322     }
18323
18324   print (vam->ofp, "Help is available for the following:");
18325
18326     /* *INDENT-OFF* */
18327     hash_foreach_pair (p, vam->function_by_name,
18328     ({
18329       vec_add1 (cmds, (u8 *)(p->key));
18330     }));
18331     /* *INDENT-ON* */
18332
18333   vec_sort_with_function (cmds, cmd_cmp);
18334
18335   for (j = 0; j < vec_len (cmds); j++)
18336     print (vam->ofp, "%s", cmds[j]);
18337
18338   vec_free (cmds);
18339   return 0;
18340 }
18341
18342 static int
18343 set (vat_main_t * vam)
18344 {
18345   u8 *name = 0, *value = 0;
18346   unformat_input_t *i = vam->input;
18347
18348   if (unformat (i, "%s", &name))
18349     {
18350       /* The input buffer is a vector, not a string. */
18351       value = vec_dup (i->buffer);
18352       vec_delete (value, i->index, 0);
18353       /* Almost certainly has a trailing newline */
18354       if (value[vec_len (value) - 1] == '\n')
18355         value[vec_len (value) - 1] = 0;
18356       /* Make sure it's a proper string, one way or the other */
18357       vec_add1 (value, 0);
18358       (void) clib_macro_set_value (&vam->macro_main,
18359                                    (char *) name, (char *) value);
18360     }
18361   else
18362     errmsg ("usage: set <name> <value>");
18363
18364   vec_free (name);
18365   vec_free (value);
18366   return 0;
18367 }
18368
18369 static int
18370 unset (vat_main_t * vam)
18371 {
18372   u8 *name = 0;
18373
18374   if (unformat (vam->input, "%s", &name))
18375     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
18376       errmsg ("unset: %s wasn't set", name);
18377   vec_free (name);
18378   return 0;
18379 }
18380
18381 typedef struct
18382 {
18383   u8 *name;
18384   u8 *value;
18385 } macro_sort_t;
18386
18387
18388 static int
18389 macro_sort_cmp (void *a1, void *a2)
18390 {
18391   macro_sort_t *s1 = a1;
18392   macro_sort_t *s2 = a2;
18393
18394   return strcmp ((char *) (s1->name), (char *) (s2->name));
18395 }
18396
18397 static int
18398 dump_macro_table (vat_main_t * vam)
18399 {
18400   macro_sort_t *sort_me = 0, *sm;
18401   int i;
18402   hash_pair_t *p;
18403
18404     /* *INDENT-OFF* */
18405     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
18406     ({
18407       vec_add2 (sort_me, sm, 1);
18408       sm->name = (u8 *)(p->key);
18409       sm->value = (u8 *) (p->value[0]);
18410     }));
18411     /* *INDENT-ON* */
18412
18413   vec_sort_with_function (sort_me, macro_sort_cmp);
18414
18415   if (vec_len (sort_me))
18416     print (vam->ofp, "%-15s%s", "Name", "Value");
18417   else
18418     print (vam->ofp, "The macro table is empty...");
18419
18420   for (i = 0; i < vec_len (sort_me); i++)
18421     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
18422   return 0;
18423 }
18424
18425 static int
18426 dump_node_table (vat_main_t * vam)
18427 {
18428   int i, j;
18429   vlib_node_t *node, *next_node;
18430
18431   if (vec_len (vam->graph_nodes) == 0)
18432     {
18433       print (vam->ofp, "Node table empty, issue get_node_graph...");
18434       return 0;
18435     }
18436
18437   for (i = 0; i < vec_len (vam->graph_nodes); i++)
18438     {
18439       node = vam->graph_nodes[i];
18440       print (vam->ofp, "[%d] %s", i, node->name);
18441       for (j = 0; j < vec_len (node->next_nodes); j++)
18442         {
18443           if (node->next_nodes[j] != ~0)
18444             {
18445               next_node = vam->graph_nodes[node->next_nodes[j]];
18446               print (vam->ofp, "  [%d] %s", j, next_node->name);
18447             }
18448         }
18449     }
18450   return 0;
18451 }
18452
18453 static int
18454 value_sort_cmp (void *a1, void *a2)
18455 {
18456   name_sort_t *n1 = a1;
18457   name_sort_t *n2 = a2;
18458
18459   if (n1->value < n2->value)
18460     return -1;
18461   if (n1->value > n2->value)
18462     return 1;
18463   return 0;
18464 }
18465
18466
18467 static int
18468 dump_msg_api_table (vat_main_t * vam)
18469 {
18470   api_main_t *am = &api_main;
18471   name_sort_t *nses = 0, *ns;
18472   hash_pair_t *hp;
18473   int i;
18474
18475   /* *INDENT-OFF* */
18476   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
18477   ({
18478     vec_add2 (nses, ns, 1);
18479     ns->name = (u8 *)(hp->key);
18480     ns->value = (u32) hp->value[0];
18481   }));
18482   /* *INDENT-ON* */
18483
18484   vec_sort_with_function (nses, value_sort_cmp);
18485
18486   for (i = 0; i < vec_len (nses); i++)
18487     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
18488   vec_free (nses);
18489   return 0;
18490 }
18491
18492 static int
18493 get_msg_id (vat_main_t * vam)
18494 {
18495   u8 *name_and_crc;
18496   u32 message_index;
18497
18498   if (unformat (vam->input, "%s", &name_and_crc))
18499     {
18500       message_index = vl_api_get_msg_index (name_and_crc);
18501       if (message_index == ~0)
18502         {
18503           print (vam->ofp, " '%s' not found", name_and_crc);
18504           return 0;
18505         }
18506       print (vam->ofp, " '%s' has message index %d",
18507              name_and_crc, message_index);
18508       return 0;
18509     }
18510   errmsg ("name_and_crc required...");
18511   return 0;
18512 }
18513
18514 static int
18515 search_node_table (vat_main_t * vam)
18516 {
18517   unformat_input_t *line_input = vam->input;
18518   u8 *node_to_find;
18519   int j;
18520   vlib_node_t *node, *next_node;
18521   uword *p;
18522
18523   if (vam->graph_node_index_by_name == 0)
18524     {
18525       print (vam->ofp, "Node table empty, issue get_node_graph...");
18526       return 0;
18527     }
18528
18529   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
18530     {
18531       if (unformat (line_input, "%s", &node_to_find))
18532         {
18533           vec_add1 (node_to_find, 0);
18534           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
18535           if (p == 0)
18536             {
18537               print (vam->ofp, "%s not found...", node_to_find);
18538               goto out;
18539             }
18540           node = vam->graph_nodes[p[0]];
18541           print (vam->ofp, "[%d] %s", p[0], node->name);
18542           for (j = 0; j < vec_len (node->next_nodes); j++)
18543             {
18544               if (node->next_nodes[j] != ~0)
18545                 {
18546                   next_node = vam->graph_nodes[node->next_nodes[j]];
18547                   print (vam->ofp, "  [%d] %s", j, next_node->name);
18548                 }
18549             }
18550         }
18551
18552       else
18553         {
18554           clib_warning ("parse error '%U'", format_unformat_error,
18555                         line_input);
18556           return -99;
18557         }
18558
18559     out:
18560       vec_free (node_to_find);
18561
18562     }
18563
18564   return 0;
18565 }
18566
18567
18568 static int
18569 script (vat_main_t * vam)
18570 {
18571 #if (VPP_API_TEST_BUILTIN==0)
18572   u8 *s = 0;
18573   char *save_current_file;
18574   unformat_input_t save_input;
18575   jmp_buf save_jump_buf;
18576   u32 save_line_number;
18577
18578   FILE *new_fp, *save_ifp;
18579
18580   if (unformat (vam->input, "%s", &s))
18581     {
18582       new_fp = fopen ((char *) s, "r");
18583       if (new_fp == 0)
18584         {
18585           errmsg ("Couldn't open script file %s", s);
18586           vec_free (s);
18587           return -99;
18588         }
18589     }
18590   else
18591     {
18592       errmsg ("Missing script name");
18593       return -99;
18594     }
18595
18596   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
18597   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
18598   save_ifp = vam->ifp;
18599   save_line_number = vam->input_line_number;
18600   save_current_file = (char *) vam->current_file;
18601
18602   vam->input_line_number = 0;
18603   vam->ifp = new_fp;
18604   vam->current_file = s;
18605   do_one_file (vam);
18606
18607   clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
18608   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
18609   vam->ifp = save_ifp;
18610   vam->input_line_number = save_line_number;
18611   vam->current_file = (u8 *) save_current_file;
18612   vec_free (s);
18613
18614   return 0;
18615 #else
18616   clib_warning ("use the exec command...");
18617   return -99;
18618 #endif
18619 }
18620
18621 static int
18622 echo (vat_main_t * vam)
18623 {
18624   print (vam->ofp, "%v", vam->input->buffer);
18625   return 0;
18626 }
18627
18628 /* List of API message constructors, CLI names map to api_xxx */
18629 #define foreach_vpe_api_msg                                             \
18630 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
18631 _(sw_interface_dump,"")                                                 \
18632 _(sw_interface_set_flags,                                               \
18633   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
18634 _(sw_interface_add_del_address,                                         \
18635   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
18636 _(sw_interface_set_table,                                               \
18637   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
18638 _(sw_interface_set_mpls_enable,                                         \
18639   "<intfc> | sw_if_index [disable | dis]")                              \
18640 _(sw_interface_set_vpath,                                               \
18641   "<intfc> | sw_if_index <id> enable | disable")                        \
18642 _(sw_interface_set_vxlan_bypass,                                        \
18643   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
18644 _(sw_interface_set_l2_xconnect,                                         \
18645   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
18646   "enable | disable")                                                   \
18647 _(sw_interface_set_l2_bridge,                                           \
18648   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
18649   "[shg <split-horizon-group>] [bvi]\n"                                 \
18650   "enable | disable")                                                   \
18651 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
18652 _(bridge_domain_add_del,                                                \
18653   "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") \
18654 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
18655 _(l2fib_add_del,                                                        \
18656   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
18657 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
18658 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
18659 _(l2_flags,                                                             \
18660   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood]\n") \
18661 _(bridge_flags,                                                         \
18662   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
18663 _(tap_connect,                                                          \
18664   "tapname <name> mac <mac-addr> | random-mac [tag <string>]")          \
18665 _(tap_modify,                                                           \
18666   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
18667 _(tap_delete,                                                           \
18668   "<vpp-if-name> | sw_if_index <id>")                                   \
18669 _(sw_interface_tap_dump, "")                                            \
18670 _(ip_add_del_route,                                                     \
18671   "<addr>/<mask> via <addr> [table-id <n>]\n"                           \
18672   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
18673   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
18674   "[multipath] [count <n>]")                                            \
18675 _(ip_mroute_add_del,                                                    \
18676   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
18677   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
18678 _(mpls_route_add_del,                                                   \
18679   "<label> <eos> via <addr> [table-id <n>]\n"                           \
18680   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
18681   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
18682   "[multipath] [count <n>]")                                            \
18683 _(mpls_ip_bind_unbind,                                                  \
18684   "<label> <addr/len>")                                                 \
18685 _(mpls_tunnel_add_del,                                                  \
18686   " via <addr> [table-id <n>]\n"                                        \
18687   "sw_if_index <id>] [l2]  [del]")                                      \
18688 _(proxy_arp_add_del,                                                    \
18689   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
18690 _(proxy_arp_intfc_enable_disable,                                       \
18691   "<intfc> | sw_if_index <id> enable | disable")                        \
18692 _(sw_interface_set_unnumbered,                                          \
18693   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
18694 _(ip_neighbor_add_del,                                                  \
18695   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
18696   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
18697 _(reset_vrf, "vrf <id> [ipv6]")                                         \
18698 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
18699 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
18700   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
18701   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
18702   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
18703 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
18704 _(reset_fib, "vrf <n> [ipv6]")                                          \
18705 _(dhcp_proxy_config,                                                    \
18706   "svr <v46-address> src <v46-address>\n"                               \
18707    "rx_vrf_id <nn> server_vrf_id <nn>  [del]")                          \
18708 _(dhcp_proxy_set_vss,                                                   \
18709   "tbl_id <n> fib_id <n> oui <n> [ipv6] [del]")                         \
18710 _(dhcp_proxy_dump, "ip6")                                               \
18711 _(dhcp_client_config,                                                   \
18712   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
18713 _(set_ip_flow_hash,                                                     \
18714   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
18715 _(sw_interface_ip6_enable_disable,                                      \
18716   "<intfc> | sw_if_index <id> enable | disable")                        \
18717 _(sw_interface_ip6_set_link_local_address,                              \
18718   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
18719 _(ip6nd_proxy_add_del,                                                  \
18720   "<intfc> | sw_if_index <id> <ip6-address>")                           \
18721 _(ip6nd_proxy_dump, "")                                                 \
18722 _(sw_interface_ip6nd_ra_prefix,                                         \
18723   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
18724   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
18725   "[nolink] [isno]")                                                    \
18726 _(sw_interface_ip6nd_ra_config,                                         \
18727   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
18728   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
18729   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
18730 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
18731 _(l2_patch_add_del,                                                     \
18732   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
18733   "enable | disable")                                                   \
18734 _(sr_localsid_add_del,                                                  \
18735   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
18736   "fib-table <num> (end.psp) sw_if_index <num>")                        \
18737 _(classify_add_del_table,                                               \
18738   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
18739   " [del] [del-chain] mask <mask-value>\n"                              \
18740   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
18741   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
18742 _(classify_add_del_session,                                             \
18743   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
18744   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
18745   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
18746   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
18747 _(classify_set_interface_ip_table,                                      \
18748   "<intfc> | sw_if_index <nn> table <nn>")                              \
18749 _(classify_set_interface_l2_tables,                                     \
18750   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
18751   "  [other-table <nn>]")                                               \
18752 _(get_node_index, "node <node-name")                                    \
18753 _(add_node_next, "node <node-name> next <next-node-name>")              \
18754 _(l2tpv3_create_tunnel,                                                 \
18755   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
18756   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
18757   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
18758 _(l2tpv3_set_tunnel_cookies,                                            \
18759   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
18760   "[new_remote_cookie <nn>]\n")                                         \
18761 _(l2tpv3_interface_enable_disable,                                      \
18762   "<intfc> | sw_if_index <nn> enable | disable")                        \
18763 _(l2tpv3_set_lookup_key,                                                \
18764   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
18765 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
18766 _(vxlan_add_del_tunnel,                                                 \
18767   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
18768   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
18769   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
18770 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
18771 _(gre_add_del_tunnel,                                                   \
18772   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [teb] [del]\n")    \
18773 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
18774 _(l2_fib_clear_table, "")                                               \
18775 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
18776 _(l2_interface_vlan_tag_rewrite,                                        \
18777   "<intfc> | sw_if_index <nn> \n"                                       \
18778   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
18779   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
18780 _(create_vhost_user_if,                                                 \
18781         "socket <filename> [server] [renumber <dev_instance>] "         \
18782         "[mac <mac_address>] "                                          \
18783         "[mode <interrupt | polling>]")                                 \
18784 _(modify_vhost_user_if,                                                 \
18785         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
18786         "[server] [renumber <dev_instance>] "                           \
18787         "[mode <interrupt | polling>]")                                 \
18788 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
18789 _(sw_interface_vhost_user_dump, "")                                     \
18790 _(show_version, "")                                                     \
18791 _(vxlan_gpe_add_del_tunnel,                                             \
18792   "local <addr> remote <addr> vni <nn>\n"                               \
18793     "[encap-vrf-id <nn>] [decap-vrf-id <nn>] [next-ip4][next-ip6]"      \
18794   "[next-ethernet] [next-nsh]\n")                                       \
18795 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
18796 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
18797 _(interface_name_renumber,                                              \
18798   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
18799 _(input_acl_set_interface,                                              \
18800   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
18801   "  [l2-table <nn>] [del]")                                            \
18802 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
18803 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
18804 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
18805 _(ip_dump, "ipv4 | ipv6")                                               \
18806 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
18807 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
18808   "  spid_id <n> ")                                                     \
18809 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
18810   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
18811   "  integ_alg <alg> integ_key <hex>")                                  \
18812 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
18813   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
18814   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
18815   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
18816 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
18817 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
18818 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
18819   "(auth_data 0x<data> | auth_data <data>)")                            \
18820 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
18821   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
18822 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
18823   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
18824   "(local|remote)")                                                     \
18825 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
18826 _(ikev2_set_responder, "<profile_name> interface <interface> address <addr>") \
18827 _(ikev2_set_ike_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
18828 _(ikev2_set_esp_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
18829 _(ikev2_set_sa_lifetime, "<profile_name> <seconds> <jitter> <handover> <max bytes>") \
18830 _(ikev2_initiate_sa_init, "<profile_name>")                             \
18831 _(ikev2_initiate_del_ike_sa, "<ispi>")                                  \
18832 _(ikev2_initiate_del_child_sa, "<ispi>")                                \
18833 _(ikev2_initiate_rekey_child_sa, "<ispi>")                              \
18834 _(delete_loopback,"sw_if_index <nn>")                                   \
18835 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
18836 _(map_add_domain,                                                       \
18837   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
18838   "ip6-src <ip6addr> "                                                  \
18839   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
18840 _(map_del_domain, "index <n>")                                          \
18841 _(map_add_del_rule,                                                     \
18842   "index <n> psid <n> dst <ip6addr> [del]")                             \
18843 _(map_domain_dump, "")                                                  \
18844 _(map_rule_dump, "index <map-domain>")                                  \
18845 _(want_interface_events,  "enable|disable")                             \
18846 _(want_stats,"enable|disable")                                          \
18847 _(get_first_msg_id, "client <name>")                                    \
18848 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
18849 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
18850   "fib-id <nn> [ip4][ip6][default]")                                    \
18851 _(get_node_graph, " ")                                                  \
18852 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
18853 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
18854 _(ioam_disable, "")                                                     \
18855 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
18856                             " sw_if_index <sw_if_index> p <priority> "  \
18857                             "w <weight>] [del]")                        \
18858 _(one_add_del_locator, "locator-set <locator_name> "                    \
18859                         "iface <intf> | sw_if_index <sw_if_index> "     \
18860                         "p <priority> w <weight> [del]")                \
18861 _(one_add_del_local_eid,"vni <vni> eid "                                \
18862                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
18863                          "locator-set <locator_name> [del]"             \
18864                          "[key-id sha1|sha256 secret-key <secret-key>]")\
18865 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
18866 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
18867 _(one_enable_disable, "enable|disable")                                 \
18868 _(one_map_register_enable_disable, "enable|disable")                    \
18869 _(one_rloc_probe_enable_disable, "enable|disable")                      \
18870 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
18871                                "[seid <seid>] "                         \
18872                                "rloc <locator> p <prio> "               \
18873                                "w <weight> [rloc <loc> ... ] "          \
18874                                "action <action> [del-all]")             \
18875 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
18876                           "<local-eid>")                                \
18877 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
18878 _(one_use_petr, "ip-address> | disable")                                \
18879 _(one_map_request_mode, "src-dst|dst-only")                             \
18880 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
18881 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
18882 _(one_locator_set_dump, "[local | remote]")                             \
18883 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
18884 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
18885                        "[local] | [remote]")                            \
18886 _(one_stats_enable_disable, "enable|disalbe")                           \
18887 _(show_one_stats_enable_disable, "")                                    \
18888 _(one_eid_table_vni_dump, "")                                           \
18889 _(one_eid_table_map_dump, "l2|l3")                                      \
18890 _(one_map_resolver_dump, "")                                            \
18891 _(one_map_server_dump, "")                                              \
18892 _(one_adjacencies_get, "vni <vni>")                                     \
18893 _(show_one_rloc_probe_state, "")                                        \
18894 _(show_one_map_register_state, "")                                      \
18895 _(show_one_status, "")                                                  \
18896 _(one_stats_dump, "")                                                   \
18897 _(one_stats_flush, "")                                                  \
18898 _(one_get_map_request_itr_rlocs, "")                                    \
18899 _(show_one_pitr, "")                                                    \
18900 _(show_one_use_petr, "")                                                \
18901 _(show_one_map_request_mode, "")                                        \
18902 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
18903                             " sw_if_index <sw_if_index> p <priority> "  \
18904                             "w <weight>] [del]")                        \
18905 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
18906                         "iface <intf> | sw_if_index <sw_if_index> "     \
18907                         "p <priority> w <weight> [del]")                \
18908 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
18909                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
18910                          "locator-set <locator_name> [del]"             \
18911                          "[key-id sha1|sha256 secret-key <secret-key>]") \
18912 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
18913 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
18914 _(lisp_enable_disable, "enable|disable")                                \
18915 _(lisp_map_register_enable_disable, "enable|disable")                   \
18916 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
18917 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
18918                                "[seid <seid>] "                         \
18919                                "rloc <locator> p <prio> "               \
18920                                "w <weight> [rloc <loc> ... ] "          \
18921                                "action <action> [del-all]")             \
18922 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
18923                           "<local-eid>")                                \
18924 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
18925 _(lisp_use_petr, "<ip-address> | disable")                              \
18926 _(lisp_map_request_mode, "src-dst|dst-only")                            \
18927 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
18928 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
18929 _(lisp_locator_set_dump, "[local | remote]")                            \
18930 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
18931 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
18932                        "[local] | [remote]")                            \
18933 _(lisp_eid_table_vni_dump, "")                                          \
18934 _(lisp_eid_table_map_dump, "l2|l3")                                     \
18935 _(lisp_map_resolver_dump, "")                                           \
18936 _(lisp_map_server_dump, "")                                             \
18937 _(lisp_adjacencies_get, "vni <vni>")                                    \
18938 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
18939 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
18940 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
18941 _(gpe_get_encap_mode, "")                                               \
18942 _(lisp_gpe_add_del_iface, "up|down")                                    \
18943 _(lisp_gpe_enable_disable, "enable|disable")                            \
18944 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
18945   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
18946 _(show_lisp_rloc_probe_state, "")                                       \
18947 _(show_lisp_map_register_state, "")                                     \
18948 _(show_lisp_status, "")                                                 \
18949 _(lisp_get_map_request_itr_rlocs, "")                                   \
18950 _(show_lisp_pitr, "")                                                   \
18951 _(show_lisp_use_petr, "")                                               \
18952 _(show_lisp_map_request_mode, "")                                       \
18953 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
18954 _(af_packet_delete, "name <host interface name>")                       \
18955 _(policer_add_del, "name <policer name> <params> [del]")                \
18956 _(policer_dump, "[name <policer name>]")                                \
18957 _(policer_classify_set_interface,                                       \
18958   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
18959   "  [l2-table <nn>] [del]")                                            \
18960 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
18961 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
18962     "[master|slave]")                                                   \
18963 _(netmap_delete, "name <interface name>")                               \
18964 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
18965 _(mpls_fib_dump, "")                                                    \
18966 _(classify_table_ids, "")                                               \
18967 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
18968 _(classify_table_info, "table_id <nn>")                                 \
18969 _(classify_session_dump, "table_id <nn>")                               \
18970 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
18971     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
18972     "[template_interval <nn>] [udp_checksum]")                          \
18973 _(ipfix_exporter_dump, "")                                              \
18974 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
18975 _(ipfix_classify_stream_dump, "")                                       \
18976 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
18977 _(ipfix_classify_table_dump, "")                                        \
18978 _(sw_interface_span_enable_disable, "[src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
18979 _(sw_interface_span_dump, "")                                           \
18980 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
18981 _(pg_create_interface, "if_id <nn>")                                    \
18982 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
18983 _(pg_enable_disable, "[stream <id>] disable")                           \
18984 _(ip_source_and_port_range_check_add_del,                               \
18985   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
18986 _(ip_source_and_port_range_check_interface_add_del,                     \
18987   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
18988   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
18989 _(ipsec_gre_add_del_tunnel,                                             \
18990   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
18991 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
18992 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
18993 _(l2_interface_pbb_tag_rewrite,                                         \
18994   "<intfc> | sw_if_index <nn> \n"                                       \
18995   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
18996   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
18997 _(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
18998 _(flow_classify_set_interface,                                          \
18999   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
19000 _(flow_classify_dump, "type [ip4|ip6]")                                 \
19001 _(ip_fib_dump, "")                                                      \
19002 _(ip_mfib_dump, "")                                                     \
19003 _(ip6_fib_dump, "")                                                     \
19004 _(ip6_mfib_dump, "")                                                    \
19005 _(feature_enable_disable, "arc_name <arc_name> "                        \
19006   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
19007 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
19008 "[disable]")                                                            \
19009 _(l2_xconnect_dump, "")                                                 \
19010 _(sw_interface_set_mtu, "<intfc> | sw_if_index <nn> mtu <nn>")        \
19011 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
19012 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")
19013
19014 /* List of command functions, CLI names map directly to functions */
19015 #define foreach_cli_function                                    \
19016 _(comment, "usage: comment <ignore-rest-of-line>")              \
19017 _(dump_interface_table, "usage: dump_interface_table")          \
19018 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
19019 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
19020 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
19021 _(dump_stats_table, "usage: dump_stats_table")                  \
19022 _(dump_macro_table, "usage: dump_macro_table ")                 \
19023 _(dump_node_table, "usage: dump_node_table")                    \
19024 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
19025 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
19026 _(echo, "usage: echo <message>")                                \
19027 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
19028 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
19029 _(help, "usage: help")                                          \
19030 _(q, "usage: quit")                                             \
19031 _(quit, "usage: quit")                                          \
19032 _(search_node_table, "usage: search_node_table <name>...")      \
19033 _(set, "usage: set <variable-name> <value>")                    \
19034 _(script, "usage: script <file-name>")                          \
19035 _(unset, "usage: unset <variable-name>")
19036
19037 #define _(N,n)                                  \
19038     static void vl_api_##n##_t_handler_uni      \
19039     (vl_api_##n##_t * mp)                       \
19040     {                                           \
19041         vat_main_t * vam = &vat_main;           \
19042         if (vam->json_output) {                 \
19043             vl_api_##n##_t_handler_json(mp);    \
19044         } else {                                \
19045             vl_api_##n##_t_handler(mp);         \
19046         }                                       \
19047     }
19048 foreach_vpe_api_reply_msg;
19049 #if VPP_API_TEST_BUILTIN == 0
19050 foreach_standalone_reply_msg;
19051 #endif
19052 #undef _
19053
19054 void
19055 vat_api_hookup (vat_main_t * vam)
19056 {
19057 #define _(N,n)                                                  \
19058     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
19059                            vl_api_##n##_t_handler_uni,          \
19060                            vl_noop_handler,                     \
19061                            vl_api_##n##_t_endian,               \
19062                            vl_api_##n##_t_print,                \
19063                            sizeof(vl_api_##n##_t), 1);
19064   foreach_vpe_api_reply_msg;
19065 #if VPP_API_TEST_BUILTIN == 0
19066   foreach_standalone_reply_msg;
19067 #endif
19068 #undef _
19069
19070 #if (VPP_API_TEST_BUILTIN==0)
19071   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
19072
19073   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
19074
19075   vam->function_by_name = hash_create_string (0, sizeof (uword));
19076
19077   vam->help_by_name = hash_create_string (0, sizeof (uword));
19078 #endif
19079
19080   /* API messages we can send */
19081 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
19082   foreach_vpe_api_msg;
19083 #undef _
19084
19085   /* Help strings */
19086 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
19087   foreach_vpe_api_msg;
19088 #undef _
19089
19090   /* CLI functions */
19091 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
19092   foreach_cli_function;
19093 #undef _
19094
19095   /* Help strings */
19096 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
19097   foreach_cli_function;
19098 #undef _
19099 }
19100
19101 #if VPP_API_TEST_BUILTIN
19102 static clib_error_t *
19103 vat_api_hookup_shim (vlib_main_t * vm)
19104 {
19105   vat_api_hookup (&vat_main);
19106   return 0;
19107 }
19108
19109 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
19110 #endif
19111
19112 /*
19113  * fd.io coding-style-patch-verification: ON
19114  *
19115  * Local Variables:
19116  * eval: (c-set-style "gnu")
19117  * End:
19118  */