GRE over IPv6
[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 _(ip_add_del_route_reply)                               \
4155 _(ip_mroute_add_del_reply)                              \
4156 _(mpls_route_add_del_reply)                             \
4157 _(mpls_ip_bind_unbind_reply)                            \
4158 _(proxy_arp_add_del_reply)                              \
4159 _(proxy_arp_intfc_enable_disable_reply)                 \
4160 _(sw_interface_set_unnumbered_reply)                    \
4161 _(ip_neighbor_add_del_reply)                            \
4162 _(reset_vrf_reply)                                      \
4163 _(oam_add_del_reply)                                    \
4164 _(reset_fib_reply)                                      \
4165 _(dhcp_proxy_config_reply)                              \
4166 _(dhcp_proxy_set_vss_reply)                             \
4167 _(dhcp_client_config_reply)                             \
4168 _(set_ip_flow_hash_reply)                               \
4169 _(sw_interface_ip6_enable_disable_reply)                \
4170 _(sw_interface_ip6_set_link_local_address_reply)        \
4171 _(ip6nd_proxy_add_del_reply)                            \
4172 _(sw_interface_ip6nd_ra_prefix_reply)                   \
4173 _(sw_interface_ip6nd_ra_config_reply)                   \
4174 _(set_arp_neighbor_limit_reply)                         \
4175 _(l2_patch_add_del_reply)                               \
4176 _(sr_policy_add_reply)                                  \
4177 _(sr_policy_mod_reply)                                  \
4178 _(sr_policy_del_reply)                                  \
4179 _(sr_localsid_add_del_reply)                            \
4180 _(sr_steering_add_del_reply)                            \
4181 _(classify_add_del_session_reply)                       \
4182 _(classify_set_interface_ip_table_reply)                \
4183 _(classify_set_interface_l2_tables_reply)               \
4184 _(l2tpv3_set_tunnel_cookies_reply)                      \
4185 _(l2tpv3_interface_enable_disable_reply)                \
4186 _(l2tpv3_set_lookup_key_reply)                          \
4187 _(l2_fib_clear_table_reply)                             \
4188 _(l2_interface_efp_filter_reply)                        \
4189 _(l2_interface_vlan_tag_rewrite_reply)                  \
4190 _(modify_vhost_user_if_reply)                           \
4191 _(delete_vhost_user_if_reply)                           \
4192 _(want_ip4_arp_events_reply)                            \
4193 _(want_ip6_nd_events_reply)                             \
4194 _(input_acl_set_interface_reply)                        \
4195 _(ipsec_spd_add_del_reply)                              \
4196 _(ipsec_interface_add_del_spd_reply)                    \
4197 _(ipsec_spd_add_del_entry_reply)                        \
4198 _(ipsec_sad_add_del_entry_reply)                        \
4199 _(ipsec_sa_set_key_reply)                               \
4200 _(ikev2_profile_add_del_reply)                          \
4201 _(ikev2_profile_set_auth_reply)                         \
4202 _(ikev2_profile_set_id_reply)                           \
4203 _(ikev2_profile_set_ts_reply)                           \
4204 _(ikev2_set_local_key_reply)                            \
4205 _(ikev2_set_responder_reply)                            \
4206 _(ikev2_set_ike_transforms_reply)                       \
4207 _(ikev2_set_esp_transforms_reply)                       \
4208 _(ikev2_set_sa_lifetime_reply)                          \
4209 _(ikev2_initiate_sa_init_reply)                         \
4210 _(ikev2_initiate_del_ike_sa_reply)                      \
4211 _(ikev2_initiate_del_child_sa_reply)                    \
4212 _(ikev2_initiate_rekey_child_sa_reply)                  \
4213 _(delete_loopback_reply)                                \
4214 _(bd_ip_mac_add_del_reply)                              \
4215 _(map_del_domain_reply)                                 \
4216 _(map_add_del_rule_reply)                               \
4217 _(want_interface_events_reply)                          \
4218 _(want_stats_reply)                                     \
4219 _(cop_interface_enable_disable_reply)                   \
4220 _(cop_whitelist_enable_disable_reply)                   \
4221 _(sw_interface_clear_stats_reply)                       \
4222 _(ioam_enable_reply)                              \
4223 _(ioam_disable_reply)                              \
4224 _(one_add_del_locator_reply)                            \
4225 _(one_add_del_local_eid_reply)                          \
4226 _(one_add_del_remote_mapping_reply)                     \
4227 _(one_add_del_adjacency_reply)                          \
4228 _(one_add_del_map_resolver_reply)                       \
4229 _(one_add_del_map_server_reply)                         \
4230 _(one_enable_disable_reply)                             \
4231 _(one_rloc_probe_enable_disable_reply)                  \
4232 _(one_map_register_enable_disable_reply)                \
4233 _(one_pitr_set_locator_set_reply)                       \
4234 _(one_map_request_mode_reply)                           \
4235 _(one_add_del_map_request_itr_rlocs_reply)              \
4236 _(one_eid_table_add_del_map_reply)                      \
4237 _(one_use_petr_reply)                                   \
4238 _(one_stats_enable_disable_reply)                       \
4239 _(gpe_add_del_fwd_entry_reply)                          \
4240 _(gpe_enable_disable_reply)                             \
4241 _(gpe_set_encap_mode_reply)                             \
4242 _(gpe_add_del_iface_reply)                              \
4243 _(vxlan_gpe_add_del_tunnel_reply)                       \
4244 _(af_packet_delete_reply)                               \
4245 _(policer_classify_set_interface_reply)                 \
4246 _(netmap_create_reply)                                  \
4247 _(netmap_delete_reply)                                  \
4248 _(set_ipfix_exporter_reply)                             \
4249 _(set_ipfix_classify_stream_reply)                      \
4250 _(ipfix_classify_table_add_del_reply)                   \
4251 _(flow_classify_set_interface_reply)                    \
4252 _(sw_interface_span_enable_disable_reply)               \
4253 _(pg_capture_reply)                                     \
4254 _(pg_enable_disable_reply)                              \
4255 _(ip_source_and_port_range_check_add_del_reply)         \
4256 _(ip_source_and_port_range_check_interface_add_del_reply)\
4257 _(delete_subif_reply)                                   \
4258 _(l2_interface_pbb_tag_rewrite_reply)                   \
4259 _(punt_reply)                                           \
4260 _(feature_enable_disable_reply)                         \
4261 _(sw_interface_tag_add_del_reply)                       \
4262 _(sw_interface_set_mtu_reply)
4263
4264 #define _(n)                                    \
4265     static void vl_api_##n##_t_handler          \
4266     (vl_api_##n##_t * mp)                       \
4267     {                                           \
4268         vat_main_t * vam = &vat_main;           \
4269         i32 retval = ntohl(mp->retval);         \
4270         if (vam->async_mode) {                  \
4271             vam->async_errors += (retval < 0);  \
4272         } else {                                \
4273             vam->retval = retval;               \
4274             vam->result_ready = 1;              \
4275         }                                       \
4276     }
4277 foreach_standard_reply_retval_handler;
4278 #undef _
4279
4280 #define _(n)                                    \
4281     static void vl_api_##n##_t_handler_json     \
4282     (vl_api_##n##_t * mp)                       \
4283     {                                           \
4284         vat_main_t * vam = &vat_main;           \
4285         vat_json_node_t node;                   \
4286         vat_json_init_object(&node);            \
4287         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
4288         vat_json_print(vam->ofp, &node);        \
4289         vam->retval = ntohl(mp->retval);        \
4290         vam->result_ready = 1;                  \
4291     }
4292 foreach_standard_reply_retval_handler;
4293 #undef _
4294
4295 /*
4296  * Table of message reply handlers, must include boilerplate handlers
4297  * we just generated
4298  */
4299
4300 #define foreach_vpe_api_reply_msg                                       \
4301 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
4302 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
4303 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
4304 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
4305 _(CONTROL_PING_REPLY, control_ping_reply)                               \
4306 _(CLI_REPLY, cli_reply)                                                 \
4307 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
4308 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
4309   sw_interface_add_del_address_reply)                                   \
4310 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
4311 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
4312 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
4313 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
4314 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
4315   sw_interface_set_l2_xconnect_reply)                                   \
4316 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
4317   sw_interface_set_l2_bridge_reply)                                     \
4318 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
4319 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
4320 _(BRIDGE_DOMAIN_SW_IF_DETAILS, bridge_domain_sw_if_details)             \
4321 _(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply)     \
4322 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
4323 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
4324 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
4325 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
4326 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
4327 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
4328 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
4329 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
4330 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
4331 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
4332 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
4333 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
4334 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
4335   proxy_arp_intfc_enable_disable_reply)                                 \
4336 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
4337 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
4338   sw_interface_set_unnumbered_reply)                                    \
4339 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
4340 _(RESET_VRF_REPLY, reset_vrf_reply)                                     \
4341 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
4342 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
4343 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
4344 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
4345 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
4346 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
4347 _(DHCP_PROXY_DETAILS, dhcp_proxy_details)                               \
4348 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
4349 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
4350 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
4351   sw_interface_ip6_enable_disable_reply)                                \
4352 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY,                        \
4353   sw_interface_ip6_set_link_local_address_reply)                        \
4354 _(IP6ND_PROXY_ADD_DEL_REPLY, ip6nd_proxy_add_del_reply)                 \
4355 _(IP6ND_PROXY_DETAILS, ip6nd_proxy_details)                             \
4356 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
4357   sw_interface_ip6nd_ra_prefix_reply)                                   \
4358 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
4359   sw_interface_ip6nd_ra_config_reply)                                   \
4360 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
4361 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
4362 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
4363 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
4364 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
4365 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
4366 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
4367 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
4368 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
4369 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
4370 classify_set_interface_ip_table_reply)                                  \
4371 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
4372   classify_set_interface_l2_tables_reply)                               \
4373 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
4374 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
4375 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
4376 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
4377 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
4378   l2tpv3_interface_enable_disable_reply)                                \
4379 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
4380 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
4381 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
4382 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
4383 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
4384 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
4385 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
4386 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
4387 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
4388 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
4389 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
4390 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
4391 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
4392 _(SHOW_VERSION_REPLY, show_version_reply)                               \
4393 _(L2_FIB_TABLE_ENTRY, l2_fib_table_entry)                               \
4394 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)           \
4395 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
4396 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
4397 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
4398 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
4399 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
4400 _(IP6_ND_EVENT, ip6_nd_event)                                           \
4401 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
4402 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
4403 _(IP_DETAILS, ip_details)                                               \
4404 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
4405 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
4406 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
4407 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
4408 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
4409 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
4410 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
4411 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
4412 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
4413 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
4414 _(IKEV2_SET_RESPONDER_REPLY, ikev2_set_responder_reply)                 \
4415 _(IKEV2_SET_IKE_TRANSFORMS_REPLY, ikev2_set_ike_transforms_reply)       \
4416 _(IKEV2_SET_ESP_TRANSFORMS_REPLY, ikev2_set_esp_transforms_reply)       \
4417 _(IKEV2_SET_SA_LIFETIME_REPLY, ikev2_set_sa_lifetime_reply)             \
4418 _(IKEV2_INITIATE_SA_INIT_REPLY, ikev2_initiate_sa_init_reply)           \
4419 _(IKEV2_INITIATE_DEL_IKE_SA_REPLY, ikev2_initiate_del_ike_sa_reply)     \
4420 _(IKEV2_INITIATE_DEL_CHILD_SA_REPLY, ikev2_initiate_del_child_sa_reply) \
4421 _(IKEV2_INITIATE_REKEY_CHILD_SA_REPLY, ikev2_initiate_rekey_child_sa_reply) \
4422 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
4423 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
4424 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
4425 _(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply)                           \
4426 _(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply)                           \
4427 _(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply)                       \
4428 _(MAP_DOMAIN_DETAILS, map_domain_details)                               \
4429 _(MAP_RULE_DETAILS, map_rule_details)                                   \
4430 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
4431 _(WANT_STATS_REPLY, want_stats_reply)                                   \
4432 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
4433 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
4434 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
4435 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
4436 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
4437 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
4438 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
4439 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
4440 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
4441 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
4442 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
4443 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
4444 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
4445 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
4446 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
4447 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
4448   one_map_register_enable_disable_reply)                                \
4449 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
4450   one_rloc_probe_enable_disable_reply)                                  \
4451 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
4452 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
4453 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
4454 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
4455 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
4456 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
4457 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
4458 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
4459 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
4460 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
4461 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
4462 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
4463 _(ONE_STATS_DETAILS, one_stats_details)                                 \
4464 _(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply)       \
4465 _(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,                                  \
4466   show_one_stats_enable_disable_reply)                                  \
4467 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
4468 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
4469 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
4470 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
4471 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
4472 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
4473 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
4474   gpe_fwd_entry_path_details)                                           \
4475 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
4476 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
4477   one_add_del_map_request_itr_rlocs_reply)                              \
4478 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
4479   one_get_map_request_itr_rlocs_reply)                                  \
4480 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
4481 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
4482 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
4483 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
4484 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
4485   show_one_map_register_state_reply)                                    \
4486 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
4487 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
4488 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
4489 _(POLICER_DETAILS, policer_details)                                     \
4490 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
4491 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
4492 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
4493 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
4494 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
4495 _(MPLS_FIB_DETAILS, mpls_fib_details)                                   \
4496 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
4497 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
4498 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
4499 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
4500 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
4501 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
4502 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
4503 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
4504 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
4505 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
4506 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
4507 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
4508 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
4509 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
4510 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
4511 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
4512 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
4513 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
4514 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
4515  ip_source_and_port_range_check_add_del_reply)                          \
4516 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
4517  ip_source_and_port_range_check_interface_add_del_reply)                \
4518 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
4519 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
4520 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
4521 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
4522 _(PUNT_REPLY, punt_reply)                                               \
4523 _(IP_FIB_DETAILS, ip_fib_details)                                       \
4524 _(IP6_FIB_DETAILS, ip6_fib_details)                                     \
4525 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
4526 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
4527 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
4528 _(SW_INTERFACE_SET_MTU_REPLY, sw_interface_set_mtu_reply)               \
4529 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
4530 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)
4531
4532 #define foreach_standalone_reply_msg                                    \
4533 _(SW_INTERFACE_SET_FLAGS, sw_interface_set_flags)                       \
4534 _(VNET_INTERFACE_COUNTERS, vnet_interface_counters)                     \
4535 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
4536 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
4537 _(VNET_IP4_NBR_COUNTERS, vnet_ip4_nbr_counters)                         \
4538 _(VNET_IP6_NBR_COUNTERS, vnet_ip6_nbr_counters)
4539
4540 typedef struct
4541 {
4542   u8 *name;
4543   u32 value;
4544 } name_sort_t;
4545
4546
4547 #define STR_VTR_OP_CASE(op)     \
4548     case L2_VTR_ ## op:         \
4549         return "" # op;
4550
4551 static const char *
4552 str_vtr_op (u32 vtr_op)
4553 {
4554   switch (vtr_op)
4555     {
4556       STR_VTR_OP_CASE (DISABLED);
4557       STR_VTR_OP_CASE (PUSH_1);
4558       STR_VTR_OP_CASE (PUSH_2);
4559       STR_VTR_OP_CASE (POP_1);
4560       STR_VTR_OP_CASE (POP_2);
4561       STR_VTR_OP_CASE (TRANSLATE_1_1);
4562       STR_VTR_OP_CASE (TRANSLATE_1_2);
4563       STR_VTR_OP_CASE (TRANSLATE_2_1);
4564       STR_VTR_OP_CASE (TRANSLATE_2_2);
4565     }
4566
4567   return "UNKNOWN";
4568 }
4569
4570 static int
4571 dump_sub_interface_table (vat_main_t * vam)
4572 {
4573   const sw_interface_subif_t *sub = NULL;
4574
4575   if (vam->json_output)
4576     {
4577       clib_warning
4578         ("JSON output supported only for VPE API calls and dump_stats_table");
4579       return -99;
4580     }
4581
4582   print (vam->ofp,
4583          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
4584          "Interface", "sw_if_index",
4585          "sub id", "dot1ad", "tags", "outer id",
4586          "inner id", "exact", "default", "outer any", "inner any");
4587
4588   vec_foreach (sub, vam->sw_if_subif_table)
4589   {
4590     print (vam->ofp,
4591            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
4592            sub->interface_name,
4593            sub->sw_if_index,
4594            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
4595            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
4596            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
4597            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
4598     if (sub->vtr_op != L2_VTR_DISABLED)
4599       {
4600         print (vam->ofp,
4601                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
4602                "tag1: %d tag2: %d ]",
4603                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
4604                sub->vtr_tag1, sub->vtr_tag2);
4605       }
4606   }
4607
4608   return 0;
4609 }
4610
4611 static int
4612 name_sort_cmp (void *a1, void *a2)
4613 {
4614   name_sort_t *n1 = a1;
4615   name_sort_t *n2 = a2;
4616
4617   return strcmp ((char *) n1->name, (char *) n2->name);
4618 }
4619
4620 static int
4621 dump_interface_table (vat_main_t * vam)
4622 {
4623   hash_pair_t *p;
4624   name_sort_t *nses = 0, *ns;
4625
4626   if (vam->json_output)
4627     {
4628       clib_warning
4629         ("JSON output supported only for VPE API calls and dump_stats_table");
4630       return -99;
4631     }
4632
4633   /* *INDENT-OFF* */
4634   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
4635   ({
4636     vec_add2 (nses, ns, 1);
4637     ns->name = (u8 *)(p->key);
4638     ns->value = (u32) p->value[0];
4639   }));
4640   /* *INDENT-ON* */
4641
4642   vec_sort_with_function (nses, name_sort_cmp);
4643
4644   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
4645   vec_foreach (ns, nses)
4646   {
4647     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
4648   }
4649   vec_free (nses);
4650   return 0;
4651 }
4652
4653 static int
4654 dump_ip_table (vat_main_t * vam, int is_ipv6)
4655 {
4656   const ip_details_t *det = NULL;
4657   const ip_address_details_t *address = NULL;
4658   u32 i = ~0;
4659
4660   print (vam->ofp, "%-12s", "sw_if_index");
4661
4662   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
4663   {
4664     i++;
4665     if (!det->present)
4666       {
4667         continue;
4668       }
4669     print (vam->ofp, "%-12d", i);
4670     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
4671     if (!det->addr)
4672       {
4673         continue;
4674       }
4675     vec_foreach (address, det->addr)
4676     {
4677       print (vam->ofp,
4678              "            %-30U%-13d",
4679              is_ipv6 ? format_ip6_address : format_ip4_address,
4680              address->ip, address->prefix_length);
4681     }
4682   }
4683
4684   return 0;
4685 }
4686
4687 static int
4688 dump_ipv4_table (vat_main_t * vam)
4689 {
4690   if (vam->json_output)
4691     {
4692       clib_warning
4693         ("JSON output supported only for VPE API calls and dump_stats_table");
4694       return -99;
4695     }
4696
4697   return dump_ip_table (vam, 0);
4698 }
4699
4700 static int
4701 dump_ipv6_table (vat_main_t * vam)
4702 {
4703   if (vam->json_output)
4704     {
4705       clib_warning
4706         ("JSON output supported only for VPE API calls and dump_stats_table");
4707       return -99;
4708     }
4709
4710   return dump_ip_table (vam, 1);
4711 }
4712
4713 static char *
4714 counter_type_to_str (u8 counter_type, u8 is_combined)
4715 {
4716   if (!is_combined)
4717     {
4718       switch (counter_type)
4719         {
4720         case VNET_INTERFACE_COUNTER_DROP:
4721           return "drop";
4722         case VNET_INTERFACE_COUNTER_PUNT:
4723           return "punt";
4724         case VNET_INTERFACE_COUNTER_IP4:
4725           return "ip4";
4726         case VNET_INTERFACE_COUNTER_IP6:
4727           return "ip6";
4728         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
4729           return "rx-no-buf";
4730         case VNET_INTERFACE_COUNTER_RX_MISS:
4731           return "rx-miss";
4732         case VNET_INTERFACE_COUNTER_RX_ERROR:
4733           return "rx-error";
4734         case VNET_INTERFACE_COUNTER_TX_ERROR:
4735           return "tx-error";
4736         default:
4737           return "INVALID-COUNTER-TYPE";
4738         }
4739     }
4740   else
4741     {
4742       switch (counter_type)
4743         {
4744         case VNET_INTERFACE_COUNTER_RX:
4745           return "rx";
4746         case VNET_INTERFACE_COUNTER_TX:
4747           return "tx";
4748         default:
4749           return "INVALID-COUNTER-TYPE";
4750         }
4751     }
4752 }
4753
4754 static int
4755 dump_stats_table (vat_main_t * vam)
4756 {
4757   vat_json_node_t node;
4758   vat_json_node_t *msg_array;
4759   vat_json_node_t *msg;
4760   vat_json_node_t *counter_array;
4761   vat_json_node_t *counter;
4762   interface_counter_t c;
4763   u64 packets;
4764   ip4_fib_counter_t *c4;
4765   ip6_fib_counter_t *c6;
4766   ip4_nbr_counter_t *n4;
4767   ip6_nbr_counter_t *n6;
4768   int i, j;
4769
4770   if (!vam->json_output)
4771     {
4772       clib_warning ("dump_stats_table supported only in JSON format");
4773       return -99;
4774     }
4775
4776   vat_json_init_object (&node);
4777
4778   /* interface counters */
4779   msg_array = vat_json_object_add (&node, "interface_counters");
4780   vat_json_init_array (msg_array);
4781   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
4782     {
4783       msg = vat_json_array_add (msg_array);
4784       vat_json_init_object (msg);
4785       vat_json_object_add_string_copy (msg, "vnet_counter_type",
4786                                        (u8 *) counter_type_to_str (i, 0));
4787       vat_json_object_add_int (msg, "is_combined", 0);
4788       counter_array = vat_json_object_add (msg, "data");
4789       vat_json_init_array (counter_array);
4790       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
4791         {
4792           packets = vam->simple_interface_counters[i][j];
4793           vat_json_array_add_uint (counter_array, packets);
4794         }
4795     }
4796   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
4797     {
4798       msg = vat_json_array_add (msg_array);
4799       vat_json_init_object (msg);
4800       vat_json_object_add_string_copy (msg, "vnet_counter_type",
4801                                        (u8 *) counter_type_to_str (i, 1));
4802       vat_json_object_add_int (msg, "is_combined", 1);
4803       counter_array = vat_json_object_add (msg, "data");
4804       vat_json_init_array (counter_array);
4805       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
4806         {
4807           c = vam->combined_interface_counters[i][j];
4808           counter = vat_json_array_add (counter_array);
4809           vat_json_init_object (counter);
4810           vat_json_object_add_uint (counter, "packets", c.packets);
4811           vat_json_object_add_uint (counter, "bytes", c.bytes);
4812         }
4813     }
4814
4815   /* ip4 fib counters */
4816   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
4817   vat_json_init_array (msg_array);
4818   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
4819     {
4820       msg = vat_json_array_add (msg_array);
4821       vat_json_init_object (msg);
4822       vat_json_object_add_uint (msg, "vrf_id",
4823                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
4824       counter_array = vat_json_object_add (msg, "c");
4825       vat_json_init_array (counter_array);
4826       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
4827         {
4828           counter = vat_json_array_add (counter_array);
4829           vat_json_init_object (counter);
4830           c4 = &vam->ip4_fib_counters[i][j];
4831           vat_json_object_add_ip4 (counter, "address", c4->address);
4832           vat_json_object_add_uint (counter, "address_length",
4833                                     c4->address_length);
4834           vat_json_object_add_uint (counter, "packets", c4->packets);
4835           vat_json_object_add_uint (counter, "bytes", c4->bytes);
4836         }
4837     }
4838
4839   /* ip6 fib counters */
4840   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
4841   vat_json_init_array (msg_array);
4842   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
4843     {
4844       msg = vat_json_array_add (msg_array);
4845       vat_json_init_object (msg);
4846       vat_json_object_add_uint (msg, "vrf_id",
4847                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
4848       counter_array = vat_json_object_add (msg, "c");
4849       vat_json_init_array (counter_array);
4850       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
4851         {
4852           counter = vat_json_array_add (counter_array);
4853           vat_json_init_object (counter);
4854           c6 = &vam->ip6_fib_counters[i][j];
4855           vat_json_object_add_ip6 (counter, "address", c6->address);
4856           vat_json_object_add_uint (counter, "address_length",
4857                                     c6->address_length);
4858           vat_json_object_add_uint (counter, "packets", c6->packets);
4859           vat_json_object_add_uint (counter, "bytes", c6->bytes);
4860         }
4861     }
4862
4863   /* ip4 nbr counters */
4864   msg_array = vat_json_object_add (&node, "ip4_nbr_counters");
4865   vat_json_init_array (msg_array);
4866   for (i = 0; i < vec_len (vam->ip4_nbr_counters); i++)
4867     {
4868       msg = vat_json_array_add (msg_array);
4869       vat_json_init_object (msg);
4870       vat_json_object_add_uint (msg, "sw_if_index", i);
4871       counter_array = vat_json_object_add (msg, "c");
4872       vat_json_init_array (counter_array);
4873       for (j = 0; j < vec_len (vam->ip4_nbr_counters[i]); j++)
4874         {
4875           counter = vat_json_array_add (counter_array);
4876           vat_json_init_object (counter);
4877           n4 = &vam->ip4_nbr_counters[i][j];
4878           vat_json_object_add_ip4 (counter, "address", n4->address);
4879           vat_json_object_add_uint (counter, "link-type", n4->linkt);
4880           vat_json_object_add_uint (counter, "packets", n4->packets);
4881           vat_json_object_add_uint (counter, "bytes", n4->bytes);
4882         }
4883     }
4884
4885   /* ip6 nbr counters */
4886   msg_array = vat_json_object_add (&node, "ip6_nbr_counters");
4887   vat_json_init_array (msg_array);
4888   for (i = 0; i < vec_len (vam->ip6_nbr_counters); i++)
4889     {
4890       msg = vat_json_array_add (msg_array);
4891       vat_json_init_object (msg);
4892       vat_json_object_add_uint (msg, "sw_if_index", i);
4893       counter_array = vat_json_object_add (msg, "c");
4894       vat_json_init_array (counter_array);
4895       for (j = 0; j < vec_len (vam->ip6_nbr_counters[i]); j++)
4896         {
4897           counter = vat_json_array_add (counter_array);
4898           vat_json_init_object (counter);
4899           n6 = &vam->ip6_nbr_counters[i][j];
4900           vat_json_object_add_ip6 (counter, "address", n6->address);
4901           vat_json_object_add_uint (counter, "packets", n6->packets);
4902           vat_json_object_add_uint (counter, "bytes", n6->bytes);
4903         }
4904     }
4905
4906   vat_json_print (vam->ofp, &node);
4907   vat_json_free (&node);
4908
4909   return 0;
4910 }
4911
4912 int
4913 exec (vat_main_t * vam)
4914 {
4915   api_main_t *am = &api_main;
4916   vl_api_cli_request_t *mp;
4917   f64 timeout;
4918   void *oldheap;
4919   u8 *cmd = 0;
4920   unformat_input_t *i = vam->input;
4921
4922   if (vec_len (i->buffer) == 0)
4923     return -1;
4924
4925   if (vam->exec_mode == 0 && unformat (i, "mode"))
4926     {
4927       vam->exec_mode = 1;
4928       return 0;
4929     }
4930   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4931     {
4932       vam->exec_mode = 0;
4933       return 0;
4934     }
4935
4936
4937   M (CLI_REQUEST, mp);
4938
4939   /*
4940    * Copy cmd into shared memory.
4941    * In order for the CLI command to work, it
4942    * must be a vector ending in \n, not a C-string ending
4943    * in \n\0.
4944    */
4945   pthread_mutex_lock (&am->vlib_rp->mutex);
4946   oldheap = svm_push_data_heap (am->vlib_rp);
4947
4948   vec_validate (cmd, vec_len (vam->input->buffer) - 1);
4949   clib_memcpy (cmd, vam->input->buffer, vec_len (vam->input->buffer));
4950
4951   svm_pop_heap (oldheap);
4952   pthread_mutex_unlock (&am->vlib_rp->mutex);
4953
4954   mp->cmd_in_shmem = (u64) cmd;
4955   S (mp);
4956   timeout = vat_time_now (vam) + 10.0;
4957
4958   while (vat_time_now (vam) < timeout)
4959     {
4960       if (vam->result_ready == 1)
4961         {
4962           u8 *free_me;
4963           if (vam->shmem_result != NULL)
4964             print (vam->ofp, "%s", vam->shmem_result);
4965           pthread_mutex_lock (&am->vlib_rp->mutex);
4966           oldheap = svm_push_data_heap (am->vlib_rp);
4967
4968           free_me = (u8 *) vam->shmem_result;
4969           vec_free (free_me);
4970
4971           svm_pop_heap (oldheap);
4972           pthread_mutex_unlock (&am->vlib_rp->mutex);
4973           return 0;
4974         }
4975     }
4976   return -99;
4977 }
4978
4979 /*
4980  * Future replacement of exec() that passes CLI buffers directly in
4981  * the API messages instead of an additional shared memory area.
4982  */
4983 static int
4984 exec_inband (vat_main_t * vam)
4985 {
4986   vl_api_cli_inband_t *mp;
4987   unformat_input_t *i = vam->input;
4988   int ret;
4989
4990   if (vec_len (i->buffer) == 0)
4991     return -1;
4992
4993   if (vam->exec_mode == 0 && unformat (i, "mode"))
4994     {
4995       vam->exec_mode = 1;
4996       return 0;
4997     }
4998   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4999     {
5000       vam->exec_mode = 0;
5001       return 0;
5002     }
5003
5004   /*
5005    * In order for the CLI command to work, it
5006    * must be a vector ending in \n, not a C-string ending
5007    * in \n\0.
5008    */
5009   u32 len = vec_len (vam->input->buffer);
5010   M2 (CLI_INBAND, mp, len);
5011   clib_memcpy (mp->cmd, vam->input->buffer, len);
5012   mp->length = htonl (len);
5013
5014   S (mp);
5015   W2 (ret, print (vam->ofp, "%s", vam->cmd_reply));
5016   return ret;
5017 }
5018
5019 static int
5020 api_create_loopback (vat_main_t * vam)
5021 {
5022   unformat_input_t *i = vam->input;
5023   vl_api_create_loopback_t *mp;
5024   vl_api_create_loopback_instance_t *mp_lbi;
5025   u8 mac_address[6];
5026   u8 mac_set = 0;
5027   u8 is_specified = 0;
5028   u32 user_instance = 0;
5029   int ret;
5030
5031   memset (mac_address, 0, sizeof (mac_address));
5032
5033   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5034     {
5035       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5036         mac_set = 1;
5037       if (unformat (i, "instance %d", &user_instance))
5038         is_specified = 1;
5039       else
5040         break;
5041     }
5042
5043   if (is_specified)
5044     {
5045       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
5046       mp_lbi->is_specified = is_specified;
5047       if (is_specified)
5048         mp_lbi->user_instance = htonl (user_instance);
5049       if (mac_set)
5050         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
5051       S (mp_lbi);
5052     }
5053   else
5054     {
5055       /* Construct the API message */
5056       M (CREATE_LOOPBACK, mp);
5057       if (mac_set)
5058         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
5059       S (mp);
5060     }
5061
5062   W (ret);
5063   return ret;
5064 }
5065
5066 static int
5067 api_delete_loopback (vat_main_t * vam)
5068 {
5069   unformat_input_t *i = vam->input;
5070   vl_api_delete_loopback_t *mp;
5071   u32 sw_if_index = ~0;
5072   int ret;
5073
5074   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5075     {
5076       if (unformat (i, "sw_if_index %d", &sw_if_index))
5077         ;
5078       else
5079         break;
5080     }
5081
5082   if (sw_if_index == ~0)
5083     {
5084       errmsg ("missing sw_if_index");
5085       return -99;
5086     }
5087
5088   /* Construct the API message */
5089   M (DELETE_LOOPBACK, mp);
5090   mp->sw_if_index = ntohl (sw_if_index);
5091
5092   S (mp);
5093   W (ret);
5094   return ret;
5095 }
5096
5097 static int
5098 api_want_stats (vat_main_t * vam)
5099 {
5100   unformat_input_t *i = vam->input;
5101   vl_api_want_stats_t *mp;
5102   int enable = -1;
5103   int ret;
5104
5105   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5106     {
5107       if (unformat (i, "enable"))
5108         enable = 1;
5109       else if (unformat (i, "disable"))
5110         enable = 0;
5111       else
5112         break;
5113     }
5114
5115   if (enable == -1)
5116     {
5117       errmsg ("missing enable|disable");
5118       return -99;
5119     }
5120
5121   M (WANT_STATS, mp);
5122   mp->enable_disable = enable;
5123
5124   S (mp);
5125   W (ret);
5126   return ret;
5127 }
5128
5129 static int
5130 api_want_interface_events (vat_main_t * vam)
5131 {
5132   unformat_input_t *i = vam->input;
5133   vl_api_want_interface_events_t *mp;
5134   int enable = -1;
5135   int ret;
5136
5137   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5138     {
5139       if (unformat (i, "enable"))
5140         enable = 1;
5141       else if (unformat (i, "disable"))
5142         enable = 0;
5143       else
5144         break;
5145     }
5146
5147   if (enable == -1)
5148     {
5149       errmsg ("missing enable|disable");
5150       return -99;
5151     }
5152
5153   M (WANT_INTERFACE_EVENTS, mp);
5154   mp->enable_disable = enable;
5155
5156   vam->interface_event_display = enable;
5157
5158   S (mp);
5159   W (ret);
5160   return ret;
5161 }
5162
5163
5164 /* Note: non-static, called once to set up the initial intfc table */
5165 int
5166 api_sw_interface_dump (vat_main_t * vam)
5167 {
5168   vl_api_sw_interface_dump_t *mp;
5169   vl_api_control_ping_t *mp_ping;
5170   hash_pair_t *p;
5171   name_sort_t *nses = 0, *ns;
5172   sw_interface_subif_t *sub = NULL;
5173   int ret;
5174
5175   /* Toss the old name table */
5176   /* *INDENT-OFF* */
5177   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5178   ({
5179     vec_add2 (nses, ns, 1);
5180     ns->name = (u8 *)(p->key);
5181     ns->value = (u32) p->value[0];
5182   }));
5183   /* *INDENT-ON* */
5184
5185   hash_free (vam->sw_if_index_by_interface_name);
5186
5187   vec_foreach (ns, nses) vec_free (ns->name);
5188
5189   vec_free (nses);
5190
5191   vec_foreach (sub, vam->sw_if_subif_table)
5192   {
5193     vec_free (sub->interface_name);
5194   }
5195   vec_free (vam->sw_if_subif_table);
5196
5197   /* recreate the interface name hash table */
5198   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
5199
5200   /* Get list of ethernets */
5201   M (SW_INTERFACE_DUMP, mp);
5202   mp->name_filter_valid = 1;
5203   strncpy ((char *) mp->name_filter, "Ether", sizeof (mp->name_filter) - 1);
5204   S (mp);
5205
5206   /* and local / loopback interfaces */
5207   M (SW_INTERFACE_DUMP, mp);
5208   mp->name_filter_valid = 1;
5209   strncpy ((char *) mp->name_filter, "lo", sizeof (mp->name_filter) - 1);
5210   S (mp);
5211
5212   /* and packet-generator interfaces */
5213   M (SW_INTERFACE_DUMP, mp);
5214   mp->name_filter_valid = 1;
5215   strncpy ((char *) mp->name_filter, "pg", sizeof (mp->name_filter) - 1);
5216   S (mp);
5217
5218   /* and vxlan-gpe tunnel interfaces */
5219   M (SW_INTERFACE_DUMP, mp);
5220   mp->name_filter_valid = 1;
5221   strncpy ((char *) mp->name_filter, "vxlan_gpe",
5222            sizeof (mp->name_filter) - 1);
5223   S (mp);
5224
5225   /* and vxlan tunnel interfaces */
5226   M (SW_INTERFACE_DUMP, mp);
5227   mp->name_filter_valid = 1;
5228   strncpy ((char *) mp->name_filter, "vxlan", sizeof (mp->name_filter) - 1);
5229   S (mp);
5230
5231   /* and host (af_packet) interfaces */
5232   M (SW_INTERFACE_DUMP, mp);
5233   mp->name_filter_valid = 1;
5234   strncpy ((char *) mp->name_filter, "host", sizeof (mp->name_filter) - 1);
5235   S (mp);
5236
5237   /* and l2tpv3 tunnel interfaces */
5238   M (SW_INTERFACE_DUMP, mp);
5239   mp->name_filter_valid = 1;
5240   strncpy ((char *) mp->name_filter, "l2tpv3_tunnel",
5241            sizeof (mp->name_filter) - 1);
5242   S (mp);
5243
5244   /* and GRE tunnel interfaces */
5245   M (SW_INTERFACE_DUMP, mp);
5246   mp->name_filter_valid = 1;
5247   strncpy ((char *) mp->name_filter, "gre", sizeof (mp->name_filter) - 1);
5248   S (mp);
5249
5250   /* and LISP-GPE interfaces */
5251   M (SW_INTERFACE_DUMP, mp);
5252   mp->name_filter_valid = 1;
5253   strncpy ((char *) mp->name_filter, "lisp_gpe",
5254            sizeof (mp->name_filter) - 1);
5255   S (mp);
5256
5257   /* and IPSEC tunnel interfaces */
5258   M (SW_INTERFACE_DUMP, mp);
5259   mp->name_filter_valid = 1;
5260   strncpy ((char *) mp->name_filter, "ipsec", sizeof (mp->name_filter) - 1);
5261   S (mp);
5262
5263   /* Use a control ping for synchronization */
5264   M (CONTROL_PING, mp_ping);
5265   S (mp_ping);
5266
5267   W (ret);
5268   return ret;
5269 }
5270
5271 static int
5272 api_sw_interface_set_flags (vat_main_t * vam)
5273 {
5274   unformat_input_t *i = vam->input;
5275   vl_api_sw_interface_set_flags_t *mp;
5276   u32 sw_if_index;
5277   u8 sw_if_index_set = 0;
5278   u8 admin_up = 0, link_up = 0;
5279   int ret;
5280
5281   /* Parse args required to build the message */
5282   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5283     {
5284       if (unformat (i, "admin-up"))
5285         admin_up = 1;
5286       else if (unformat (i, "admin-down"))
5287         admin_up = 0;
5288       else if (unformat (i, "link-up"))
5289         link_up = 1;
5290       else if (unformat (i, "link-down"))
5291         link_up = 0;
5292       else
5293         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5294         sw_if_index_set = 1;
5295       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5296         sw_if_index_set = 1;
5297       else
5298         break;
5299     }
5300
5301   if (sw_if_index_set == 0)
5302     {
5303       errmsg ("missing interface name or sw_if_index");
5304       return -99;
5305     }
5306
5307   /* Construct the API message */
5308   M (SW_INTERFACE_SET_FLAGS, mp);
5309   mp->sw_if_index = ntohl (sw_if_index);
5310   mp->admin_up_down = admin_up;
5311   mp->link_up_down = link_up;
5312
5313   /* send it... */
5314   S (mp);
5315
5316   /* Wait for a reply, return the good/bad news... */
5317   W (ret);
5318   return ret;
5319 }
5320
5321 static int
5322 api_sw_interface_clear_stats (vat_main_t * vam)
5323 {
5324   unformat_input_t *i = vam->input;
5325   vl_api_sw_interface_clear_stats_t *mp;
5326   u32 sw_if_index;
5327   u8 sw_if_index_set = 0;
5328   int ret;
5329
5330   /* Parse args required to build the message */
5331   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5332     {
5333       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5334         sw_if_index_set = 1;
5335       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5336         sw_if_index_set = 1;
5337       else
5338         break;
5339     }
5340
5341   /* Construct the API message */
5342   M (SW_INTERFACE_CLEAR_STATS, mp);
5343
5344   if (sw_if_index_set == 1)
5345     mp->sw_if_index = ntohl (sw_if_index);
5346   else
5347     mp->sw_if_index = ~0;
5348
5349   /* send it... */
5350   S (mp);
5351
5352   /* Wait for a reply, return the good/bad news... */
5353   W (ret);
5354   return ret;
5355 }
5356
5357 static int
5358 api_sw_interface_add_del_address (vat_main_t * vam)
5359 {
5360   unformat_input_t *i = vam->input;
5361   vl_api_sw_interface_add_del_address_t *mp;
5362   u32 sw_if_index;
5363   u8 sw_if_index_set = 0;
5364   u8 is_add = 1, del_all = 0;
5365   u32 address_length = 0;
5366   u8 v4_address_set = 0;
5367   u8 v6_address_set = 0;
5368   ip4_address_t v4address;
5369   ip6_address_t v6address;
5370   int ret;
5371
5372   /* Parse args required to build the message */
5373   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5374     {
5375       if (unformat (i, "del-all"))
5376         del_all = 1;
5377       else if (unformat (i, "del"))
5378         is_add = 0;
5379       else
5380         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5381         sw_if_index_set = 1;
5382       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5383         sw_if_index_set = 1;
5384       else if (unformat (i, "%U/%d",
5385                          unformat_ip4_address, &v4address, &address_length))
5386         v4_address_set = 1;
5387       else if (unformat (i, "%U/%d",
5388                          unformat_ip6_address, &v6address, &address_length))
5389         v6_address_set = 1;
5390       else
5391         break;
5392     }
5393
5394   if (sw_if_index_set == 0)
5395     {
5396       errmsg ("missing interface name or sw_if_index");
5397       return -99;
5398     }
5399   if (v4_address_set && v6_address_set)
5400     {
5401       errmsg ("both v4 and v6 addresses set");
5402       return -99;
5403     }
5404   if (!v4_address_set && !v6_address_set && !del_all)
5405     {
5406       errmsg ("no addresses set");
5407       return -99;
5408     }
5409
5410   /* Construct the API message */
5411   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
5412
5413   mp->sw_if_index = ntohl (sw_if_index);
5414   mp->is_add = is_add;
5415   mp->del_all = del_all;
5416   if (v6_address_set)
5417     {
5418       mp->is_ipv6 = 1;
5419       clib_memcpy (mp->address, &v6address, sizeof (v6address));
5420     }
5421   else
5422     {
5423       clib_memcpy (mp->address, &v4address, sizeof (v4address));
5424     }
5425   mp->address_length = address_length;
5426
5427   /* send it... */
5428   S (mp);
5429
5430   /* Wait for a reply, return good/bad news  */
5431   W (ret);
5432   return ret;
5433 }
5434
5435 static int
5436 api_sw_interface_set_mpls_enable (vat_main_t * vam)
5437 {
5438   unformat_input_t *i = vam->input;
5439   vl_api_sw_interface_set_mpls_enable_t *mp;
5440   u32 sw_if_index;
5441   u8 sw_if_index_set = 0;
5442   u8 enable = 1;
5443   int ret;
5444
5445   /* Parse args required to build the message */
5446   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5447     {
5448       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5449         sw_if_index_set = 1;
5450       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5451         sw_if_index_set = 1;
5452       else if (unformat (i, "disable"))
5453         enable = 0;
5454       else if (unformat (i, "dis"))
5455         enable = 0;
5456       else
5457         break;
5458     }
5459
5460   if (sw_if_index_set == 0)
5461     {
5462       errmsg ("missing interface name or sw_if_index");
5463       return -99;
5464     }
5465
5466   /* Construct the API message */
5467   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
5468
5469   mp->sw_if_index = ntohl (sw_if_index);
5470   mp->enable = enable;
5471
5472   /* send it... */
5473   S (mp);
5474
5475   /* Wait for a reply... */
5476   W (ret);
5477   return ret;
5478 }
5479
5480 static int
5481 api_sw_interface_set_table (vat_main_t * vam)
5482 {
5483   unformat_input_t *i = vam->input;
5484   vl_api_sw_interface_set_table_t *mp;
5485   u32 sw_if_index, vrf_id = 0;
5486   u8 sw_if_index_set = 0;
5487   u8 is_ipv6 = 0;
5488   int ret;
5489
5490   /* Parse args required to build the message */
5491   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5492     {
5493       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5494         sw_if_index_set = 1;
5495       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5496         sw_if_index_set = 1;
5497       else if (unformat (i, "vrf %d", &vrf_id))
5498         ;
5499       else if (unformat (i, "ipv6"))
5500         is_ipv6 = 1;
5501       else
5502         break;
5503     }
5504
5505   if (sw_if_index_set == 0)
5506     {
5507       errmsg ("missing interface name or sw_if_index");
5508       return -99;
5509     }
5510
5511   /* Construct the API message */
5512   M (SW_INTERFACE_SET_TABLE, mp);
5513
5514   mp->sw_if_index = ntohl (sw_if_index);
5515   mp->is_ipv6 = is_ipv6;
5516   mp->vrf_id = ntohl (vrf_id);
5517
5518   /* send it... */
5519   S (mp);
5520
5521   /* Wait for a reply... */
5522   W (ret);
5523   return ret;
5524 }
5525
5526 static void vl_api_sw_interface_get_table_reply_t_handler
5527   (vl_api_sw_interface_get_table_reply_t * mp)
5528 {
5529   vat_main_t *vam = &vat_main;
5530
5531   print (vam->ofp, "%d", ntohl (mp->vrf_id));
5532
5533   vam->retval = ntohl (mp->retval);
5534   vam->result_ready = 1;
5535
5536 }
5537
5538 static void vl_api_sw_interface_get_table_reply_t_handler_json
5539   (vl_api_sw_interface_get_table_reply_t * mp)
5540 {
5541   vat_main_t *vam = &vat_main;
5542   vat_json_node_t node;
5543
5544   vat_json_init_object (&node);
5545   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
5546   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
5547
5548   vat_json_print (vam->ofp, &node);
5549   vat_json_free (&node);
5550
5551   vam->retval = ntohl (mp->retval);
5552   vam->result_ready = 1;
5553 }
5554
5555 static int
5556 api_sw_interface_get_table (vat_main_t * vam)
5557 {
5558   unformat_input_t *i = vam->input;
5559   vl_api_sw_interface_get_table_t *mp;
5560   u32 sw_if_index;
5561   u8 sw_if_index_set = 0;
5562   u8 is_ipv6 = 0;
5563   int ret;
5564
5565   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5566     {
5567       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5568         sw_if_index_set = 1;
5569       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5570         sw_if_index_set = 1;
5571       else if (unformat (i, "ipv6"))
5572         is_ipv6 = 1;
5573       else
5574         break;
5575     }
5576
5577   if (sw_if_index_set == 0)
5578     {
5579       errmsg ("missing interface name or sw_if_index");
5580       return -99;
5581     }
5582
5583   M (SW_INTERFACE_GET_TABLE, mp);
5584   mp->sw_if_index = htonl (sw_if_index);
5585   mp->is_ipv6 = is_ipv6;
5586
5587   S (mp);
5588   W (ret);
5589   return ret;
5590 }
5591
5592 static int
5593 api_sw_interface_set_vpath (vat_main_t * vam)
5594 {
5595   unformat_input_t *i = vam->input;
5596   vl_api_sw_interface_set_vpath_t *mp;
5597   u32 sw_if_index = 0;
5598   u8 sw_if_index_set = 0;
5599   u8 is_enable = 0;
5600   int ret;
5601
5602   /* Parse args required to build the message */
5603   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5604     {
5605       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5606         sw_if_index_set = 1;
5607       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5608         sw_if_index_set = 1;
5609       else if (unformat (i, "enable"))
5610         is_enable = 1;
5611       else if (unformat (i, "disable"))
5612         is_enable = 0;
5613       else
5614         break;
5615     }
5616
5617   if (sw_if_index_set == 0)
5618     {
5619       errmsg ("missing interface name or sw_if_index");
5620       return -99;
5621     }
5622
5623   /* Construct the API message */
5624   M (SW_INTERFACE_SET_VPATH, mp);
5625
5626   mp->sw_if_index = ntohl (sw_if_index);
5627   mp->enable = is_enable;
5628
5629   /* send it... */
5630   S (mp);
5631
5632   /* Wait for a reply... */
5633   W (ret);
5634   return ret;
5635 }
5636
5637 static int
5638 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
5639 {
5640   unformat_input_t *i = vam->input;
5641   vl_api_sw_interface_set_vxlan_bypass_t *mp;
5642   u32 sw_if_index = 0;
5643   u8 sw_if_index_set = 0;
5644   u8 is_enable = 1;
5645   u8 is_ipv6 = 0;
5646   int ret;
5647
5648   /* Parse args required to build the message */
5649   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5650     {
5651       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5652         sw_if_index_set = 1;
5653       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5654         sw_if_index_set = 1;
5655       else if (unformat (i, "enable"))
5656         is_enable = 1;
5657       else if (unformat (i, "disable"))
5658         is_enable = 0;
5659       else if (unformat (i, "ip4"))
5660         is_ipv6 = 0;
5661       else if (unformat (i, "ip6"))
5662         is_ipv6 = 1;
5663       else
5664         break;
5665     }
5666
5667   if (sw_if_index_set == 0)
5668     {
5669       errmsg ("missing interface name or sw_if_index");
5670       return -99;
5671     }
5672
5673   /* Construct the API message */
5674   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
5675
5676   mp->sw_if_index = ntohl (sw_if_index);
5677   mp->enable = is_enable;
5678   mp->is_ipv6 = is_ipv6;
5679
5680   /* send it... */
5681   S (mp);
5682
5683   /* Wait for a reply... */
5684   W (ret);
5685   return ret;
5686 }
5687
5688 static int
5689 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
5690 {
5691   unformat_input_t *i = vam->input;
5692   vl_api_sw_interface_set_l2_xconnect_t *mp;
5693   u32 rx_sw_if_index;
5694   u8 rx_sw_if_index_set = 0;
5695   u32 tx_sw_if_index;
5696   u8 tx_sw_if_index_set = 0;
5697   u8 enable = 1;
5698   int ret;
5699
5700   /* Parse args required to build the message */
5701   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5702     {
5703       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
5704         rx_sw_if_index_set = 1;
5705       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
5706         tx_sw_if_index_set = 1;
5707       else if (unformat (i, "rx"))
5708         {
5709           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5710             {
5711               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
5712                             &rx_sw_if_index))
5713                 rx_sw_if_index_set = 1;
5714             }
5715           else
5716             break;
5717         }
5718       else if (unformat (i, "tx"))
5719         {
5720           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5721             {
5722               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
5723                             &tx_sw_if_index))
5724                 tx_sw_if_index_set = 1;
5725             }
5726           else
5727             break;
5728         }
5729       else if (unformat (i, "enable"))
5730         enable = 1;
5731       else if (unformat (i, "disable"))
5732         enable = 0;
5733       else
5734         break;
5735     }
5736
5737   if (rx_sw_if_index_set == 0)
5738     {
5739       errmsg ("missing rx interface name or rx_sw_if_index");
5740       return -99;
5741     }
5742
5743   if (enable && (tx_sw_if_index_set == 0))
5744     {
5745       errmsg ("missing tx interface name or tx_sw_if_index");
5746       return -99;
5747     }
5748
5749   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
5750
5751   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
5752   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
5753   mp->enable = enable;
5754
5755   S (mp);
5756   W (ret);
5757   return ret;
5758 }
5759
5760 static int
5761 api_sw_interface_set_l2_bridge (vat_main_t * vam)
5762 {
5763   unformat_input_t *i = vam->input;
5764   vl_api_sw_interface_set_l2_bridge_t *mp;
5765   u32 rx_sw_if_index;
5766   u8 rx_sw_if_index_set = 0;
5767   u32 bd_id;
5768   u8 bd_id_set = 0;
5769   u8 bvi = 0;
5770   u32 shg = 0;
5771   u8 enable = 1;
5772   int ret;
5773
5774   /* Parse args required to build the message */
5775   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5776     {
5777       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
5778         rx_sw_if_index_set = 1;
5779       else if (unformat (i, "bd_id %d", &bd_id))
5780         bd_id_set = 1;
5781       else
5782         if (unformat
5783             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
5784         rx_sw_if_index_set = 1;
5785       else if (unformat (i, "shg %d", &shg))
5786         ;
5787       else if (unformat (i, "bvi"))
5788         bvi = 1;
5789       else if (unformat (i, "enable"))
5790         enable = 1;
5791       else if (unformat (i, "disable"))
5792         enable = 0;
5793       else
5794         break;
5795     }
5796
5797   if (rx_sw_if_index_set == 0)
5798     {
5799       errmsg ("missing rx interface name or sw_if_index");
5800       return -99;
5801     }
5802
5803   if (enable && (bd_id_set == 0))
5804     {
5805       errmsg ("missing bridge domain");
5806       return -99;
5807     }
5808
5809   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
5810
5811   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
5812   mp->bd_id = ntohl (bd_id);
5813   mp->shg = (u8) shg;
5814   mp->bvi = bvi;
5815   mp->enable = enable;
5816
5817   S (mp);
5818   W (ret);
5819   return ret;
5820 }
5821
5822 static int
5823 api_bridge_domain_dump (vat_main_t * vam)
5824 {
5825   unformat_input_t *i = vam->input;
5826   vl_api_bridge_domain_dump_t *mp;
5827   vl_api_control_ping_t *mp_ping;
5828   u32 bd_id = ~0;
5829   int ret;
5830
5831   /* Parse args required to build the message */
5832   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5833     {
5834       if (unformat (i, "bd_id %d", &bd_id))
5835         ;
5836       else
5837         break;
5838     }
5839
5840   M (BRIDGE_DOMAIN_DUMP, mp);
5841   mp->bd_id = ntohl (bd_id);
5842   S (mp);
5843
5844   /* Use a control ping for synchronization */
5845   M (CONTROL_PING, mp_ping);
5846   S (mp_ping);
5847
5848   W (ret);
5849   return ret;
5850 }
5851
5852 static int
5853 api_bridge_domain_add_del (vat_main_t * vam)
5854 {
5855   unformat_input_t *i = vam->input;
5856   vl_api_bridge_domain_add_del_t *mp;
5857   u32 bd_id = ~0;
5858   u8 is_add = 1;
5859   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
5860   u32 mac_age = 0;
5861   int ret;
5862
5863   /* Parse args required to build the message */
5864   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5865     {
5866       if (unformat (i, "bd_id %d", &bd_id))
5867         ;
5868       else if (unformat (i, "flood %d", &flood))
5869         ;
5870       else if (unformat (i, "uu-flood %d", &uu_flood))
5871         ;
5872       else if (unformat (i, "forward %d", &forward))
5873         ;
5874       else if (unformat (i, "learn %d", &learn))
5875         ;
5876       else if (unformat (i, "arp-term %d", &arp_term))
5877         ;
5878       else if (unformat (i, "mac-age %d", &mac_age))
5879         ;
5880       else if (unformat (i, "del"))
5881         {
5882           is_add = 0;
5883           flood = uu_flood = forward = learn = 0;
5884         }
5885       else
5886         break;
5887     }
5888
5889   if (bd_id == ~0)
5890     {
5891       errmsg ("missing bridge domain");
5892       return -99;
5893     }
5894
5895   if (mac_age > 255)
5896     {
5897       errmsg ("mac age must be less than 256 ");
5898       return -99;
5899     }
5900
5901   M (BRIDGE_DOMAIN_ADD_DEL, mp);
5902
5903   mp->bd_id = ntohl (bd_id);
5904   mp->flood = flood;
5905   mp->uu_flood = uu_flood;
5906   mp->forward = forward;
5907   mp->learn = learn;
5908   mp->arp_term = arp_term;
5909   mp->is_add = is_add;
5910   mp->mac_age = (u8) mac_age;
5911
5912   S (mp);
5913   W (ret);
5914   return ret;
5915 }
5916
5917 static int
5918 api_l2fib_add_del (vat_main_t * vam)
5919 {
5920   unformat_input_t *i = vam->input;
5921   vl_api_l2fib_add_del_t *mp;
5922   f64 timeout;
5923   u64 mac = 0;
5924   u8 mac_set = 0;
5925   u32 bd_id;
5926   u8 bd_id_set = 0;
5927   u32 sw_if_index = ~0;
5928   u8 sw_if_index_set = 0;
5929   u8 is_add = 1;
5930   u8 static_mac = 0;
5931   u8 filter_mac = 0;
5932   u8 bvi_mac = 0;
5933   int count = 1;
5934   f64 before = 0;
5935   int j;
5936
5937   /* Parse args required to build the message */
5938   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5939     {
5940       if (unformat (i, "mac %U", unformat_ethernet_address, &mac))
5941         mac_set = 1;
5942       else if (unformat (i, "bd_id %d", &bd_id))
5943         bd_id_set = 1;
5944       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5945         sw_if_index_set = 1;
5946       else if (unformat (i, "sw_if"))
5947         {
5948           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5949             {
5950               if (unformat
5951                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5952                 sw_if_index_set = 1;
5953             }
5954           else
5955             break;
5956         }
5957       else if (unformat (i, "static"))
5958         static_mac = 1;
5959       else if (unformat (i, "filter"))
5960         {
5961           filter_mac = 1;
5962           static_mac = 1;
5963         }
5964       else if (unformat (i, "bvi"))
5965         {
5966           bvi_mac = 1;
5967           static_mac = 1;
5968         }
5969       else if (unformat (i, "del"))
5970         is_add = 0;
5971       else if (unformat (i, "count %d", &count))
5972         ;
5973       else
5974         break;
5975     }
5976
5977   if (mac_set == 0)
5978     {
5979       errmsg ("missing mac address");
5980       return -99;
5981     }
5982
5983   if (bd_id_set == 0)
5984     {
5985       errmsg ("missing bridge domain");
5986       return -99;
5987     }
5988
5989   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
5990     {
5991       errmsg ("missing interface name or sw_if_index");
5992       return -99;
5993     }
5994
5995   if (count > 1)
5996     {
5997       /* Turn on async mode */
5998       vam->async_mode = 1;
5999       vam->async_errors = 0;
6000       before = vat_time_now (vam);
6001     }
6002
6003   for (j = 0; j < count; j++)
6004     {
6005       M (L2FIB_ADD_DEL, mp);
6006
6007       mp->mac = mac;
6008       mp->bd_id = ntohl (bd_id);
6009       mp->is_add = is_add;
6010
6011       if (is_add)
6012         {
6013           mp->sw_if_index = ntohl (sw_if_index);
6014           mp->static_mac = static_mac;
6015           mp->filter_mac = filter_mac;
6016           mp->bvi_mac = bvi_mac;
6017         }
6018       increment_mac_address (&mac);
6019       /* send it... */
6020       S (mp);
6021     }
6022
6023   if (count > 1)
6024     {
6025       vl_api_control_ping_t *mp_ping;
6026       f64 after;
6027
6028       /* Shut off async mode */
6029       vam->async_mode = 0;
6030
6031       M (CONTROL_PING, mp_ping);
6032       S (mp_ping);
6033
6034       timeout = vat_time_now (vam) + 1.0;
6035       while (vat_time_now (vam) < timeout)
6036         if (vam->result_ready == 1)
6037           goto out;
6038       vam->retval = -99;
6039
6040     out:
6041       if (vam->retval == -99)
6042         errmsg ("timeout");
6043
6044       if (vam->async_errors > 0)
6045         {
6046           errmsg ("%d asynchronous errors", vam->async_errors);
6047           vam->retval = -98;
6048         }
6049       vam->async_errors = 0;
6050       after = vat_time_now (vam);
6051
6052       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6053              count, after - before, count / (after - before));
6054     }
6055   else
6056     {
6057       int ret;
6058
6059       /* Wait for a reply... */
6060       W (ret);
6061       return ret;
6062     }
6063   /* Return the good/bad news */
6064   return (vam->retval);
6065 }
6066
6067 static int
6068 api_bridge_domain_set_mac_age (vat_main_t * vam)
6069 {
6070   unformat_input_t *i = vam->input;
6071   vl_api_bridge_domain_set_mac_age_t *mp;
6072   u32 bd_id = ~0;
6073   u32 mac_age = 0;
6074   int ret;
6075
6076   /* Parse args required to build the message */
6077   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6078     {
6079       if (unformat (i, "bd_id %d", &bd_id));
6080       else if (unformat (i, "mac-age %d", &mac_age));
6081       else
6082         break;
6083     }
6084
6085   if (bd_id == ~0)
6086     {
6087       errmsg ("missing bridge domain");
6088       return -99;
6089     }
6090
6091   if (mac_age > 255)
6092     {
6093       errmsg ("mac age must be less than 256 ");
6094       return -99;
6095     }
6096
6097   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
6098
6099   mp->bd_id = htonl (bd_id);
6100   mp->mac_age = (u8) mac_age;
6101
6102   S (mp);
6103   W (ret);
6104   return ret;
6105 }
6106
6107 static int
6108 api_l2_flags (vat_main_t * vam)
6109 {
6110   unformat_input_t *i = vam->input;
6111   vl_api_l2_flags_t *mp;
6112   u32 sw_if_index;
6113   u32 feature_bitmap = 0;
6114   u8 sw_if_index_set = 0;
6115   int ret;
6116
6117   /* Parse args required to build the message */
6118   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6119     {
6120       if (unformat (i, "sw_if_index %d", &sw_if_index))
6121         sw_if_index_set = 1;
6122       else if (unformat (i, "sw_if"))
6123         {
6124           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6125             {
6126               if (unformat
6127                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6128                 sw_if_index_set = 1;
6129             }
6130           else
6131             break;
6132         }
6133       else if (unformat (i, "learn"))
6134         feature_bitmap |= L2INPUT_FEAT_LEARN;
6135       else if (unformat (i, "forward"))
6136         feature_bitmap |= L2INPUT_FEAT_FWD;
6137       else if (unformat (i, "flood"))
6138         feature_bitmap |= L2INPUT_FEAT_FLOOD;
6139       else if (unformat (i, "uu-flood"))
6140         feature_bitmap |= L2INPUT_FEAT_UU_FLOOD;
6141       else
6142         break;
6143     }
6144
6145   if (sw_if_index_set == 0)
6146     {
6147       errmsg ("missing interface name or sw_if_index");
6148       return -99;
6149     }
6150
6151   M (L2_FLAGS, mp);
6152
6153   mp->sw_if_index = ntohl (sw_if_index);
6154   mp->feature_bitmap = ntohl (feature_bitmap);
6155
6156   S (mp);
6157   W (ret);
6158   return ret;
6159 }
6160
6161 static int
6162 api_bridge_flags (vat_main_t * vam)
6163 {
6164   unformat_input_t *i = vam->input;
6165   vl_api_bridge_flags_t *mp;
6166   u32 bd_id;
6167   u8 bd_id_set = 0;
6168   u8 is_set = 1;
6169   u32 flags = 0;
6170   int ret;
6171
6172   /* Parse args required to build the message */
6173   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6174     {
6175       if (unformat (i, "bd_id %d", &bd_id))
6176         bd_id_set = 1;
6177       else if (unformat (i, "learn"))
6178         flags |= L2_LEARN;
6179       else if (unformat (i, "forward"))
6180         flags |= L2_FWD;
6181       else if (unformat (i, "flood"))
6182         flags |= L2_FLOOD;
6183       else if (unformat (i, "uu-flood"))
6184         flags |= L2_UU_FLOOD;
6185       else if (unformat (i, "arp-term"))
6186         flags |= L2_ARP_TERM;
6187       else if (unformat (i, "off"))
6188         is_set = 0;
6189       else if (unformat (i, "disable"))
6190         is_set = 0;
6191       else
6192         break;
6193     }
6194
6195   if (bd_id_set == 0)
6196     {
6197       errmsg ("missing bridge domain");
6198       return -99;
6199     }
6200
6201   M (BRIDGE_FLAGS, mp);
6202
6203   mp->bd_id = ntohl (bd_id);
6204   mp->feature_bitmap = ntohl (flags);
6205   mp->is_set = is_set;
6206
6207   S (mp);
6208   W (ret);
6209   return ret;
6210 }
6211
6212 static int
6213 api_bd_ip_mac_add_del (vat_main_t * vam)
6214 {
6215   unformat_input_t *i = vam->input;
6216   vl_api_bd_ip_mac_add_del_t *mp;
6217   u32 bd_id;
6218   u8 is_ipv6 = 0;
6219   u8 is_add = 1;
6220   u8 bd_id_set = 0;
6221   u8 ip_set = 0;
6222   u8 mac_set = 0;
6223   ip4_address_t v4addr;
6224   ip6_address_t v6addr;
6225   u8 macaddr[6];
6226   int ret;
6227
6228
6229   /* Parse args required to build the message */
6230   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6231     {
6232       if (unformat (i, "bd_id %d", &bd_id))
6233         {
6234           bd_id_set++;
6235         }
6236       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
6237         {
6238           ip_set++;
6239         }
6240       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
6241         {
6242           ip_set++;
6243           is_ipv6++;
6244         }
6245       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
6246         {
6247           mac_set++;
6248         }
6249       else if (unformat (i, "del"))
6250         is_add = 0;
6251       else
6252         break;
6253     }
6254
6255   if (bd_id_set == 0)
6256     {
6257       errmsg ("missing bridge domain");
6258       return -99;
6259     }
6260   else if (ip_set == 0)
6261     {
6262       errmsg ("missing IP address");
6263       return -99;
6264     }
6265   else if (mac_set == 0)
6266     {
6267       errmsg ("missing MAC address");
6268       return -99;
6269     }
6270
6271   M (BD_IP_MAC_ADD_DEL, mp);
6272
6273   mp->bd_id = ntohl (bd_id);
6274   mp->is_ipv6 = is_ipv6;
6275   mp->is_add = is_add;
6276   if (is_ipv6)
6277     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
6278   else
6279     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
6280   clib_memcpy (mp->mac_address, macaddr, 6);
6281   S (mp);
6282   W (ret);
6283   return ret;
6284 }
6285
6286 static int
6287 api_tap_connect (vat_main_t * vam)
6288 {
6289   unformat_input_t *i = vam->input;
6290   vl_api_tap_connect_t *mp;
6291   u8 mac_address[6];
6292   u8 random_mac = 1;
6293   u8 name_set = 0;
6294   u8 *tap_name;
6295   u8 *tag = 0;
6296   ip4_address_t ip4_address;
6297   u32 ip4_mask_width;
6298   int ip4_address_set = 0;
6299   ip6_address_t ip6_address;
6300   u32 ip6_mask_width;
6301   int ip6_address_set = 0;
6302   int ret;
6303
6304   memset (mac_address, 0, sizeof (mac_address));
6305
6306   /* Parse args required to build the message */
6307   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6308     {
6309       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6310         {
6311           random_mac = 0;
6312         }
6313       else if (unformat (i, "random-mac"))
6314         random_mac = 1;
6315       else if (unformat (i, "tapname %s", &tap_name))
6316         name_set = 1;
6317       else if (unformat (i, "tag %s", &tag))
6318         ;
6319       else if (unformat (i, "address %U/%d",
6320                          unformat_ip4_address, &ip4_address, &ip4_mask_width))
6321         ip4_address_set = 1;
6322       else if (unformat (i, "address %U/%d",
6323                          unformat_ip6_address, &ip6_address, &ip6_mask_width))
6324         ip6_address_set = 1;
6325       else
6326         break;
6327     }
6328
6329   if (name_set == 0)
6330     {
6331       errmsg ("missing tap name");
6332       return -99;
6333     }
6334   if (vec_len (tap_name) > 63)
6335     {
6336       errmsg ("tap name too long");
6337       return -99;
6338     }
6339   vec_add1 (tap_name, 0);
6340
6341   if (vec_len (tag) > 63)
6342     {
6343       errmsg ("tag too long");
6344       return -99;
6345     }
6346
6347   /* Construct the API message */
6348   M (TAP_CONNECT, mp);
6349
6350   mp->use_random_mac = random_mac;
6351   clib_memcpy (mp->mac_address, mac_address, 6);
6352   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
6353   if (tag)
6354     clib_memcpy (mp->tag, tag, vec_len (tag));
6355
6356   if (ip4_address_set)
6357     {
6358       mp->ip4_address_set = 1;
6359       clib_memcpy (mp->ip4_address, &ip4_address, sizeof (mp->ip4_address));
6360       mp->ip4_mask_width = ip4_mask_width;
6361     }
6362   if (ip6_address_set)
6363     {
6364       mp->ip6_address_set = 1;
6365       clib_memcpy (mp->ip6_address, &ip6_address, sizeof (mp->ip6_address));
6366       mp->ip6_mask_width = ip6_mask_width;
6367     }
6368
6369   vec_free (tap_name);
6370   vec_free (tag);
6371
6372   /* send it... */
6373   S (mp);
6374
6375   /* Wait for a reply... */
6376   W (ret);
6377   return ret;
6378 }
6379
6380 static int
6381 api_tap_modify (vat_main_t * vam)
6382 {
6383   unformat_input_t *i = vam->input;
6384   vl_api_tap_modify_t *mp;
6385   u8 mac_address[6];
6386   u8 random_mac = 1;
6387   u8 name_set = 0;
6388   u8 *tap_name;
6389   u32 sw_if_index = ~0;
6390   u8 sw_if_index_set = 0;
6391   int ret;
6392
6393   memset (mac_address, 0, sizeof (mac_address));
6394
6395   /* Parse args required to build the message */
6396   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6397     {
6398       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6399         sw_if_index_set = 1;
6400       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6401         sw_if_index_set = 1;
6402       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6403         {
6404           random_mac = 0;
6405         }
6406       else if (unformat (i, "random-mac"))
6407         random_mac = 1;
6408       else if (unformat (i, "tapname %s", &tap_name))
6409         name_set = 1;
6410       else
6411         break;
6412     }
6413
6414   if (sw_if_index_set == 0)
6415     {
6416       errmsg ("missing vpp interface name");
6417       return -99;
6418     }
6419   if (name_set == 0)
6420     {
6421       errmsg ("missing tap name");
6422       return -99;
6423     }
6424   if (vec_len (tap_name) > 63)
6425     {
6426       errmsg ("tap name too long");
6427     }
6428   vec_add1 (tap_name, 0);
6429
6430   /* Construct the API message */
6431   M (TAP_MODIFY, mp);
6432
6433   mp->use_random_mac = random_mac;
6434   mp->sw_if_index = ntohl (sw_if_index);
6435   clib_memcpy (mp->mac_address, mac_address, 6);
6436   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
6437   vec_free (tap_name);
6438
6439   /* send it... */
6440   S (mp);
6441
6442   /* Wait for a reply... */
6443   W (ret);
6444   return ret;
6445 }
6446
6447 static int
6448 api_tap_delete (vat_main_t * vam)
6449 {
6450   unformat_input_t *i = vam->input;
6451   vl_api_tap_delete_t *mp;
6452   u32 sw_if_index = ~0;
6453   u8 sw_if_index_set = 0;
6454   int ret;
6455
6456   /* Parse args required to build the message */
6457   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6458     {
6459       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6460         sw_if_index_set = 1;
6461       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6462         sw_if_index_set = 1;
6463       else
6464         break;
6465     }
6466
6467   if (sw_if_index_set == 0)
6468     {
6469       errmsg ("missing vpp interface name");
6470       return -99;
6471     }
6472
6473   /* Construct the API message */
6474   M (TAP_DELETE, mp);
6475
6476   mp->sw_if_index = ntohl (sw_if_index);
6477
6478   /* send it... */
6479   S (mp);
6480
6481   /* Wait for a reply... */
6482   W (ret);
6483   return ret;
6484 }
6485
6486 static int
6487 api_ip_add_del_route (vat_main_t * vam)
6488 {
6489   unformat_input_t *i = vam->input;
6490   vl_api_ip_add_del_route_t *mp;
6491   u32 sw_if_index = ~0, vrf_id = 0;
6492   u8 is_ipv6 = 0;
6493   u8 is_local = 0, is_drop = 0;
6494   u8 is_unreach = 0, is_prohibit = 0;
6495   u8 create_vrf_if_needed = 0;
6496   u8 is_add = 1;
6497   u32 next_hop_weight = 1;
6498   u8 not_last = 0;
6499   u8 is_multipath = 0;
6500   u8 address_set = 0;
6501   u8 address_length_set = 0;
6502   u32 next_hop_table_id = 0;
6503   u32 resolve_attempts = 0;
6504   u32 dst_address_length = 0;
6505   u8 next_hop_set = 0;
6506   ip4_address_t v4_dst_address, v4_next_hop_address;
6507   ip6_address_t v6_dst_address, v6_next_hop_address;
6508   int count = 1;
6509   int j;
6510   f64 before = 0;
6511   u32 random_add_del = 0;
6512   u32 *random_vector = 0;
6513   uword *random_hash;
6514   u32 random_seed = 0xdeaddabe;
6515   u32 classify_table_index = ~0;
6516   u8 is_classify = 0;
6517   u8 resolve_host = 0, resolve_attached = 0;
6518   mpls_label_t *next_hop_out_label_stack = NULL;
6519   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
6520   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
6521
6522   /* Parse args required to build the message */
6523   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6524     {
6525       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6526         ;
6527       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6528         ;
6529       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
6530         {
6531           address_set = 1;
6532           is_ipv6 = 0;
6533         }
6534       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
6535         {
6536           address_set = 1;
6537           is_ipv6 = 1;
6538         }
6539       else if (unformat (i, "/%d", &dst_address_length))
6540         {
6541           address_length_set = 1;
6542         }
6543
6544       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
6545                                          &v4_next_hop_address))
6546         {
6547           next_hop_set = 1;
6548         }
6549       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
6550                                          &v6_next_hop_address))
6551         {
6552           next_hop_set = 1;
6553         }
6554       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
6555         ;
6556       else if (unformat (i, "weight %d", &next_hop_weight))
6557         ;
6558       else if (unformat (i, "drop"))
6559         {
6560           is_drop = 1;
6561         }
6562       else if (unformat (i, "null-send-unreach"))
6563         {
6564           is_unreach = 1;
6565         }
6566       else if (unformat (i, "null-send-prohibit"))
6567         {
6568           is_prohibit = 1;
6569         }
6570       else if (unformat (i, "local"))
6571         {
6572           is_local = 1;
6573         }
6574       else if (unformat (i, "classify %d", &classify_table_index))
6575         {
6576           is_classify = 1;
6577         }
6578       else if (unformat (i, "del"))
6579         is_add = 0;
6580       else if (unformat (i, "add"))
6581         is_add = 1;
6582       else if (unformat (i, "not-last"))
6583         not_last = 1;
6584       else if (unformat (i, "resolve-via-host"))
6585         resolve_host = 1;
6586       else if (unformat (i, "resolve-via-attached"))
6587         resolve_attached = 1;
6588       else if (unformat (i, "multipath"))
6589         is_multipath = 1;
6590       else if (unformat (i, "vrf %d", &vrf_id))
6591         ;
6592       else if (unformat (i, "create-vrf"))
6593         create_vrf_if_needed = 1;
6594       else if (unformat (i, "count %d", &count))
6595         ;
6596       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
6597         ;
6598       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
6599         ;
6600       else if (unformat (i, "out-label %d", &next_hop_out_label))
6601         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
6602       else if (unformat (i, "via-label %d", &next_hop_via_label))
6603         ;
6604       else if (unformat (i, "random"))
6605         random_add_del = 1;
6606       else if (unformat (i, "seed %d", &random_seed))
6607         ;
6608       else
6609         {
6610           clib_warning ("parse error '%U'", format_unformat_error, i);
6611           return -99;
6612         }
6613     }
6614
6615   if (!next_hop_set && !is_drop && !is_local &&
6616       !is_classify && !is_unreach && !is_prohibit &&
6617       MPLS_LABEL_INVALID == next_hop_via_label)
6618     {
6619       errmsg
6620         ("next hop / local / drop / unreach / prohibit / classify not set");
6621       return -99;
6622     }
6623
6624   if (next_hop_set && MPLS_LABEL_INVALID != next_hop_via_label)
6625     {
6626       errmsg ("next hop and next-hop via label set");
6627       return -99;
6628     }
6629   if (address_set == 0)
6630     {
6631       errmsg ("missing addresses");
6632       return -99;
6633     }
6634
6635   if (address_length_set == 0)
6636     {
6637       errmsg ("missing address length");
6638       return -99;
6639     }
6640
6641   /* Generate a pile of unique, random routes */
6642   if (random_add_del)
6643     {
6644       u32 this_random_address;
6645       random_hash = hash_create (count, sizeof (uword));
6646
6647       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
6648       for (j = 0; j <= count; j++)
6649         {
6650           do
6651             {
6652               this_random_address = random_u32 (&random_seed);
6653               this_random_address =
6654                 clib_host_to_net_u32 (this_random_address);
6655             }
6656           while (hash_get (random_hash, this_random_address));
6657           vec_add1 (random_vector, this_random_address);
6658           hash_set (random_hash, this_random_address, 1);
6659         }
6660       hash_free (random_hash);
6661       v4_dst_address.as_u32 = random_vector[0];
6662     }
6663
6664   if (count > 1)
6665     {
6666       /* Turn on async mode */
6667       vam->async_mode = 1;
6668       vam->async_errors = 0;
6669       before = vat_time_now (vam);
6670     }
6671
6672   for (j = 0; j < count; j++)
6673     {
6674       /* Construct the API message */
6675       M2 (IP_ADD_DEL_ROUTE, mp,
6676           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
6677
6678       mp->next_hop_sw_if_index = ntohl (sw_if_index);
6679       mp->table_id = ntohl (vrf_id);
6680       mp->create_vrf_if_needed = create_vrf_if_needed;
6681
6682       mp->is_add = is_add;
6683       mp->is_drop = is_drop;
6684       mp->is_unreach = is_unreach;
6685       mp->is_prohibit = is_prohibit;
6686       mp->is_ipv6 = is_ipv6;
6687       mp->is_local = is_local;
6688       mp->is_classify = is_classify;
6689       mp->is_multipath = is_multipath;
6690       mp->is_resolve_host = resolve_host;
6691       mp->is_resolve_attached = resolve_attached;
6692       mp->not_last = not_last;
6693       mp->next_hop_weight = next_hop_weight;
6694       mp->dst_address_length = dst_address_length;
6695       mp->next_hop_table_id = ntohl (next_hop_table_id);
6696       mp->classify_table_index = ntohl (classify_table_index);
6697       mp->next_hop_via_label = ntohl (next_hop_via_label);
6698       mp->next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
6699       if (0 != mp->next_hop_n_out_labels)
6700         {
6701           memcpy (mp->next_hop_out_label_stack,
6702                   next_hop_out_label_stack,
6703                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
6704           vec_free (next_hop_out_label_stack);
6705         }
6706
6707       if (is_ipv6)
6708         {
6709           clib_memcpy (mp->dst_address, &v6_dst_address,
6710                        sizeof (v6_dst_address));
6711           if (next_hop_set)
6712             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
6713                          sizeof (v6_next_hop_address));
6714           increment_v6_address (&v6_dst_address);
6715         }
6716       else
6717         {
6718           clib_memcpy (mp->dst_address, &v4_dst_address,
6719                        sizeof (v4_dst_address));
6720           if (next_hop_set)
6721             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
6722                          sizeof (v4_next_hop_address));
6723           if (random_add_del)
6724             v4_dst_address.as_u32 = random_vector[j + 1];
6725           else
6726             increment_v4_address (&v4_dst_address);
6727         }
6728       /* send it... */
6729       S (mp);
6730       /* If we receive SIGTERM, stop now... */
6731       if (vam->do_exit)
6732         break;
6733     }
6734
6735   /* When testing multiple add/del ops, use a control-ping to sync */
6736   if (count > 1)
6737     {
6738       vl_api_control_ping_t *mp_ping;
6739       f64 after;
6740       f64 timeout;
6741
6742       /* Shut off async mode */
6743       vam->async_mode = 0;
6744
6745       M (CONTROL_PING, mp_ping);
6746       S (mp_ping);
6747
6748       timeout = vat_time_now (vam) + 1.0;
6749       while (vat_time_now (vam) < timeout)
6750         if (vam->result_ready == 1)
6751           goto out;
6752       vam->retval = -99;
6753
6754     out:
6755       if (vam->retval == -99)
6756         errmsg ("timeout");
6757
6758       if (vam->async_errors > 0)
6759         {
6760           errmsg ("%d asynchronous errors", vam->async_errors);
6761           vam->retval = -98;
6762         }
6763       vam->async_errors = 0;
6764       after = vat_time_now (vam);
6765
6766       /* slim chance, but we might have eaten SIGTERM on the first iteration */
6767       if (j > 0)
6768         count = j;
6769
6770       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6771              count, after - before, count / (after - before));
6772     }
6773   else
6774     {
6775       int ret;
6776
6777       /* Wait for a reply... */
6778       W (ret);
6779       return ret;
6780     }
6781
6782   /* Return the good/bad news */
6783   return (vam->retval);
6784 }
6785
6786 static int
6787 api_ip_mroute_add_del (vat_main_t * vam)
6788 {
6789   unformat_input_t *i = vam->input;
6790   vl_api_ip_mroute_add_del_t *mp;
6791   u32 sw_if_index = ~0, vrf_id = 0;
6792   u8 is_ipv6 = 0;
6793   u8 is_local = 0;
6794   u8 create_vrf_if_needed = 0;
6795   u8 is_add = 1;
6796   u8 address_set = 0;
6797   u32 grp_address_length = 0;
6798   ip4_address_t v4_grp_address, v4_src_address;
6799   ip6_address_t v6_grp_address, v6_src_address;
6800   mfib_itf_flags_t iflags = 0;
6801   mfib_entry_flags_t eflags = 0;
6802   int ret;
6803
6804   /* Parse args required to build the message */
6805   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6806     {
6807       if (unformat (i, "sw_if_index %d", &sw_if_index))
6808         ;
6809       else if (unformat (i, "%U %U",
6810                          unformat_ip4_address, &v4_src_address,
6811                          unformat_ip4_address, &v4_grp_address))
6812         {
6813           grp_address_length = 64;
6814           address_set = 1;
6815           is_ipv6 = 0;
6816         }
6817       else if (unformat (i, "%U %U",
6818                          unformat_ip6_address, &v6_src_address,
6819                          unformat_ip6_address, &v6_grp_address))
6820         {
6821           grp_address_length = 256;
6822           address_set = 1;
6823           is_ipv6 = 1;
6824         }
6825       else if (unformat (i, "%U", unformat_ip4_address, &v4_grp_address))
6826         {
6827           memset (&v4_src_address, 0, sizeof (v4_src_address));
6828           grp_address_length = 32;
6829           address_set = 1;
6830           is_ipv6 = 0;
6831         }
6832       else if (unformat (i, "%U", unformat_ip6_address, &v6_grp_address))
6833         {
6834           memset (&v6_src_address, 0, sizeof (v6_src_address));
6835           grp_address_length = 128;
6836           address_set = 1;
6837           is_ipv6 = 1;
6838         }
6839       else if (unformat (i, "/%d", &grp_address_length))
6840         ;
6841       else if (unformat (i, "local"))
6842         {
6843           is_local = 1;
6844         }
6845       else if (unformat (i, "del"))
6846         is_add = 0;
6847       else if (unformat (i, "add"))
6848         is_add = 1;
6849       else if (unformat (i, "vrf %d", &vrf_id))
6850         ;
6851       else if (unformat (i, "create-vrf"))
6852         create_vrf_if_needed = 1;
6853       else if (unformat (i, "%U", unformat_mfib_itf_flags, &iflags))
6854         ;
6855       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
6856         ;
6857       else
6858         {
6859           clib_warning ("parse error '%U'", format_unformat_error, i);
6860           return -99;
6861         }
6862     }
6863
6864   if (address_set == 0)
6865     {
6866       errmsg ("missing addresses\n");
6867       return -99;
6868     }
6869
6870   /* Construct the API message */
6871   M (IP_MROUTE_ADD_DEL, mp);
6872
6873   mp->next_hop_sw_if_index = ntohl (sw_if_index);
6874   mp->table_id = ntohl (vrf_id);
6875   mp->create_vrf_if_needed = create_vrf_if_needed;
6876
6877   mp->is_add = is_add;
6878   mp->is_ipv6 = is_ipv6;
6879   mp->is_local = is_local;
6880   mp->itf_flags = ntohl (iflags);
6881   mp->entry_flags = ntohl (eflags);
6882   mp->grp_address_length = grp_address_length;
6883   mp->grp_address_length = ntohs (mp->grp_address_length);
6884
6885   if (is_ipv6)
6886     {
6887       clib_memcpy (mp->grp_address, &v6_grp_address, sizeof (v6_grp_address));
6888       clib_memcpy (mp->src_address, &v6_src_address, sizeof (v6_src_address));
6889     }
6890   else
6891     {
6892       clib_memcpy (mp->grp_address, &v4_grp_address, sizeof (v4_grp_address));
6893       clib_memcpy (mp->src_address, &v4_src_address, sizeof (v4_src_address));
6894
6895     }
6896
6897   /* send it... */
6898   S (mp);
6899   /* Wait for a reply... */
6900   W (ret);
6901   return ret;
6902 }
6903
6904 static int
6905 api_mpls_route_add_del (vat_main_t * vam)
6906 {
6907   unformat_input_t *i = vam->input;
6908   vl_api_mpls_route_add_del_t *mp;
6909   u32 sw_if_index = ~0, table_id = 0;
6910   u8 create_table_if_needed = 0;
6911   u8 is_add = 1;
6912   u32 next_hop_weight = 1;
6913   u8 is_multipath = 0;
6914   u32 next_hop_table_id = 0;
6915   u8 next_hop_set = 0;
6916   ip4_address_t v4_next_hop_address = {
6917     .as_u32 = 0,
6918   };
6919   ip6_address_t v6_next_hop_address = { {0} };
6920   int count = 1;
6921   int j;
6922   f64 before = 0;
6923   u32 classify_table_index = ~0;
6924   u8 is_classify = 0;
6925   u8 resolve_host = 0, resolve_attached = 0;
6926   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
6927   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
6928   mpls_label_t *next_hop_out_label_stack = NULL;
6929   mpls_label_t local_label = MPLS_LABEL_INVALID;
6930   u8 is_eos = 0;
6931   u8 next_hop_proto_is_ip4 = 1;
6932
6933   /* Parse args required to build the message */
6934   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6935     {
6936       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6937         ;
6938       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6939         ;
6940       else if (unformat (i, "%d", &local_label))
6941         ;
6942       else if (unformat (i, "eos"))
6943         is_eos = 1;
6944       else if (unformat (i, "non-eos"))
6945         is_eos = 0;
6946       else if (unformat (i, "via %U", unformat_ip4_address,
6947                          &v4_next_hop_address))
6948         {
6949           next_hop_set = 1;
6950           next_hop_proto_is_ip4 = 1;
6951         }
6952       else if (unformat (i, "via %U", unformat_ip6_address,
6953                          &v6_next_hop_address))
6954         {
6955           next_hop_set = 1;
6956           next_hop_proto_is_ip4 = 0;
6957         }
6958       else if (unformat (i, "weight %d", &next_hop_weight))
6959         ;
6960       else if (unformat (i, "create-table"))
6961         create_table_if_needed = 1;
6962       else if (unformat (i, "classify %d", &classify_table_index))
6963         {
6964           is_classify = 1;
6965         }
6966       else if (unformat (i, "del"))
6967         is_add = 0;
6968       else if (unformat (i, "add"))
6969         is_add = 1;
6970       else if (unformat (i, "resolve-via-host"))
6971         resolve_host = 1;
6972       else if (unformat (i, "resolve-via-attached"))
6973         resolve_attached = 1;
6974       else if (unformat (i, "multipath"))
6975         is_multipath = 1;
6976       else if (unformat (i, "count %d", &count))
6977         ;
6978       else if (unformat (i, "lookup-in-ip4-table %d", &next_hop_table_id))
6979         {
6980           next_hop_set = 1;
6981           next_hop_proto_is_ip4 = 1;
6982         }
6983       else if (unformat (i, "lookup-in-ip6-table %d", &next_hop_table_id))
6984         {
6985           next_hop_set = 1;
6986           next_hop_proto_is_ip4 = 0;
6987         }
6988       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
6989         ;
6990       else if (unformat (i, "via-label %d", &next_hop_via_label))
6991         ;
6992       else if (unformat (i, "out-label %d", &next_hop_out_label))
6993         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
6994       else
6995         {
6996           clib_warning ("parse error '%U'", format_unformat_error, i);
6997           return -99;
6998         }
6999     }
7000
7001   if (!next_hop_set && !is_classify)
7002     {
7003       errmsg ("next hop / classify not set");
7004       return -99;
7005     }
7006
7007   if (MPLS_LABEL_INVALID == local_label)
7008     {
7009       errmsg ("missing label");
7010       return -99;
7011     }
7012
7013   if (count > 1)
7014     {
7015       /* Turn on async mode */
7016       vam->async_mode = 1;
7017       vam->async_errors = 0;
7018       before = vat_time_now (vam);
7019     }
7020
7021   for (j = 0; j < count; j++)
7022     {
7023       /* Construct the API message */
7024       M2 (MPLS_ROUTE_ADD_DEL, mp,
7025           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
7026
7027       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
7028       mp->mr_table_id = ntohl (table_id);
7029       mp->mr_create_table_if_needed = create_table_if_needed;
7030
7031       mp->mr_is_add = is_add;
7032       mp->mr_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
7033       mp->mr_is_classify = is_classify;
7034       mp->mr_is_multipath = is_multipath;
7035       mp->mr_is_resolve_host = resolve_host;
7036       mp->mr_is_resolve_attached = resolve_attached;
7037       mp->mr_next_hop_weight = next_hop_weight;
7038       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
7039       mp->mr_classify_table_index = ntohl (classify_table_index);
7040       mp->mr_next_hop_via_label = ntohl (next_hop_via_label);
7041       mp->mr_label = ntohl (local_label);
7042       mp->mr_eos = is_eos;
7043
7044       mp->mr_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
7045       if (0 != mp->mr_next_hop_n_out_labels)
7046         {
7047           memcpy (mp->mr_next_hop_out_label_stack,
7048                   next_hop_out_label_stack,
7049                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
7050           vec_free (next_hop_out_label_stack);
7051         }
7052
7053       if (next_hop_set)
7054         {
7055           if (next_hop_proto_is_ip4)
7056             {
7057               clib_memcpy (mp->mr_next_hop,
7058                            &v4_next_hop_address,
7059                            sizeof (v4_next_hop_address));
7060             }
7061           else
7062             {
7063               clib_memcpy (mp->mr_next_hop,
7064                            &v6_next_hop_address,
7065                            sizeof (v6_next_hop_address));
7066             }
7067         }
7068       local_label++;
7069
7070       /* send it... */
7071       S (mp);
7072       /* If we receive SIGTERM, stop now... */
7073       if (vam->do_exit)
7074         break;
7075     }
7076
7077   /* When testing multiple add/del ops, use a control-ping to sync */
7078   if (count > 1)
7079     {
7080       vl_api_control_ping_t *mp_ping;
7081       f64 after;
7082       f64 timeout;
7083
7084       /* Shut off async mode */
7085       vam->async_mode = 0;
7086
7087       M (CONTROL_PING, mp_ping);
7088       S (mp_ping);
7089
7090       timeout = vat_time_now (vam) + 1.0;
7091       while (vat_time_now (vam) < timeout)
7092         if (vam->result_ready == 1)
7093           goto out;
7094       vam->retval = -99;
7095
7096     out:
7097       if (vam->retval == -99)
7098         errmsg ("timeout");
7099
7100       if (vam->async_errors > 0)
7101         {
7102           errmsg ("%d asynchronous errors", vam->async_errors);
7103           vam->retval = -98;
7104         }
7105       vam->async_errors = 0;
7106       after = vat_time_now (vam);
7107
7108       /* slim chance, but we might have eaten SIGTERM on the first iteration */
7109       if (j > 0)
7110         count = j;
7111
7112       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
7113              count, after - before, count / (after - before));
7114     }
7115   else
7116     {
7117       int ret;
7118
7119       /* Wait for a reply... */
7120       W (ret);
7121       return ret;
7122     }
7123
7124   /* Return the good/bad news */
7125   return (vam->retval);
7126 }
7127
7128 static int
7129 api_mpls_ip_bind_unbind (vat_main_t * vam)
7130 {
7131   unformat_input_t *i = vam->input;
7132   vl_api_mpls_ip_bind_unbind_t *mp;
7133   u32 ip_table_id = 0;
7134   u8 create_table_if_needed = 0;
7135   u8 is_bind = 1;
7136   u8 is_ip4 = 1;
7137   ip4_address_t v4_address;
7138   ip6_address_t v6_address;
7139   u32 address_length;
7140   u8 address_set = 0;
7141   mpls_label_t local_label = MPLS_LABEL_INVALID;
7142   int ret;
7143
7144   /* Parse args required to build the message */
7145   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7146     {
7147       if (unformat (i, "%U/%d", unformat_ip4_address,
7148                     &v4_address, &address_length))
7149         {
7150           is_ip4 = 1;
7151           address_set = 1;
7152         }
7153       else if (unformat (i, "%U/%d", unformat_ip6_address,
7154                          &v6_address, &address_length))
7155         {
7156           is_ip4 = 0;
7157           address_set = 1;
7158         }
7159       else if (unformat (i, "%d", &local_label))
7160         ;
7161       else if (unformat (i, "create-table"))
7162         create_table_if_needed = 1;
7163       else if (unformat (i, "table-id %d", &ip_table_id))
7164         ;
7165       else if (unformat (i, "unbind"))
7166         is_bind = 0;
7167       else if (unformat (i, "bind"))
7168         is_bind = 1;
7169       else
7170         {
7171           clib_warning ("parse error '%U'", format_unformat_error, i);
7172           return -99;
7173         }
7174     }
7175
7176   if (!address_set)
7177     {
7178       errmsg ("IP addres not set");
7179       return -99;
7180     }
7181
7182   if (MPLS_LABEL_INVALID == local_label)
7183     {
7184       errmsg ("missing label");
7185       return -99;
7186     }
7187
7188   /* Construct the API message */
7189   M (MPLS_IP_BIND_UNBIND, mp);
7190
7191   mp->mb_create_table_if_needed = create_table_if_needed;
7192   mp->mb_is_bind = is_bind;
7193   mp->mb_is_ip4 = is_ip4;
7194   mp->mb_ip_table_id = ntohl (ip_table_id);
7195   mp->mb_mpls_table_id = 0;
7196   mp->mb_label = ntohl (local_label);
7197   mp->mb_address_length = address_length;
7198
7199   if (is_ip4)
7200     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
7201   else
7202     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
7203
7204   /* send it... */
7205   S (mp);
7206
7207   /* Wait for a reply... */
7208   W (ret);
7209   return ret;
7210 }
7211
7212 static int
7213 api_proxy_arp_add_del (vat_main_t * vam)
7214 {
7215   unformat_input_t *i = vam->input;
7216   vl_api_proxy_arp_add_del_t *mp;
7217   u32 vrf_id = 0;
7218   u8 is_add = 1;
7219   ip4_address_t lo, hi;
7220   u8 range_set = 0;
7221   int ret;
7222
7223   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7224     {
7225       if (unformat (i, "vrf %d", &vrf_id))
7226         ;
7227       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
7228                          unformat_ip4_address, &hi))
7229         range_set = 1;
7230       else if (unformat (i, "del"))
7231         is_add = 0;
7232       else
7233         {
7234           clib_warning ("parse error '%U'", format_unformat_error, i);
7235           return -99;
7236         }
7237     }
7238
7239   if (range_set == 0)
7240     {
7241       errmsg ("address range not set");
7242       return -99;
7243     }
7244
7245   M (PROXY_ARP_ADD_DEL, mp);
7246
7247   mp->vrf_id = ntohl (vrf_id);
7248   mp->is_add = is_add;
7249   clib_memcpy (mp->low_address, &lo, sizeof (mp->low_address));
7250   clib_memcpy (mp->hi_address, &hi, sizeof (mp->hi_address));
7251
7252   S (mp);
7253   W (ret);
7254   return ret;
7255 }
7256
7257 static int
7258 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
7259 {
7260   unformat_input_t *i = vam->input;
7261   vl_api_proxy_arp_intfc_enable_disable_t *mp;
7262   u32 sw_if_index;
7263   u8 enable = 1;
7264   u8 sw_if_index_set = 0;
7265   int ret;
7266
7267   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7268     {
7269       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7270         sw_if_index_set = 1;
7271       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7272         sw_if_index_set = 1;
7273       else if (unformat (i, "enable"))
7274         enable = 1;
7275       else if (unformat (i, "disable"))
7276         enable = 0;
7277       else
7278         {
7279           clib_warning ("parse error '%U'", format_unformat_error, i);
7280           return -99;
7281         }
7282     }
7283
7284   if (sw_if_index_set == 0)
7285     {
7286       errmsg ("missing interface name or sw_if_index");
7287       return -99;
7288     }
7289
7290   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
7291
7292   mp->sw_if_index = ntohl (sw_if_index);
7293   mp->enable_disable = enable;
7294
7295   S (mp);
7296   W (ret);
7297   return ret;
7298 }
7299
7300 static int
7301 api_mpls_tunnel_add_del (vat_main_t * vam)
7302 {
7303   unformat_input_t *i = vam->input;
7304   vl_api_mpls_tunnel_add_del_t *mp;
7305
7306   u8 is_add = 1;
7307   u8 l2_only = 0;
7308   u32 sw_if_index = ~0;
7309   u32 next_hop_sw_if_index = ~0;
7310   u32 next_hop_proto_is_ip4 = 1;
7311
7312   u32 next_hop_table_id = 0;
7313   ip4_address_t v4_next_hop_address = {
7314     .as_u32 = 0,
7315   };
7316   ip6_address_t v6_next_hop_address = { {0} };
7317   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID, *labels = NULL;
7318   int ret;
7319
7320   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7321     {
7322       if (unformat (i, "add"))
7323         is_add = 1;
7324       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
7325         is_add = 0;
7326       else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
7327         ;
7328       else if (unformat (i, "via %U",
7329                          unformat_ip4_address, &v4_next_hop_address))
7330         {
7331           next_hop_proto_is_ip4 = 1;
7332         }
7333       else if (unformat (i, "via %U",
7334                          unformat_ip6_address, &v6_next_hop_address))
7335         {
7336           next_hop_proto_is_ip4 = 0;
7337         }
7338       else if (unformat (i, "l2-only"))
7339         l2_only = 1;
7340       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
7341         ;
7342       else if (unformat (i, "out-label %d", &next_hop_out_label))
7343         vec_add1 (labels, ntohl (next_hop_out_label));
7344       else
7345         {
7346           clib_warning ("parse error '%U'", format_unformat_error, i);
7347           return -99;
7348         }
7349     }
7350
7351   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (mpls_label_t) * vec_len (labels));
7352
7353   mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
7354   mp->mt_sw_if_index = ntohl (sw_if_index);
7355   mp->mt_is_add = is_add;
7356   mp->mt_l2_only = l2_only;
7357   mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
7358   mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
7359
7360   mp->mt_next_hop_n_out_labels = vec_len (labels);
7361
7362   if (0 != mp->mt_next_hop_n_out_labels)
7363     {
7364       clib_memcpy (mp->mt_next_hop_out_label_stack, labels,
7365                    sizeof (mpls_label_t) * mp->mt_next_hop_n_out_labels);
7366       vec_free (labels);
7367     }
7368
7369   if (next_hop_proto_is_ip4)
7370     {
7371       clib_memcpy (mp->mt_next_hop,
7372                    &v4_next_hop_address, sizeof (v4_next_hop_address));
7373     }
7374   else
7375     {
7376       clib_memcpy (mp->mt_next_hop,
7377                    &v6_next_hop_address, sizeof (v6_next_hop_address));
7378     }
7379
7380   S (mp);
7381   W (ret);
7382   return ret;
7383 }
7384
7385 static int
7386 api_sw_interface_set_unnumbered (vat_main_t * vam)
7387 {
7388   unformat_input_t *i = vam->input;
7389   vl_api_sw_interface_set_unnumbered_t *mp;
7390   u32 sw_if_index;
7391   u32 unnum_sw_index = ~0;
7392   u8 is_add = 1;
7393   u8 sw_if_index_set = 0;
7394   int ret;
7395
7396   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7397     {
7398       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7399         sw_if_index_set = 1;
7400       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7401         sw_if_index_set = 1;
7402       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
7403         ;
7404       else if (unformat (i, "del"))
7405         is_add = 0;
7406       else
7407         {
7408           clib_warning ("parse error '%U'", format_unformat_error, i);
7409           return -99;
7410         }
7411     }
7412
7413   if (sw_if_index_set == 0)
7414     {
7415       errmsg ("missing interface name or sw_if_index");
7416       return -99;
7417     }
7418
7419   M (SW_INTERFACE_SET_UNNUMBERED, mp);
7420
7421   mp->sw_if_index = ntohl (sw_if_index);
7422   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
7423   mp->is_add = is_add;
7424
7425   S (mp);
7426   W (ret);
7427   return ret;
7428 }
7429
7430 static int
7431 api_ip_neighbor_add_del (vat_main_t * vam)
7432 {
7433   unformat_input_t *i = vam->input;
7434   vl_api_ip_neighbor_add_del_t *mp;
7435   u32 sw_if_index;
7436   u8 sw_if_index_set = 0;
7437   u8 is_add = 1;
7438   u8 is_static = 0;
7439   u8 is_no_fib_entry = 0;
7440   u8 mac_address[6];
7441   u8 mac_set = 0;
7442   u8 v4_address_set = 0;
7443   u8 v6_address_set = 0;
7444   ip4_address_t v4address;
7445   ip6_address_t v6address;
7446   int ret;
7447
7448   memset (mac_address, 0, sizeof (mac_address));
7449
7450   /* Parse args required to build the message */
7451   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7452     {
7453       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7454         {
7455           mac_set = 1;
7456         }
7457       else if (unformat (i, "del"))
7458         is_add = 0;
7459       else
7460         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7461         sw_if_index_set = 1;
7462       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7463         sw_if_index_set = 1;
7464       else if (unformat (i, "is_static"))
7465         is_static = 1;
7466       else if (unformat (i, "no-fib-entry"))
7467         is_no_fib_entry = 1;
7468       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
7469         v4_address_set = 1;
7470       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
7471         v6_address_set = 1;
7472       else
7473         {
7474           clib_warning ("parse error '%U'", format_unformat_error, i);
7475           return -99;
7476         }
7477     }
7478
7479   if (sw_if_index_set == 0)
7480     {
7481       errmsg ("missing interface name or sw_if_index");
7482       return -99;
7483     }
7484   if (v4_address_set && v6_address_set)
7485     {
7486       errmsg ("both v4 and v6 addresses set");
7487       return -99;
7488     }
7489   if (!v4_address_set && !v6_address_set)
7490     {
7491       errmsg ("no address set");
7492       return -99;
7493     }
7494
7495   /* Construct the API message */
7496   M (IP_NEIGHBOR_ADD_DEL, mp);
7497
7498   mp->sw_if_index = ntohl (sw_if_index);
7499   mp->is_add = is_add;
7500   mp->is_static = is_static;
7501   mp->is_no_adj_fib = is_no_fib_entry;
7502   if (mac_set)
7503     clib_memcpy (mp->mac_address, mac_address, 6);
7504   if (v6_address_set)
7505     {
7506       mp->is_ipv6 = 1;
7507       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
7508     }
7509   else
7510     {
7511       /* mp->is_ipv6 = 0; via memset in M macro above */
7512       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
7513     }
7514
7515   /* send it... */
7516   S (mp);
7517
7518   /* Wait for a reply, return good/bad news  */
7519   W (ret);
7520   return ret;
7521 }
7522
7523 static int
7524 api_reset_vrf (vat_main_t * vam)
7525 {
7526   unformat_input_t *i = vam->input;
7527   vl_api_reset_vrf_t *mp;
7528   u32 vrf_id = 0;
7529   u8 is_ipv6 = 0;
7530   u8 vrf_id_set = 0;
7531   int ret;
7532
7533   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7534     {
7535       if (unformat (i, "vrf %d", &vrf_id))
7536         vrf_id_set = 1;
7537       else if (unformat (i, "ipv6"))
7538         is_ipv6 = 1;
7539       else
7540         {
7541           clib_warning ("parse error '%U'", format_unformat_error, i);
7542           return -99;
7543         }
7544     }
7545
7546   if (vrf_id_set == 0)
7547     {
7548       errmsg ("missing vrf id");
7549       return -99;
7550     }
7551
7552   M (RESET_VRF, mp);
7553
7554   mp->vrf_id = ntohl (vrf_id);
7555   mp->is_ipv6 = is_ipv6;
7556
7557   S (mp);
7558   W (ret);
7559   return ret;
7560 }
7561
7562 static int
7563 api_create_vlan_subif (vat_main_t * vam)
7564 {
7565   unformat_input_t *i = vam->input;
7566   vl_api_create_vlan_subif_t *mp;
7567   u32 sw_if_index;
7568   u8 sw_if_index_set = 0;
7569   u32 vlan_id;
7570   u8 vlan_id_set = 0;
7571   int ret;
7572
7573   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7574     {
7575       if (unformat (i, "sw_if_index %d", &sw_if_index))
7576         sw_if_index_set = 1;
7577       else
7578         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7579         sw_if_index_set = 1;
7580       else if (unformat (i, "vlan %d", &vlan_id))
7581         vlan_id_set = 1;
7582       else
7583         {
7584           clib_warning ("parse error '%U'", format_unformat_error, i);
7585           return -99;
7586         }
7587     }
7588
7589   if (sw_if_index_set == 0)
7590     {
7591       errmsg ("missing interface name or sw_if_index");
7592       return -99;
7593     }
7594
7595   if (vlan_id_set == 0)
7596     {
7597       errmsg ("missing vlan_id");
7598       return -99;
7599     }
7600   M (CREATE_VLAN_SUBIF, mp);
7601
7602   mp->sw_if_index = ntohl (sw_if_index);
7603   mp->vlan_id = ntohl (vlan_id);
7604
7605   S (mp);
7606   W (ret);
7607   return ret;
7608 }
7609
7610 #define foreach_create_subif_bit                \
7611 _(no_tags)                                      \
7612 _(one_tag)                                      \
7613 _(two_tags)                                     \
7614 _(dot1ad)                                       \
7615 _(exact_match)                                  \
7616 _(default_sub)                                  \
7617 _(outer_vlan_id_any)                            \
7618 _(inner_vlan_id_any)
7619
7620 static int
7621 api_create_subif (vat_main_t * vam)
7622 {
7623   unformat_input_t *i = vam->input;
7624   vl_api_create_subif_t *mp;
7625   u32 sw_if_index;
7626   u8 sw_if_index_set = 0;
7627   u32 sub_id;
7628   u8 sub_id_set = 0;
7629   u32 no_tags = 0;
7630   u32 one_tag = 0;
7631   u32 two_tags = 0;
7632   u32 dot1ad = 0;
7633   u32 exact_match = 0;
7634   u32 default_sub = 0;
7635   u32 outer_vlan_id_any = 0;
7636   u32 inner_vlan_id_any = 0;
7637   u32 tmp;
7638   u16 outer_vlan_id = 0;
7639   u16 inner_vlan_id = 0;
7640   int ret;
7641
7642   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7643     {
7644       if (unformat (i, "sw_if_index %d", &sw_if_index))
7645         sw_if_index_set = 1;
7646       else
7647         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7648         sw_if_index_set = 1;
7649       else if (unformat (i, "sub_id %d", &sub_id))
7650         sub_id_set = 1;
7651       else if (unformat (i, "outer_vlan_id %d", &tmp))
7652         outer_vlan_id = tmp;
7653       else if (unformat (i, "inner_vlan_id %d", &tmp))
7654         inner_vlan_id = tmp;
7655
7656 #define _(a) else if (unformat (i, #a)) a = 1 ;
7657       foreach_create_subif_bit
7658 #undef _
7659         else
7660         {
7661           clib_warning ("parse error '%U'", format_unformat_error, i);
7662           return -99;
7663         }
7664     }
7665
7666   if (sw_if_index_set == 0)
7667     {
7668       errmsg ("missing interface name or sw_if_index");
7669       return -99;
7670     }
7671
7672   if (sub_id_set == 0)
7673     {
7674       errmsg ("missing sub_id");
7675       return -99;
7676     }
7677   M (CREATE_SUBIF, mp);
7678
7679   mp->sw_if_index = ntohl (sw_if_index);
7680   mp->sub_id = ntohl (sub_id);
7681
7682 #define _(a) mp->a = a;
7683   foreach_create_subif_bit;
7684 #undef _
7685
7686   mp->outer_vlan_id = ntohs (outer_vlan_id);
7687   mp->inner_vlan_id = ntohs (inner_vlan_id);
7688
7689   S (mp);
7690   W (ret);
7691   return ret;
7692 }
7693
7694 static int
7695 api_oam_add_del (vat_main_t * vam)
7696 {
7697   unformat_input_t *i = vam->input;
7698   vl_api_oam_add_del_t *mp;
7699   u32 vrf_id = 0;
7700   u8 is_add = 1;
7701   ip4_address_t src, dst;
7702   u8 src_set = 0;
7703   u8 dst_set = 0;
7704   int ret;
7705
7706   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7707     {
7708       if (unformat (i, "vrf %d", &vrf_id))
7709         ;
7710       else if (unformat (i, "src %U", unformat_ip4_address, &src))
7711         src_set = 1;
7712       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
7713         dst_set = 1;
7714       else if (unformat (i, "del"))
7715         is_add = 0;
7716       else
7717         {
7718           clib_warning ("parse error '%U'", format_unformat_error, i);
7719           return -99;
7720         }
7721     }
7722
7723   if (src_set == 0)
7724     {
7725       errmsg ("missing src addr");
7726       return -99;
7727     }
7728
7729   if (dst_set == 0)
7730     {
7731       errmsg ("missing dst addr");
7732       return -99;
7733     }
7734
7735   M (OAM_ADD_DEL, mp);
7736
7737   mp->vrf_id = ntohl (vrf_id);
7738   mp->is_add = is_add;
7739   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
7740   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
7741
7742   S (mp);
7743   W (ret);
7744   return ret;
7745 }
7746
7747 static int
7748 api_reset_fib (vat_main_t * vam)
7749 {
7750   unformat_input_t *i = vam->input;
7751   vl_api_reset_fib_t *mp;
7752   u32 vrf_id = 0;
7753   u8 is_ipv6 = 0;
7754   u8 vrf_id_set = 0;
7755
7756   int ret;
7757   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7758     {
7759       if (unformat (i, "vrf %d", &vrf_id))
7760         vrf_id_set = 1;
7761       else if (unformat (i, "ipv6"))
7762         is_ipv6 = 1;
7763       else
7764         {
7765           clib_warning ("parse error '%U'", format_unformat_error, i);
7766           return -99;
7767         }
7768     }
7769
7770   if (vrf_id_set == 0)
7771     {
7772       errmsg ("missing vrf id");
7773       return -99;
7774     }
7775
7776   M (RESET_FIB, mp);
7777
7778   mp->vrf_id = ntohl (vrf_id);
7779   mp->is_ipv6 = is_ipv6;
7780
7781   S (mp);
7782   W (ret);
7783   return ret;
7784 }
7785
7786 static int
7787 api_dhcp_proxy_config (vat_main_t * vam)
7788 {
7789   unformat_input_t *i = vam->input;
7790   vl_api_dhcp_proxy_config_t *mp;
7791   u32 rx_vrf_id = 0;
7792   u32 server_vrf_id = 0;
7793   u8 is_add = 1;
7794   u8 v4_address_set = 0;
7795   u8 v6_address_set = 0;
7796   ip4_address_t v4address;
7797   ip6_address_t v6address;
7798   u8 v4_src_address_set = 0;
7799   u8 v6_src_address_set = 0;
7800   ip4_address_t v4srcaddress;
7801   ip6_address_t v6srcaddress;
7802   int ret;
7803
7804   /* Parse args required to build the message */
7805   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7806     {
7807       if (unformat (i, "del"))
7808         is_add = 0;
7809       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
7810         ;
7811       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
7812         ;
7813       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
7814         v4_address_set = 1;
7815       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
7816         v6_address_set = 1;
7817       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
7818         v4_src_address_set = 1;
7819       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
7820         v6_src_address_set = 1;
7821       else
7822         break;
7823     }
7824
7825   if (v4_address_set && v6_address_set)
7826     {
7827       errmsg ("both v4 and v6 server addresses set");
7828       return -99;
7829     }
7830   if (!v4_address_set && !v6_address_set)
7831     {
7832       errmsg ("no server addresses set");
7833       return -99;
7834     }
7835
7836   if (v4_src_address_set && v6_src_address_set)
7837     {
7838       errmsg ("both v4 and v6  src addresses set");
7839       return -99;
7840     }
7841   if (!v4_src_address_set && !v6_src_address_set)
7842     {
7843       errmsg ("no src addresses set");
7844       return -99;
7845     }
7846
7847   if (!(v4_src_address_set && v4_address_set) &&
7848       !(v6_src_address_set && v6_address_set))
7849     {
7850       errmsg ("no matching server and src addresses set");
7851       return -99;
7852     }
7853
7854   /* Construct the API message */
7855   M (DHCP_PROXY_CONFIG, mp);
7856
7857   mp->is_add = is_add;
7858   mp->rx_vrf_id = ntohl (rx_vrf_id);
7859   mp->server_vrf_id = ntohl (server_vrf_id);
7860   if (v6_address_set)
7861     {
7862       mp->is_ipv6 = 1;
7863       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
7864       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
7865     }
7866   else
7867     {
7868       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
7869       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
7870     }
7871
7872   /* send it... */
7873   S (mp);
7874
7875   /* Wait for a reply, return good/bad news  */
7876   W (ret);
7877   return ret;
7878 }
7879
7880 #define vl_api_dhcp_proxy_details_t_endian vl_noop_handler
7881 #define vl_api_dhcp_proxy_details_t_print vl_noop_handler
7882
7883 static void
7884 vl_api_dhcp_proxy_details_t_handler (vl_api_dhcp_proxy_details_t * mp)
7885 {
7886   vat_main_t *vam = &vat_main;
7887   u32 i, count = mp->count;
7888   vl_api_dhcp_server_t *s;
7889
7890   if (mp->is_ipv6)
7891     print (vam->ofp,
7892            "RX Table-ID %d, Source Address %U, VSS FIB-ID %d, VSS OUI %d",
7893            ntohl (mp->rx_vrf_id),
7894            format_ip6_address, mp->dhcp_src_address,
7895            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
7896   else
7897     print (vam->ofp,
7898            "RX Table-ID %d, Source Address %U, VSS FIB-ID %d, VSS OUI %d",
7899            ntohl (mp->rx_vrf_id),
7900            format_ip4_address, mp->dhcp_src_address,
7901            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
7902
7903   for (i = 0; i < count; i++)
7904     {
7905       s = &mp->servers[i];
7906
7907       if (mp->is_ipv6)
7908         print (vam->ofp,
7909                " Server Table-ID %d, Server Address %U",
7910                ntohl (s->server_vrf_id), format_ip6_address, s->dhcp_server);
7911       else
7912         print (vam->ofp,
7913                " Server Table-ID %d, Server Address %U",
7914                ntohl (s->server_vrf_id), format_ip4_address, s->dhcp_server);
7915     }
7916 }
7917
7918 static void vl_api_dhcp_proxy_details_t_handler_json
7919   (vl_api_dhcp_proxy_details_t * mp)
7920 {
7921   vat_main_t *vam = &vat_main;
7922   vat_json_node_t *node = NULL;
7923   u32 i, count = mp->count;
7924   struct in_addr ip4;
7925   struct in6_addr ip6;
7926   vl_api_dhcp_server_t *s;
7927
7928   if (VAT_JSON_ARRAY != vam->json_tree.type)
7929     {
7930       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
7931       vat_json_init_array (&vam->json_tree);
7932     }
7933   node = vat_json_array_add (&vam->json_tree);
7934
7935   vat_json_init_object (node);
7936   vat_json_object_add_uint (node, "rx-table-id", ntohl (mp->rx_vrf_id));
7937   vat_json_object_add_uint (node, "vss-fib-id", ntohl (mp->vss_fib_id));
7938   vat_json_object_add_uint (node, "vss-oui", ntohl (mp->vss_oui));
7939
7940   if (mp->is_ipv6)
7941     {
7942       clib_memcpy (&ip6, &mp->dhcp_src_address, sizeof (ip6));
7943       vat_json_object_add_ip6 (node, "src_address", ip6);
7944     }
7945   else
7946     {
7947       clib_memcpy (&ip4, &mp->dhcp_src_address, sizeof (ip4));
7948       vat_json_object_add_ip4 (node, "src_address", ip4);
7949     }
7950
7951   for (i = 0; i < count; i++)
7952     {
7953       s = &mp->servers[i];
7954
7955       vat_json_object_add_uint (node, "server-table-id",
7956                                 ntohl (s->server_vrf_id));
7957
7958       if (mp->is_ipv6)
7959         {
7960           clib_memcpy (&ip4, &s->dhcp_server, sizeof (ip4));
7961           vat_json_object_add_ip4 (node, "src_address", ip4);
7962         }
7963       else
7964         {
7965           clib_memcpy (&ip6, &s->dhcp_server, sizeof (ip6));
7966           vat_json_object_add_ip6 (node, "server_address", ip6);
7967         }
7968     }
7969 }
7970
7971 static int
7972 api_dhcp_proxy_dump (vat_main_t * vam)
7973 {
7974   unformat_input_t *i = vam->input;
7975   vl_api_control_ping_t *mp_ping;
7976   vl_api_dhcp_proxy_dump_t *mp;
7977   u8 is_ipv6 = 0;
7978   int ret;
7979
7980   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7981     {
7982       if (unformat (i, "ipv6"))
7983         is_ipv6 = 1;
7984       else
7985         {
7986           clib_warning ("parse error '%U'", format_unformat_error, i);
7987           return -99;
7988         }
7989     }
7990
7991   M (DHCP_PROXY_DUMP, mp);
7992
7993   mp->is_ip6 = is_ipv6;
7994   S (mp);
7995
7996   /* Use a control ping for synchronization */
7997   M (CONTROL_PING, mp_ping);
7998   S (mp_ping);
7999
8000   W (ret);
8001   return ret;
8002 }
8003
8004 static int
8005 api_dhcp_proxy_set_vss (vat_main_t * vam)
8006 {
8007   unformat_input_t *i = vam->input;
8008   vl_api_dhcp_proxy_set_vss_t *mp;
8009   u8 is_ipv6 = 0;
8010   u8 is_add = 1;
8011   u32 tbl_id;
8012   u8 tbl_id_set = 0;
8013   u32 oui;
8014   u8 oui_set = 0;
8015   u32 fib_id;
8016   u8 fib_id_set = 0;
8017   int ret;
8018
8019   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8020     {
8021       if (unformat (i, "tbl_id %d", &tbl_id))
8022         tbl_id_set = 1;
8023       if (unformat (i, "fib_id %d", &fib_id))
8024         fib_id_set = 1;
8025       if (unformat (i, "oui %d", &oui))
8026         oui_set = 1;
8027       else if (unformat (i, "ipv6"))
8028         is_ipv6 = 1;
8029       else if (unformat (i, "del"))
8030         is_add = 0;
8031       else
8032         {
8033           clib_warning ("parse error '%U'", format_unformat_error, i);
8034           return -99;
8035         }
8036     }
8037
8038   if (tbl_id_set == 0)
8039     {
8040       errmsg ("missing tbl id");
8041       return -99;
8042     }
8043
8044   if (fib_id_set == 0)
8045     {
8046       errmsg ("missing fib id");
8047       return -99;
8048     }
8049   if (oui_set == 0)
8050     {
8051       errmsg ("missing oui");
8052       return -99;
8053     }
8054
8055   M (DHCP_PROXY_SET_VSS, mp);
8056   mp->tbl_id = ntohl (tbl_id);
8057   mp->fib_id = ntohl (fib_id);
8058   mp->oui = ntohl (oui);
8059   mp->is_ipv6 = is_ipv6;
8060   mp->is_add = is_add;
8061
8062   S (mp);
8063   W (ret);
8064   return ret;
8065 }
8066
8067 static int
8068 api_dhcp_client_config (vat_main_t * vam)
8069 {
8070   unformat_input_t *i = vam->input;
8071   vl_api_dhcp_client_config_t *mp;
8072   u32 sw_if_index;
8073   u8 sw_if_index_set = 0;
8074   u8 is_add = 1;
8075   u8 *hostname = 0;
8076   u8 disable_event = 0;
8077   int ret;
8078
8079   /* Parse args required to build the message */
8080   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8081     {
8082       if (unformat (i, "del"))
8083         is_add = 0;
8084       else
8085         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8086         sw_if_index_set = 1;
8087       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8088         sw_if_index_set = 1;
8089       else if (unformat (i, "hostname %s", &hostname))
8090         ;
8091       else if (unformat (i, "disable_event"))
8092         disable_event = 1;
8093       else
8094         break;
8095     }
8096
8097   if (sw_if_index_set == 0)
8098     {
8099       errmsg ("missing interface name or sw_if_index");
8100       return -99;
8101     }
8102
8103   if (vec_len (hostname) > 63)
8104     {
8105       errmsg ("hostname too long");
8106     }
8107   vec_add1 (hostname, 0);
8108
8109   /* Construct the API message */
8110   M (DHCP_CLIENT_CONFIG, mp);
8111
8112   mp->sw_if_index = htonl (sw_if_index);
8113   clib_memcpy (mp->hostname, hostname, vec_len (hostname));
8114   vec_free (hostname);
8115   mp->is_add = is_add;
8116   mp->want_dhcp_event = disable_event ? 0 : 1;
8117   mp->pid = htonl (getpid ());
8118
8119   /* send it... */
8120   S (mp);
8121
8122   /* Wait for a reply, return good/bad news  */
8123   W (ret);
8124   return ret;
8125 }
8126
8127 static int
8128 api_set_ip_flow_hash (vat_main_t * vam)
8129 {
8130   unformat_input_t *i = vam->input;
8131   vl_api_set_ip_flow_hash_t *mp;
8132   u32 vrf_id = 0;
8133   u8 is_ipv6 = 0;
8134   u8 vrf_id_set = 0;
8135   u8 src = 0;
8136   u8 dst = 0;
8137   u8 sport = 0;
8138   u8 dport = 0;
8139   u8 proto = 0;
8140   u8 reverse = 0;
8141   int ret;
8142
8143   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8144     {
8145       if (unformat (i, "vrf %d", &vrf_id))
8146         vrf_id_set = 1;
8147       else if (unformat (i, "ipv6"))
8148         is_ipv6 = 1;
8149       else if (unformat (i, "src"))
8150         src = 1;
8151       else if (unformat (i, "dst"))
8152         dst = 1;
8153       else if (unformat (i, "sport"))
8154         sport = 1;
8155       else if (unformat (i, "dport"))
8156         dport = 1;
8157       else if (unformat (i, "proto"))
8158         proto = 1;
8159       else if (unformat (i, "reverse"))
8160         reverse = 1;
8161
8162       else
8163         {
8164           clib_warning ("parse error '%U'", format_unformat_error, i);
8165           return -99;
8166         }
8167     }
8168
8169   if (vrf_id_set == 0)
8170     {
8171       errmsg ("missing vrf id");
8172       return -99;
8173     }
8174
8175   M (SET_IP_FLOW_HASH, mp);
8176   mp->src = src;
8177   mp->dst = dst;
8178   mp->sport = sport;
8179   mp->dport = dport;
8180   mp->proto = proto;
8181   mp->reverse = reverse;
8182   mp->vrf_id = ntohl (vrf_id);
8183   mp->is_ipv6 = is_ipv6;
8184
8185   S (mp);
8186   W (ret);
8187   return ret;
8188 }
8189
8190 static int
8191 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
8192 {
8193   unformat_input_t *i = vam->input;
8194   vl_api_sw_interface_ip6_enable_disable_t *mp;
8195   u32 sw_if_index;
8196   u8 sw_if_index_set = 0;
8197   u8 enable = 0;
8198   int ret;
8199
8200   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8201     {
8202       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8203         sw_if_index_set = 1;
8204       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8205         sw_if_index_set = 1;
8206       else if (unformat (i, "enable"))
8207         enable = 1;
8208       else if (unformat (i, "disable"))
8209         enable = 0;
8210       else
8211         {
8212           clib_warning ("parse error '%U'", format_unformat_error, i);
8213           return -99;
8214         }
8215     }
8216
8217   if (sw_if_index_set == 0)
8218     {
8219       errmsg ("missing interface name or sw_if_index");
8220       return -99;
8221     }
8222
8223   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
8224
8225   mp->sw_if_index = ntohl (sw_if_index);
8226   mp->enable = enable;
8227
8228   S (mp);
8229   W (ret);
8230   return ret;
8231 }
8232
8233 static int
8234 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
8235 {
8236   unformat_input_t *i = vam->input;
8237   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
8238   u32 sw_if_index;
8239   u8 sw_if_index_set = 0;
8240   u8 v6_address_set = 0;
8241   ip6_address_t v6address;
8242   int ret;
8243
8244   /* Parse args required to build the message */
8245   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8246     {
8247       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8248         sw_if_index_set = 1;
8249       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8250         sw_if_index_set = 1;
8251       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
8252         v6_address_set = 1;
8253       else
8254         break;
8255     }
8256
8257   if (sw_if_index_set == 0)
8258     {
8259       errmsg ("missing interface name or sw_if_index");
8260       return -99;
8261     }
8262   if (!v6_address_set)
8263     {
8264       errmsg ("no address set");
8265       return -99;
8266     }
8267
8268   /* Construct the API message */
8269   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS, mp);
8270
8271   mp->sw_if_index = ntohl (sw_if_index);
8272   clib_memcpy (mp->address, &v6address, sizeof (v6address));
8273
8274   /* send it... */
8275   S (mp);
8276
8277   /* Wait for a reply, return good/bad news  */
8278   W (ret);
8279   return ret;
8280 }
8281
8282 static int
8283 api_ip6nd_proxy_add_del (vat_main_t * vam)
8284 {
8285   unformat_input_t *i = vam->input;
8286   vl_api_ip6nd_proxy_add_del_t *mp;
8287   u32 sw_if_index = ~0;
8288   u8 v6_address_set = 0;
8289   ip6_address_t v6address;
8290   u8 is_del = 0;
8291   int ret;
8292
8293   /* Parse args required to build the message */
8294   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8295     {
8296       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8297         ;
8298       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8299         ;
8300       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
8301         v6_address_set = 1;
8302       if (unformat (i, "del"))
8303         is_del = 1;
8304       else
8305         {
8306           clib_warning ("parse error '%U'", format_unformat_error, i);
8307           return -99;
8308         }
8309     }
8310
8311   if (sw_if_index == ~0)
8312     {
8313       errmsg ("missing interface name or sw_if_index");
8314       return -99;
8315     }
8316   if (!v6_address_set)
8317     {
8318       errmsg ("no address set");
8319       return -99;
8320     }
8321
8322   /* Construct the API message */
8323   M (IP6ND_PROXY_ADD_DEL, mp);
8324
8325   mp->is_del = is_del;
8326   mp->sw_if_index = ntohl (sw_if_index);
8327   clib_memcpy (mp->address, &v6address, sizeof (v6address));
8328
8329   /* send it... */
8330   S (mp);
8331
8332   /* Wait for a reply, return good/bad news  */
8333   W (ret);
8334   return ret;
8335 }
8336
8337 static int
8338 api_ip6nd_proxy_dump (vat_main_t * vam)
8339 {
8340   vl_api_ip6nd_proxy_dump_t *mp;
8341   vl_api_control_ping_t *mp_ping;
8342   int ret;
8343
8344   M (IP6ND_PROXY_DUMP, mp);
8345
8346   S (mp);
8347
8348   /* Use a control ping for synchronization */
8349   M (CONTROL_PING, mp_ping);
8350   S (mp_ping);
8351
8352   W (ret);
8353   return ret;
8354 }
8355
8356 static void vl_api_ip6nd_proxy_details_t_handler
8357   (vl_api_ip6nd_proxy_details_t * mp)
8358 {
8359   vat_main_t *vam = &vat_main;
8360
8361   print (vam->ofp, "host %U sw_if_index %d",
8362          format_ip6_address, mp->address, ntohl (mp->sw_if_index));
8363 }
8364
8365 static void vl_api_ip6nd_proxy_details_t_handler_json
8366   (vl_api_ip6nd_proxy_details_t * mp)
8367 {
8368   vat_main_t *vam = &vat_main;
8369   struct in6_addr ip6;
8370   vat_json_node_t *node = NULL;
8371
8372   if (VAT_JSON_ARRAY != vam->json_tree.type)
8373     {
8374       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
8375       vat_json_init_array (&vam->json_tree);
8376     }
8377   node = vat_json_array_add (&vam->json_tree);
8378
8379   vat_json_init_object (node);
8380   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
8381
8382   clib_memcpy (&ip6, mp->address, sizeof (ip6));
8383   vat_json_object_add_ip6 (node, "host", ip6);
8384 }
8385
8386 static int
8387 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
8388 {
8389   unformat_input_t *i = vam->input;
8390   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
8391   u32 sw_if_index;
8392   u8 sw_if_index_set = 0;
8393   u32 address_length = 0;
8394   u8 v6_address_set = 0;
8395   ip6_address_t v6address;
8396   u8 use_default = 0;
8397   u8 no_advertise = 0;
8398   u8 off_link = 0;
8399   u8 no_autoconfig = 0;
8400   u8 no_onlink = 0;
8401   u8 is_no = 0;
8402   u32 val_lifetime = 0;
8403   u32 pref_lifetime = 0;
8404   int ret;
8405
8406   /* Parse args required to build the message */
8407   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8408     {
8409       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8410         sw_if_index_set = 1;
8411       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8412         sw_if_index_set = 1;
8413       else if (unformat (i, "%U/%d",
8414                          unformat_ip6_address, &v6address, &address_length))
8415         v6_address_set = 1;
8416       else if (unformat (i, "val_life %d", &val_lifetime))
8417         ;
8418       else if (unformat (i, "pref_life %d", &pref_lifetime))
8419         ;
8420       else if (unformat (i, "def"))
8421         use_default = 1;
8422       else if (unformat (i, "noadv"))
8423         no_advertise = 1;
8424       else if (unformat (i, "offl"))
8425         off_link = 1;
8426       else if (unformat (i, "noauto"))
8427         no_autoconfig = 1;
8428       else if (unformat (i, "nolink"))
8429         no_onlink = 1;
8430       else if (unformat (i, "isno"))
8431         is_no = 1;
8432       else
8433         {
8434           clib_warning ("parse error '%U'", format_unformat_error, i);
8435           return -99;
8436         }
8437     }
8438
8439   if (sw_if_index_set == 0)
8440     {
8441       errmsg ("missing interface name or sw_if_index");
8442       return -99;
8443     }
8444   if (!v6_address_set)
8445     {
8446       errmsg ("no address set");
8447       return -99;
8448     }
8449
8450   /* Construct the API message */
8451   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
8452
8453   mp->sw_if_index = ntohl (sw_if_index);
8454   clib_memcpy (mp->address, &v6address, sizeof (v6address));
8455   mp->address_length = address_length;
8456   mp->use_default = use_default;
8457   mp->no_advertise = no_advertise;
8458   mp->off_link = off_link;
8459   mp->no_autoconfig = no_autoconfig;
8460   mp->no_onlink = no_onlink;
8461   mp->is_no = is_no;
8462   mp->val_lifetime = ntohl (val_lifetime);
8463   mp->pref_lifetime = ntohl (pref_lifetime);
8464
8465   /* send it... */
8466   S (mp);
8467
8468   /* Wait for a reply, return good/bad news  */
8469   W (ret);
8470   return ret;
8471 }
8472
8473 static int
8474 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
8475 {
8476   unformat_input_t *i = vam->input;
8477   vl_api_sw_interface_ip6nd_ra_config_t *mp;
8478   u32 sw_if_index;
8479   u8 sw_if_index_set = 0;
8480   u8 suppress = 0;
8481   u8 managed = 0;
8482   u8 other = 0;
8483   u8 ll_option = 0;
8484   u8 send_unicast = 0;
8485   u8 cease = 0;
8486   u8 is_no = 0;
8487   u8 default_router = 0;
8488   u32 max_interval = 0;
8489   u32 min_interval = 0;
8490   u32 lifetime = 0;
8491   u32 initial_count = 0;
8492   u32 initial_interval = 0;
8493   int ret;
8494
8495
8496   /* Parse args required to build the message */
8497   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8498     {
8499       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8500         sw_if_index_set = 1;
8501       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8502         sw_if_index_set = 1;
8503       else if (unformat (i, "maxint %d", &max_interval))
8504         ;
8505       else if (unformat (i, "minint %d", &min_interval))
8506         ;
8507       else if (unformat (i, "life %d", &lifetime))
8508         ;
8509       else if (unformat (i, "count %d", &initial_count))
8510         ;
8511       else if (unformat (i, "interval %d", &initial_interval))
8512         ;
8513       else if (unformat (i, "suppress") || unformat (i, "surpress"))
8514         suppress = 1;
8515       else if (unformat (i, "managed"))
8516         managed = 1;
8517       else if (unformat (i, "other"))
8518         other = 1;
8519       else if (unformat (i, "ll"))
8520         ll_option = 1;
8521       else if (unformat (i, "send"))
8522         send_unicast = 1;
8523       else if (unformat (i, "cease"))
8524         cease = 1;
8525       else if (unformat (i, "isno"))
8526         is_no = 1;
8527       else if (unformat (i, "def"))
8528         default_router = 1;
8529       else
8530         {
8531           clib_warning ("parse error '%U'", format_unformat_error, i);
8532           return -99;
8533         }
8534     }
8535
8536   if (sw_if_index_set == 0)
8537     {
8538       errmsg ("missing interface name or sw_if_index");
8539       return -99;
8540     }
8541
8542   /* Construct the API message */
8543   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
8544
8545   mp->sw_if_index = ntohl (sw_if_index);
8546   mp->max_interval = ntohl (max_interval);
8547   mp->min_interval = ntohl (min_interval);
8548   mp->lifetime = ntohl (lifetime);
8549   mp->initial_count = ntohl (initial_count);
8550   mp->initial_interval = ntohl (initial_interval);
8551   mp->suppress = suppress;
8552   mp->managed = managed;
8553   mp->other = other;
8554   mp->ll_option = ll_option;
8555   mp->send_unicast = send_unicast;
8556   mp->cease = cease;
8557   mp->is_no = is_no;
8558   mp->default_router = default_router;
8559
8560   /* send it... */
8561   S (mp);
8562
8563   /* Wait for a reply, return good/bad news  */
8564   W (ret);
8565   return ret;
8566 }
8567
8568 static int
8569 api_set_arp_neighbor_limit (vat_main_t * vam)
8570 {
8571   unformat_input_t *i = vam->input;
8572   vl_api_set_arp_neighbor_limit_t *mp;
8573   u32 arp_nbr_limit;
8574   u8 limit_set = 0;
8575   u8 is_ipv6 = 0;
8576   int ret;
8577
8578   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8579     {
8580       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
8581         limit_set = 1;
8582       else if (unformat (i, "ipv6"))
8583         is_ipv6 = 1;
8584       else
8585         {
8586           clib_warning ("parse error '%U'", format_unformat_error, i);
8587           return -99;
8588         }
8589     }
8590
8591   if (limit_set == 0)
8592     {
8593       errmsg ("missing limit value");
8594       return -99;
8595     }
8596
8597   M (SET_ARP_NEIGHBOR_LIMIT, mp);
8598
8599   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
8600   mp->is_ipv6 = is_ipv6;
8601
8602   S (mp);
8603   W (ret);
8604   return ret;
8605 }
8606
8607 static int
8608 api_l2_patch_add_del (vat_main_t * vam)
8609 {
8610   unformat_input_t *i = vam->input;
8611   vl_api_l2_patch_add_del_t *mp;
8612   u32 rx_sw_if_index;
8613   u8 rx_sw_if_index_set = 0;
8614   u32 tx_sw_if_index;
8615   u8 tx_sw_if_index_set = 0;
8616   u8 is_add = 1;
8617   int ret;
8618
8619   /* Parse args required to build the message */
8620   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8621     {
8622       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
8623         rx_sw_if_index_set = 1;
8624       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
8625         tx_sw_if_index_set = 1;
8626       else if (unformat (i, "rx"))
8627         {
8628           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8629             {
8630               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
8631                             &rx_sw_if_index))
8632                 rx_sw_if_index_set = 1;
8633             }
8634           else
8635             break;
8636         }
8637       else if (unformat (i, "tx"))
8638         {
8639           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8640             {
8641               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
8642                             &tx_sw_if_index))
8643                 tx_sw_if_index_set = 1;
8644             }
8645           else
8646             break;
8647         }
8648       else if (unformat (i, "del"))
8649         is_add = 0;
8650       else
8651         break;
8652     }
8653
8654   if (rx_sw_if_index_set == 0)
8655     {
8656       errmsg ("missing rx interface name or rx_sw_if_index");
8657       return -99;
8658     }
8659
8660   if (tx_sw_if_index_set == 0)
8661     {
8662       errmsg ("missing tx interface name or tx_sw_if_index");
8663       return -99;
8664     }
8665
8666   M (L2_PATCH_ADD_DEL, mp);
8667
8668   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
8669   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
8670   mp->is_add = is_add;
8671
8672   S (mp);
8673   W (ret);
8674   return ret;
8675 }
8676
8677 u8 is_del;
8678 u8 localsid_addr[16];
8679 u8 end_psp;
8680 u8 behavior;
8681 u32 sw_if_index;
8682 u32 vlan_index;
8683 u32 fib_table;
8684 u8 nh_addr[16];
8685
8686 static int
8687 api_sr_localsid_add_del (vat_main_t * vam)
8688 {
8689   unformat_input_t *i = vam->input;
8690   vl_api_sr_localsid_add_del_t *mp;
8691
8692   u8 is_del;
8693   ip6_address_t localsid;
8694   u8 end_psp = 0;
8695   u8 behavior = ~0;
8696   u32 sw_if_index;
8697   u32 fib_table = ~(u32) 0;
8698   ip6_address_t next_hop;
8699
8700   bool nexthop_set = 0;
8701
8702   int ret;
8703
8704   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8705     {
8706       if (unformat (i, "del"))
8707         is_del = 1;
8708       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
8709       else if (unformat (i, "next-hop %U", unformat_ip6_address, &next_hop))
8710         nexthop_set = 1;
8711       else if (unformat (i, "behavior %u", &behavior));
8712       else if (unformat (i, "sw_if_index %u", &sw_if_index));
8713       else if (unformat (i, "fib-table %u", &fib_table));
8714       else if (unformat (i, "end.psp %u", &behavior));
8715       else
8716         break;
8717     }
8718
8719   M (SR_LOCALSID_ADD_DEL, mp);
8720
8721   clib_memcpy (mp->localsid_addr, &localsid, sizeof (mp->localsid_addr));
8722   if (nexthop_set)
8723     clib_memcpy (mp->nh_addr, &next_hop, sizeof (mp->nh_addr));
8724   mp->behavior = behavior;
8725   mp->sw_if_index = ntohl (sw_if_index);
8726   mp->fib_table = ntohl (fib_table);
8727   mp->end_psp = end_psp;
8728   mp->is_del = is_del;
8729
8730   S (mp);
8731   W (ret);
8732   return ret;
8733 }
8734
8735 static int
8736 api_ioam_enable (vat_main_t * vam)
8737 {
8738   unformat_input_t *input = vam->input;
8739   vl_api_ioam_enable_t *mp;
8740   u32 id = 0;
8741   int has_trace_option = 0;
8742   int has_pot_option = 0;
8743   int has_seqno_option = 0;
8744   int has_analyse_option = 0;
8745   int ret;
8746
8747   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8748     {
8749       if (unformat (input, "trace"))
8750         has_trace_option = 1;
8751       else if (unformat (input, "pot"))
8752         has_pot_option = 1;
8753       else if (unformat (input, "seqno"))
8754         has_seqno_option = 1;
8755       else if (unformat (input, "analyse"))
8756         has_analyse_option = 1;
8757       else
8758         break;
8759     }
8760   M (IOAM_ENABLE, mp);
8761   mp->id = htons (id);
8762   mp->seqno = has_seqno_option;
8763   mp->analyse = has_analyse_option;
8764   mp->pot_enable = has_pot_option;
8765   mp->trace_enable = has_trace_option;
8766
8767   S (mp);
8768   W (ret);
8769   return ret;
8770 }
8771
8772
8773 static int
8774 api_ioam_disable (vat_main_t * vam)
8775 {
8776   vl_api_ioam_disable_t *mp;
8777   int ret;
8778
8779   M (IOAM_DISABLE, mp);
8780   S (mp);
8781   W (ret);
8782   return ret;
8783 }
8784
8785 #define foreach_tcp_proto_field                 \
8786 _(src_port)                                     \
8787 _(dst_port)
8788
8789 #define foreach_udp_proto_field                 \
8790 _(src_port)                                     \
8791 _(dst_port)
8792
8793 #define foreach_ip4_proto_field                 \
8794 _(src_address)                                  \
8795 _(dst_address)                                  \
8796 _(tos)                                          \
8797 _(length)                                       \
8798 _(fragment_id)                                  \
8799 _(ttl)                                          \
8800 _(protocol)                                     \
8801 _(checksum)
8802
8803 typedef struct
8804 {
8805   u16 src_port, dst_port;
8806 } tcpudp_header_t;
8807
8808 #if VPP_API_TEST_BUILTIN == 0
8809 uword
8810 unformat_tcp_mask (unformat_input_t * input, va_list * args)
8811 {
8812   u8 **maskp = va_arg (*args, u8 **);
8813   u8 *mask = 0;
8814   u8 found_something = 0;
8815   tcp_header_t *tcp;
8816
8817 #define _(a) u8 a=0;
8818   foreach_tcp_proto_field;
8819 #undef _
8820
8821   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8822     {
8823       if (0);
8824 #define _(a) else if (unformat (input, #a)) a=1;
8825       foreach_tcp_proto_field
8826 #undef _
8827         else
8828         break;
8829     }
8830
8831 #define _(a) found_something += a;
8832   foreach_tcp_proto_field;
8833 #undef _
8834
8835   if (found_something == 0)
8836     return 0;
8837
8838   vec_validate (mask, sizeof (*tcp) - 1);
8839
8840   tcp = (tcp_header_t *) mask;
8841
8842 #define _(a) if (a) memset (&tcp->a, 0xff, sizeof (tcp->a));
8843   foreach_tcp_proto_field;
8844 #undef _
8845
8846   *maskp = mask;
8847   return 1;
8848 }
8849
8850 uword
8851 unformat_udp_mask (unformat_input_t * input, va_list * args)
8852 {
8853   u8 **maskp = va_arg (*args, u8 **);
8854   u8 *mask = 0;
8855   u8 found_something = 0;
8856   udp_header_t *udp;
8857
8858 #define _(a) u8 a=0;
8859   foreach_udp_proto_field;
8860 #undef _
8861
8862   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8863     {
8864       if (0);
8865 #define _(a) else if (unformat (input, #a)) a=1;
8866       foreach_udp_proto_field
8867 #undef _
8868         else
8869         break;
8870     }
8871
8872 #define _(a) found_something += a;
8873   foreach_udp_proto_field;
8874 #undef _
8875
8876   if (found_something == 0)
8877     return 0;
8878
8879   vec_validate (mask, sizeof (*udp) - 1);
8880
8881   udp = (udp_header_t *) mask;
8882
8883 #define _(a) if (a) memset (&udp->a, 0xff, sizeof (udp->a));
8884   foreach_udp_proto_field;
8885 #undef _
8886
8887   *maskp = mask;
8888   return 1;
8889 }
8890
8891 uword
8892 unformat_l4_mask (unformat_input_t * input, va_list * args)
8893 {
8894   u8 **maskp = va_arg (*args, u8 **);
8895   u16 src_port = 0, dst_port = 0;
8896   tcpudp_header_t *tcpudp;
8897
8898   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8899     {
8900       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
8901         return 1;
8902       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
8903         return 1;
8904       else if (unformat (input, "src_port"))
8905         src_port = 0xFFFF;
8906       else if (unformat (input, "dst_port"))
8907         dst_port = 0xFFFF;
8908       else
8909         return 0;
8910     }
8911
8912   if (!src_port && !dst_port)
8913     return 0;
8914
8915   u8 *mask = 0;
8916   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
8917
8918   tcpudp = (tcpudp_header_t *) mask;
8919   tcpudp->src_port = src_port;
8920   tcpudp->dst_port = dst_port;
8921
8922   *maskp = mask;
8923
8924   return 1;
8925 }
8926
8927 uword
8928 unformat_ip4_mask (unformat_input_t * input, va_list * args)
8929 {
8930   u8 **maskp = va_arg (*args, u8 **);
8931   u8 *mask = 0;
8932   u8 found_something = 0;
8933   ip4_header_t *ip;
8934
8935 #define _(a) u8 a=0;
8936   foreach_ip4_proto_field;
8937 #undef _
8938   u8 version = 0;
8939   u8 hdr_length = 0;
8940
8941
8942   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8943     {
8944       if (unformat (input, "version"))
8945         version = 1;
8946       else if (unformat (input, "hdr_length"))
8947         hdr_length = 1;
8948       else if (unformat (input, "src"))
8949         src_address = 1;
8950       else if (unformat (input, "dst"))
8951         dst_address = 1;
8952       else if (unformat (input, "proto"))
8953         protocol = 1;
8954
8955 #define _(a) else if (unformat (input, #a)) a=1;
8956       foreach_ip4_proto_field
8957 #undef _
8958         else
8959         break;
8960     }
8961
8962 #define _(a) found_something += a;
8963   foreach_ip4_proto_field;
8964 #undef _
8965
8966   if (found_something == 0)
8967     return 0;
8968
8969   vec_validate (mask, sizeof (*ip) - 1);
8970
8971   ip = (ip4_header_t *) mask;
8972
8973 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
8974   foreach_ip4_proto_field;
8975 #undef _
8976
8977   ip->ip_version_and_header_length = 0;
8978
8979   if (version)
8980     ip->ip_version_and_header_length |= 0xF0;
8981
8982   if (hdr_length)
8983     ip->ip_version_and_header_length |= 0x0F;
8984
8985   *maskp = mask;
8986   return 1;
8987 }
8988
8989 #define foreach_ip6_proto_field                 \
8990 _(src_address)                                  \
8991 _(dst_address)                                  \
8992 _(payload_length)                               \
8993 _(hop_limit)                                    \
8994 _(protocol)
8995
8996 uword
8997 unformat_ip6_mask (unformat_input_t * input, va_list * args)
8998 {
8999   u8 **maskp = va_arg (*args, u8 **);
9000   u8 *mask = 0;
9001   u8 found_something = 0;
9002   ip6_header_t *ip;
9003   u32 ip_version_traffic_class_and_flow_label;
9004
9005 #define _(a) u8 a=0;
9006   foreach_ip6_proto_field;
9007 #undef _
9008   u8 version = 0;
9009   u8 traffic_class = 0;
9010   u8 flow_label = 0;
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, "traffic-class"))
9017         traffic_class = 1;
9018       else if (unformat (input, "flow-label"))
9019         flow_label = 1;
9020       else if (unformat (input, "src"))
9021         src_address = 1;
9022       else if (unformat (input, "dst"))
9023         dst_address = 1;
9024       else if (unformat (input, "proto"))
9025         protocol = 1;
9026
9027 #define _(a) else if (unformat (input, #a)) a=1;
9028       foreach_ip6_proto_field
9029 #undef _
9030         else
9031         break;
9032     }
9033
9034 #define _(a) found_something += a;
9035   foreach_ip6_proto_field;
9036 #undef _
9037
9038   if (found_something == 0)
9039     return 0;
9040
9041   vec_validate (mask, sizeof (*ip) - 1);
9042
9043   ip = (ip6_header_t *) mask;
9044
9045 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
9046   foreach_ip6_proto_field;
9047 #undef _
9048
9049   ip_version_traffic_class_and_flow_label = 0;
9050
9051   if (version)
9052     ip_version_traffic_class_and_flow_label |= 0xF0000000;
9053
9054   if (traffic_class)
9055     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
9056
9057   if (flow_label)
9058     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
9059
9060   ip->ip_version_traffic_class_and_flow_label =
9061     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
9062
9063   *maskp = mask;
9064   return 1;
9065 }
9066
9067 uword
9068 unformat_l3_mask (unformat_input_t * input, va_list * args)
9069 {
9070   u8 **maskp = va_arg (*args, u8 **);
9071
9072   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9073     {
9074       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
9075         return 1;
9076       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
9077         return 1;
9078       else
9079         break;
9080     }
9081   return 0;
9082 }
9083
9084 uword
9085 unformat_l2_mask (unformat_input_t * input, va_list * args)
9086 {
9087   u8 **maskp = va_arg (*args, u8 **);
9088   u8 *mask = 0;
9089   u8 src = 0;
9090   u8 dst = 0;
9091   u8 proto = 0;
9092   u8 tag1 = 0;
9093   u8 tag2 = 0;
9094   u8 ignore_tag1 = 0;
9095   u8 ignore_tag2 = 0;
9096   u8 cos1 = 0;
9097   u8 cos2 = 0;
9098   u8 dot1q = 0;
9099   u8 dot1ad = 0;
9100   int len = 14;
9101
9102   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9103     {
9104       if (unformat (input, "src"))
9105         src = 1;
9106       else if (unformat (input, "dst"))
9107         dst = 1;
9108       else if (unformat (input, "proto"))
9109         proto = 1;
9110       else if (unformat (input, "tag1"))
9111         tag1 = 1;
9112       else if (unformat (input, "tag2"))
9113         tag2 = 1;
9114       else if (unformat (input, "ignore-tag1"))
9115         ignore_tag1 = 1;
9116       else if (unformat (input, "ignore-tag2"))
9117         ignore_tag2 = 1;
9118       else if (unformat (input, "cos1"))
9119         cos1 = 1;
9120       else if (unformat (input, "cos2"))
9121         cos2 = 1;
9122       else if (unformat (input, "dot1q"))
9123         dot1q = 1;
9124       else if (unformat (input, "dot1ad"))
9125         dot1ad = 1;
9126       else
9127         break;
9128     }
9129   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
9130        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
9131     return 0;
9132
9133   if (tag1 || ignore_tag1 || cos1 || dot1q)
9134     len = 18;
9135   if (tag2 || ignore_tag2 || cos2 || dot1ad)
9136     len = 22;
9137
9138   vec_validate (mask, len - 1);
9139
9140   if (dst)
9141     memset (mask, 0xff, 6);
9142
9143   if (src)
9144     memset (mask + 6, 0xff, 6);
9145
9146   if (tag2 || dot1ad)
9147     {
9148       /* inner vlan tag */
9149       if (tag2)
9150         {
9151           mask[19] = 0xff;
9152           mask[18] = 0x0f;
9153         }
9154       if (cos2)
9155         mask[18] |= 0xe0;
9156       if (proto)
9157         mask[21] = mask[20] = 0xff;
9158       if (tag1)
9159         {
9160           mask[15] = 0xff;
9161           mask[14] = 0x0f;
9162         }
9163       if (cos1)
9164         mask[14] |= 0xe0;
9165       *maskp = mask;
9166       return 1;
9167     }
9168   if (tag1 | dot1q)
9169     {
9170       if (tag1)
9171         {
9172           mask[15] = 0xff;
9173           mask[14] = 0x0f;
9174         }
9175       if (cos1)
9176         mask[14] |= 0xe0;
9177       if (proto)
9178         mask[16] = mask[17] = 0xff;
9179
9180       *maskp = mask;
9181       return 1;
9182     }
9183   if (cos2)
9184     mask[18] |= 0xe0;
9185   if (cos1)
9186     mask[14] |= 0xe0;
9187   if (proto)
9188     mask[12] = mask[13] = 0xff;
9189
9190   *maskp = mask;
9191   return 1;
9192 }
9193
9194 uword
9195 unformat_classify_mask (unformat_input_t * input, va_list * args)
9196 {
9197   u8 **maskp = va_arg (*args, u8 **);
9198   u32 *skipp = va_arg (*args, u32 *);
9199   u32 *matchp = va_arg (*args, u32 *);
9200   u32 match;
9201   u8 *mask = 0;
9202   u8 *l2 = 0;
9203   u8 *l3 = 0;
9204   u8 *l4 = 0;
9205   int i;
9206
9207   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9208     {
9209       if (unformat (input, "hex %U", unformat_hex_string, &mask))
9210         ;
9211       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
9212         ;
9213       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
9214         ;
9215       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
9216         ;
9217       else
9218         break;
9219     }
9220
9221   if (l4 && !l3)
9222     {
9223       vec_free (mask);
9224       vec_free (l2);
9225       vec_free (l4);
9226       return 0;
9227     }
9228
9229   if (mask || l2 || l3 || l4)
9230     {
9231       if (l2 || l3 || l4)
9232         {
9233           /* "With a free Ethernet header in every package" */
9234           if (l2 == 0)
9235             vec_validate (l2, 13);
9236           mask = l2;
9237           if (vec_len (l3))
9238             {
9239               vec_append (mask, l3);
9240               vec_free (l3);
9241             }
9242           if (vec_len (l4))
9243             {
9244               vec_append (mask, l4);
9245               vec_free (l4);
9246             }
9247         }
9248
9249       /* Scan forward looking for the first significant mask octet */
9250       for (i = 0; i < vec_len (mask); i++)
9251         if (mask[i])
9252           break;
9253
9254       /* compute (skip, match) params */
9255       *skipp = i / sizeof (u32x4);
9256       vec_delete (mask, *skipp * sizeof (u32x4), 0);
9257
9258       /* Pad mask to an even multiple of the vector size */
9259       while (vec_len (mask) % sizeof (u32x4))
9260         vec_add1 (mask, 0);
9261
9262       match = vec_len (mask) / sizeof (u32x4);
9263
9264       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
9265         {
9266           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
9267           if (*tmp || *(tmp + 1))
9268             break;
9269           match--;
9270         }
9271       if (match == 0)
9272         clib_warning ("BUG: match 0");
9273
9274       _vec_len (mask) = match * sizeof (u32x4);
9275
9276       *matchp = match;
9277       *maskp = mask;
9278
9279       return 1;
9280     }
9281
9282   return 0;
9283 }
9284 #endif /* VPP_API_TEST_BUILTIN */
9285
9286 #define foreach_l2_next                         \
9287 _(drop, DROP)                                   \
9288 _(ethernet, ETHERNET_INPUT)                     \
9289 _(ip4, IP4_INPUT)                               \
9290 _(ip6, IP6_INPUT)
9291
9292 uword
9293 unformat_l2_next_index (unformat_input_t * input, va_list * args)
9294 {
9295   u32 *miss_next_indexp = va_arg (*args, u32 *);
9296   u32 next_index = 0;
9297   u32 tmp;
9298
9299 #define _(n,N) \
9300   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
9301   foreach_l2_next;
9302 #undef _
9303
9304   if (unformat (input, "%d", &tmp))
9305     {
9306       next_index = tmp;
9307       goto out;
9308     }
9309
9310   return 0;
9311
9312 out:
9313   *miss_next_indexp = next_index;
9314   return 1;
9315 }
9316
9317 #define foreach_ip_next                         \
9318 _(drop, DROP)                                   \
9319 _(local, LOCAL)                                 \
9320 _(rewrite, REWRITE)
9321
9322 uword
9323 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
9324 {
9325   u32 *miss_next_indexp = va_arg (*args, u32 *);
9326   u32 next_index = 0;
9327   u32 tmp;
9328
9329 #define _(n,N) \
9330   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
9331   foreach_ip_next;
9332 #undef _
9333
9334   if (unformat (input, "%d", &tmp))
9335     {
9336       next_index = tmp;
9337       goto out;
9338     }
9339
9340   return 0;
9341
9342 out:
9343   *miss_next_indexp = next_index;
9344   return 1;
9345 }
9346
9347 #define foreach_acl_next                        \
9348 _(deny, DENY)
9349
9350 uword
9351 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
9352 {
9353   u32 *miss_next_indexp = va_arg (*args, u32 *);
9354   u32 next_index = 0;
9355   u32 tmp;
9356
9357 #define _(n,N) \
9358   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
9359   foreach_acl_next;
9360 #undef _
9361
9362   if (unformat (input, "permit"))
9363     {
9364       next_index = ~0;
9365       goto out;
9366     }
9367   else if (unformat (input, "%d", &tmp))
9368     {
9369       next_index = tmp;
9370       goto out;
9371     }
9372
9373   return 0;
9374
9375 out:
9376   *miss_next_indexp = next_index;
9377   return 1;
9378 }
9379
9380 uword
9381 unformat_policer_precolor (unformat_input_t * input, va_list * args)
9382 {
9383   u32 *r = va_arg (*args, u32 *);
9384
9385   if (unformat (input, "conform-color"))
9386     *r = POLICE_CONFORM;
9387   else if (unformat (input, "exceed-color"))
9388     *r = POLICE_EXCEED;
9389   else
9390     return 0;
9391
9392   return 1;
9393 }
9394
9395 static int
9396 api_classify_add_del_table (vat_main_t * vam)
9397 {
9398   unformat_input_t *i = vam->input;
9399   vl_api_classify_add_del_table_t *mp;
9400
9401   u32 nbuckets = 2;
9402   u32 skip = ~0;
9403   u32 match = ~0;
9404   int is_add = 1;
9405   int del_chain = 0;
9406   u32 table_index = ~0;
9407   u32 next_table_index = ~0;
9408   u32 miss_next_index = ~0;
9409   u32 memory_size = 32 << 20;
9410   u8 *mask = 0;
9411   u32 current_data_flag = 0;
9412   int current_data_offset = 0;
9413   int ret;
9414
9415   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9416     {
9417       if (unformat (i, "del"))
9418         is_add = 0;
9419       else if (unformat (i, "del-chain"))
9420         {
9421           is_add = 0;
9422           del_chain = 1;
9423         }
9424       else if (unformat (i, "buckets %d", &nbuckets))
9425         ;
9426       else if (unformat (i, "memory_size %d", &memory_size))
9427         ;
9428       else if (unformat (i, "skip %d", &skip))
9429         ;
9430       else if (unformat (i, "match %d", &match))
9431         ;
9432       else if (unformat (i, "table %d", &table_index))
9433         ;
9434       else if (unformat (i, "mask %U", unformat_classify_mask,
9435                          &mask, &skip, &match))
9436         ;
9437       else if (unformat (i, "next-table %d", &next_table_index))
9438         ;
9439       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
9440                          &miss_next_index))
9441         ;
9442       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
9443                          &miss_next_index))
9444         ;
9445       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
9446                          &miss_next_index))
9447         ;
9448       else if (unformat (i, "current-data-flag %d", &current_data_flag))
9449         ;
9450       else if (unformat (i, "current-data-offset %d", &current_data_offset))
9451         ;
9452       else
9453         break;
9454     }
9455
9456   if (is_add && mask == 0)
9457     {
9458       errmsg ("Mask required");
9459       return -99;
9460     }
9461
9462   if (is_add && skip == ~0)
9463     {
9464       errmsg ("skip count required");
9465       return -99;
9466     }
9467
9468   if (is_add && match == ~0)
9469     {
9470       errmsg ("match count required");
9471       return -99;
9472     }
9473
9474   if (!is_add && table_index == ~0)
9475     {
9476       errmsg ("table index required for delete");
9477       return -99;
9478     }
9479
9480   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
9481
9482   mp->is_add = is_add;
9483   mp->del_chain = del_chain;
9484   mp->table_index = ntohl (table_index);
9485   mp->nbuckets = ntohl (nbuckets);
9486   mp->memory_size = ntohl (memory_size);
9487   mp->skip_n_vectors = ntohl (skip);
9488   mp->match_n_vectors = ntohl (match);
9489   mp->next_table_index = ntohl (next_table_index);
9490   mp->miss_next_index = ntohl (miss_next_index);
9491   mp->current_data_flag = ntohl (current_data_flag);
9492   mp->current_data_offset = ntohl (current_data_offset);
9493   clib_memcpy (mp->mask, mask, vec_len (mask));
9494
9495   vec_free (mask);
9496
9497   S (mp);
9498   W (ret);
9499   return ret;
9500 }
9501
9502 #if VPP_API_TEST_BUILTIN == 0
9503 uword
9504 unformat_l4_match (unformat_input_t * input, va_list * args)
9505 {
9506   u8 **matchp = va_arg (*args, u8 **);
9507
9508   u8 *proto_header = 0;
9509   int src_port = 0;
9510   int dst_port = 0;
9511
9512   tcpudp_header_t h;
9513
9514   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9515     {
9516       if (unformat (input, "src_port %d", &src_port))
9517         ;
9518       else if (unformat (input, "dst_port %d", &dst_port))
9519         ;
9520       else
9521         return 0;
9522     }
9523
9524   h.src_port = clib_host_to_net_u16 (src_port);
9525   h.dst_port = clib_host_to_net_u16 (dst_port);
9526   vec_validate (proto_header, sizeof (h) - 1);
9527   memcpy (proto_header, &h, sizeof (h));
9528
9529   *matchp = proto_header;
9530
9531   return 1;
9532 }
9533
9534 uword
9535 unformat_ip4_match (unformat_input_t * input, va_list * args)
9536 {
9537   u8 **matchp = va_arg (*args, u8 **);
9538   u8 *match = 0;
9539   ip4_header_t *ip;
9540   int version = 0;
9541   u32 version_val;
9542   int hdr_length = 0;
9543   u32 hdr_length_val;
9544   int src = 0, dst = 0;
9545   ip4_address_t src_val, dst_val;
9546   int proto = 0;
9547   u32 proto_val;
9548   int tos = 0;
9549   u32 tos_val;
9550   int length = 0;
9551   u32 length_val;
9552   int fragment_id = 0;
9553   u32 fragment_id_val;
9554   int ttl = 0;
9555   int ttl_val;
9556   int checksum = 0;
9557   u32 checksum_val;
9558
9559   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9560     {
9561       if (unformat (input, "version %d", &version_val))
9562         version = 1;
9563       else if (unformat (input, "hdr_length %d", &hdr_length_val))
9564         hdr_length = 1;
9565       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
9566         src = 1;
9567       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
9568         dst = 1;
9569       else if (unformat (input, "proto %d", &proto_val))
9570         proto = 1;
9571       else if (unformat (input, "tos %d", &tos_val))
9572         tos = 1;
9573       else if (unformat (input, "length %d", &length_val))
9574         length = 1;
9575       else if (unformat (input, "fragment_id %d", &fragment_id_val))
9576         fragment_id = 1;
9577       else if (unformat (input, "ttl %d", &ttl_val))
9578         ttl = 1;
9579       else if (unformat (input, "checksum %d", &checksum_val))
9580         checksum = 1;
9581       else
9582         break;
9583     }
9584
9585   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
9586       + ttl + checksum == 0)
9587     return 0;
9588
9589   /*
9590    * Aligned because we use the real comparison functions
9591    */
9592   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
9593
9594   ip = (ip4_header_t *) match;
9595
9596   /* These are realistically matched in practice */
9597   if (src)
9598     ip->src_address.as_u32 = src_val.as_u32;
9599
9600   if (dst)
9601     ip->dst_address.as_u32 = dst_val.as_u32;
9602
9603   if (proto)
9604     ip->protocol = proto_val;
9605
9606
9607   /* These are not, but they're included for completeness */
9608   if (version)
9609     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
9610
9611   if (hdr_length)
9612     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
9613
9614   if (tos)
9615     ip->tos = tos_val;
9616
9617   if (length)
9618     ip->length = clib_host_to_net_u16 (length_val);
9619
9620   if (ttl)
9621     ip->ttl = ttl_val;
9622
9623   if (checksum)
9624     ip->checksum = clib_host_to_net_u16 (checksum_val);
9625
9626   *matchp = match;
9627   return 1;
9628 }
9629
9630 uword
9631 unformat_ip6_match (unformat_input_t * input, va_list * args)
9632 {
9633   u8 **matchp = va_arg (*args, u8 **);
9634   u8 *match = 0;
9635   ip6_header_t *ip;
9636   int version = 0;
9637   u32 version_val;
9638   u8 traffic_class = 0;
9639   u32 traffic_class_val = 0;
9640   u8 flow_label = 0;
9641   u8 flow_label_val;
9642   int src = 0, dst = 0;
9643   ip6_address_t src_val, dst_val;
9644   int proto = 0;
9645   u32 proto_val;
9646   int payload_length = 0;
9647   u32 payload_length_val;
9648   int hop_limit = 0;
9649   int hop_limit_val;
9650   u32 ip_version_traffic_class_and_flow_label;
9651
9652   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9653     {
9654       if (unformat (input, "version %d", &version_val))
9655         version = 1;
9656       else if (unformat (input, "traffic_class %d", &traffic_class_val))
9657         traffic_class = 1;
9658       else if (unformat (input, "flow_label %d", &flow_label_val))
9659         flow_label = 1;
9660       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
9661         src = 1;
9662       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
9663         dst = 1;
9664       else if (unformat (input, "proto %d", &proto_val))
9665         proto = 1;
9666       else if (unformat (input, "payload_length %d", &payload_length_val))
9667         payload_length = 1;
9668       else if (unformat (input, "hop_limit %d", &hop_limit_val))
9669         hop_limit = 1;
9670       else
9671         break;
9672     }
9673
9674   if (version + traffic_class + flow_label + src + dst + proto +
9675       payload_length + hop_limit == 0)
9676     return 0;
9677
9678   /*
9679    * Aligned because we use the real comparison functions
9680    */
9681   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
9682
9683   ip = (ip6_header_t *) match;
9684
9685   if (src)
9686     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
9687
9688   if (dst)
9689     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
9690
9691   if (proto)
9692     ip->protocol = proto_val;
9693
9694   ip_version_traffic_class_and_flow_label = 0;
9695
9696   if (version)
9697     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
9698
9699   if (traffic_class)
9700     ip_version_traffic_class_and_flow_label |=
9701       (traffic_class_val & 0xFF) << 20;
9702
9703   if (flow_label)
9704     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
9705
9706   ip->ip_version_traffic_class_and_flow_label =
9707     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
9708
9709   if (payload_length)
9710     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
9711
9712   if (hop_limit)
9713     ip->hop_limit = hop_limit_val;
9714
9715   *matchp = match;
9716   return 1;
9717 }
9718
9719 uword
9720 unformat_l3_match (unformat_input_t * input, va_list * args)
9721 {
9722   u8 **matchp = va_arg (*args, u8 **);
9723
9724   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9725     {
9726       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
9727         return 1;
9728       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
9729         return 1;
9730       else
9731         break;
9732     }
9733   return 0;
9734 }
9735
9736 uword
9737 unformat_vlan_tag (unformat_input_t * input, va_list * args)
9738 {
9739   u8 *tagp = va_arg (*args, u8 *);
9740   u32 tag;
9741
9742   if (unformat (input, "%d", &tag))
9743     {
9744       tagp[0] = (tag >> 8) & 0x0F;
9745       tagp[1] = tag & 0xFF;
9746       return 1;
9747     }
9748
9749   return 0;
9750 }
9751
9752 uword
9753 unformat_l2_match (unformat_input_t * input, va_list * args)
9754 {
9755   u8 **matchp = va_arg (*args, u8 **);
9756   u8 *match = 0;
9757   u8 src = 0;
9758   u8 src_val[6];
9759   u8 dst = 0;
9760   u8 dst_val[6];
9761   u8 proto = 0;
9762   u16 proto_val;
9763   u8 tag1 = 0;
9764   u8 tag1_val[2];
9765   u8 tag2 = 0;
9766   u8 tag2_val[2];
9767   int len = 14;
9768   u8 ignore_tag1 = 0;
9769   u8 ignore_tag2 = 0;
9770   u8 cos1 = 0;
9771   u8 cos2 = 0;
9772   u32 cos1_val = 0;
9773   u32 cos2_val = 0;
9774
9775   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9776     {
9777       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
9778         src = 1;
9779       else
9780         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
9781         dst = 1;
9782       else if (unformat (input, "proto %U",
9783                          unformat_ethernet_type_host_byte_order, &proto_val))
9784         proto = 1;
9785       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
9786         tag1 = 1;
9787       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
9788         tag2 = 1;
9789       else if (unformat (input, "ignore-tag1"))
9790         ignore_tag1 = 1;
9791       else if (unformat (input, "ignore-tag2"))
9792         ignore_tag2 = 1;
9793       else if (unformat (input, "cos1 %d", &cos1_val))
9794         cos1 = 1;
9795       else if (unformat (input, "cos2 %d", &cos2_val))
9796         cos2 = 1;
9797       else
9798         break;
9799     }
9800   if ((src + dst + proto + tag1 + tag2 +
9801        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
9802     return 0;
9803
9804   if (tag1 || ignore_tag1 || cos1)
9805     len = 18;
9806   if (tag2 || ignore_tag2 || cos2)
9807     len = 22;
9808
9809   vec_validate_aligned (match, len - 1, sizeof (u32x4));
9810
9811   if (dst)
9812     clib_memcpy (match, dst_val, 6);
9813
9814   if (src)
9815     clib_memcpy (match + 6, src_val, 6);
9816
9817   if (tag2)
9818     {
9819       /* inner vlan tag */
9820       match[19] = tag2_val[1];
9821       match[18] = tag2_val[0];
9822       if (cos2)
9823         match[18] |= (cos2_val & 0x7) << 5;
9824       if (proto)
9825         {
9826           match[21] = proto_val & 0xff;
9827           match[20] = proto_val >> 8;
9828         }
9829       if (tag1)
9830         {
9831           match[15] = tag1_val[1];
9832           match[14] = tag1_val[0];
9833         }
9834       if (cos1)
9835         match[14] |= (cos1_val & 0x7) << 5;
9836       *matchp = match;
9837       return 1;
9838     }
9839   if (tag1)
9840     {
9841       match[15] = tag1_val[1];
9842       match[14] = tag1_val[0];
9843       if (proto)
9844         {
9845           match[17] = proto_val & 0xff;
9846           match[16] = proto_val >> 8;
9847         }
9848       if (cos1)
9849         match[14] |= (cos1_val & 0x7) << 5;
9850
9851       *matchp = match;
9852       return 1;
9853     }
9854   if (cos2)
9855     match[18] |= (cos2_val & 0x7) << 5;
9856   if (cos1)
9857     match[14] |= (cos1_val & 0x7) << 5;
9858   if (proto)
9859     {
9860       match[13] = proto_val & 0xff;
9861       match[12] = proto_val >> 8;
9862     }
9863
9864   *matchp = match;
9865   return 1;
9866 }
9867 #endif
9868
9869 uword
9870 api_unformat_classify_match (unformat_input_t * input, va_list * args)
9871 {
9872   u8 **matchp = va_arg (*args, u8 **);
9873   u32 skip_n_vectors = va_arg (*args, u32);
9874   u32 match_n_vectors = va_arg (*args, u32);
9875
9876   u8 *match = 0;
9877   u8 *l2 = 0;
9878   u8 *l3 = 0;
9879   u8 *l4 = 0;
9880
9881   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9882     {
9883       if (unformat (input, "hex %U", unformat_hex_string, &match))
9884         ;
9885       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
9886         ;
9887       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
9888         ;
9889       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
9890         ;
9891       else
9892         break;
9893     }
9894
9895   if (l4 && !l3)
9896     {
9897       vec_free (match);
9898       vec_free (l2);
9899       vec_free (l4);
9900       return 0;
9901     }
9902
9903   if (match || l2 || l3 || l4)
9904     {
9905       if (l2 || l3 || l4)
9906         {
9907           /* "Win a free Ethernet header in every packet" */
9908           if (l2 == 0)
9909             vec_validate_aligned (l2, 13, sizeof (u32x4));
9910           match = l2;
9911           if (vec_len (l3))
9912             {
9913               vec_append_aligned (match, l3, sizeof (u32x4));
9914               vec_free (l3);
9915             }
9916           if (vec_len (l4))
9917             {
9918               vec_append_aligned (match, l4, sizeof (u32x4));
9919               vec_free (l4);
9920             }
9921         }
9922
9923       /* Make sure the vector is big enough even if key is all 0's */
9924       vec_validate_aligned
9925         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
9926          sizeof (u32x4));
9927
9928       /* Set size, include skipped vectors */
9929       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
9930
9931       *matchp = match;
9932
9933       return 1;
9934     }
9935
9936   return 0;
9937 }
9938
9939 static int
9940 api_classify_add_del_session (vat_main_t * vam)
9941 {
9942   unformat_input_t *i = vam->input;
9943   vl_api_classify_add_del_session_t *mp;
9944   int is_add = 1;
9945   u32 table_index = ~0;
9946   u32 hit_next_index = ~0;
9947   u32 opaque_index = ~0;
9948   u8 *match = 0;
9949   i32 advance = 0;
9950   u32 skip_n_vectors = 0;
9951   u32 match_n_vectors = 0;
9952   u32 action = 0;
9953   u32 metadata = 0;
9954   int ret;
9955
9956   /*
9957    * Warning: you have to supply skip_n and match_n
9958    * because the API client cant simply look at the classify
9959    * table object.
9960    */
9961
9962   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9963     {
9964       if (unformat (i, "del"))
9965         is_add = 0;
9966       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
9967                          &hit_next_index))
9968         ;
9969       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
9970                          &hit_next_index))
9971         ;
9972       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
9973                          &hit_next_index))
9974         ;
9975       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
9976         ;
9977       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
9978         ;
9979       else if (unformat (i, "opaque-index %d", &opaque_index))
9980         ;
9981       else if (unformat (i, "skip_n %d", &skip_n_vectors))
9982         ;
9983       else if (unformat (i, "match_n %d", &match_n_vectors))
9984         ;
9985       else if (unformat (i, "match %U", api_unformat_classify_match,
9986                          &match, skip_n_vectors, match_n_vectors))
9987         ;
9988       else if (unformat (i, "advance %d", &advance))
9989         ;
9990       else if (unformat (i, "table-index %d", &table_index))
9991         ;
9992       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
9993         action = 1;
9994       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
9995         action = 2;
9996       else if (unformat (i, "action %d", &action))
9997         ;
9998       else if (unformat (i, "metadata %d", &metadata))
9999         ;
10000       else
10001         break;
10002     }
10003
10004   if (table_index == ~0)
10005     {
10006       errmsg ("Table index required");
10007       return -99;
10008     }
10009
10010   if (is_add && match == 0)
10011     {
10012       errmsg ("Match value required");
10013       return -99;
10014     }
10015
10016   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
10017
10018   mp->is_add = is_add;
10019   mp->table_index = ntohl (table_index);
10020   mp->hit_next_index = ntohl (hit_next_index);
10021   mp->opaque_index = ntohl (opaque_index);
10022   mp->advance = ntohl (advance);
10023   mp->action = action;
10024   mp->metadata = ntohl (metadata);
10025   clib_memcpy (mp->match, match, vec_len (match));
10026   vec_free (match);
10027
10028   S (mp);
10029   W (ret);
10030   return ret;
10031 }
10032
10033 static int
10034 api_classify_set_interface_ip_table (vat_main_t * vam)
10035 {
10036   unformat_input_t *i = vam->input;
10037   vl_api_classify_set_interface_ip_table_t *mp;
10038   u32 sw_if_index;
10039   int sw_if_index_set;
10040   u32 table_index = ~0;
10041   u8 is_ipv6 = 0;
10042   int ret;
10043
10044   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10045     {
10046       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10047         sw_if_index_set = 1;
10048       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10049         sw_if_index_set = 1;
10050       else if (unformat (i, "table %d", &table_index))
10051         ;
10052       else
10053         {
10054           clib_warning ("parse error '%U'", format_unformat_error, i);
10055           return -99;
10056         }
10057     }
10058
10059   if (sw_if_index_set == 0)
10060     {
10061       errmsg ("missing interface name or sw_if_index");
10062       return -99;
10063     }
10064
10065
10066   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
10067
10068   mp->sw_if_index = ntohl (sw_if_index);
10069   mp->table_index = ntohl (table_index);
10070   mp->is_ipv6 = is_ipv6;
10071
10072   S (mp);
10073   W (ret);
10074   return ret;
10075 }
10076
10077 static int
10078 api_classify_set_interface_l2_tables (vat_main_t * vam)
10079 {
10080   unformat_input_t *i = vam->input;
10081   vl_api_classify_set_interface_l2_tables_t *mp;
10082   u32 sw_if_index;
10083   int sw_if_index_set;
10084   u32 ip4_table_index = ~0;
10085   u32 ip6_table_index = ~0;
10086   u32 other_table_index = ~0;
10087   u32 is_input = 1;
10088   int ret;
10089
10090   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10091     {
10092       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10093         sw_if_index_set = 1;
10094       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10095         sw_if_index_set = 1;
10096       else if (unformat (i, "ip4-table %d", &ip4_table_index))
10097         ;
10098       else if (unformat (i, "ip6-table %d", &ip6_table_index))
10099         ;
10100       else if (unformat (i, "other-table %d", &other_table_index))
10101         ;
10102       else if (unformat (i, "is-input %d", &is_input))
10103         ;
10104       else
10105         {
10106           clib_warning ("parse error '%U'", format_unformat_error, i);
10107           return -99;
10108         }
10109     }
10110
10111   if (sw_if_index_set == 0)
10112     {
10113       errmsg ("missing interface name or sw_if_index");
10114       return -99;
10115     }
10116
10117
10118   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
10119
10120   mp->sw_if_index = ntohl (sw_if_index);
10121   mp->ip4_table_index = ntohl (ip4_table_index);
10122   mp->ip6_table_index = ntohl (ip6_table_index);
10123   mp->other_table_index = ntohl (other_table_index);
10124   mp->is_input = (u8) is_input;
10125
10126   S (mp);
10127   W (ret);
10128   return ret;
10129 }
10130
10131 static int
10132 api_set_ipfix_exporter (vat_main_t * vam)
10133 {
10134   unformat_input_t *i = vam->input;
10135   vl_api_set_ipfix_exporter_t *mp;
10136   ip4_address_t collector_address;
10137   u8 collector_address_set = 0;
10138   u32 collector_port = ~0;
10139   ip4_address_t src_address;
10140   u8 src_address_set = 0;
10141   u32 vrf_id = ~0;
10142   u32 path_mtu = ~0;
10143   u32 template_interval = ~0;
10144   u8 udp_checksum = 0;
10145   int ret;
10146
10147   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10148     {
10149       if (unformat (i, "collector_address %U", unformat_ip4_address,
10150                     &collector_address))
10151         collector_address_set = 1;
10152       else if (unformat (i, "collector_port %d", &collector_port))
10153         ;
10154       else if (unformat (i, "src_address %U", unformat_ip4_address,
10155                          &src_address))
10156         src_address_set = 1;
10157       else if (unformat (i, "vrf_id %d", &vrf_id))
10158         ;
10159       else if (unformat (i, "path_mtu %d", &path_mtu))
10160         ;
10161       else if (unformat (i, "template_interval %d", &template_interval))
10162         ;
10163       else if (unformat (i, "udp_checksum"))
10164         udp_checksum = 1;
10165       else
10166         break;
10167     }
10168
10169   if (collector_address_set == 0)
10170     {
10171       errmsg ("collector_address required");
10172       return -99;
10173     }
10174
10175   if (src_address_set == 0)
10176     {
10177       errmsg ("src_address required");
10178       return -99;
10179     }
10180
10181   M (SET_IPFIX_EXPORTER, mp);
10182
10183   memcpy (mp->collector_address, collector_address.data,
10184           sizeof (collector_address.data));
10185   mp->collector_port = htons ((u16) collector_port);
10186   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
10187   mp->vrf_id = htonl (vrf_id);
10188   mp->path_mtu = htonl (path_mtu);
10189   mp->template_interval = htonl (template_interval);
10190   mp->udp_checksum = udp_checksum;
10191
10192   S (mp);
10193   W (ret);
10194   return ret;
10195 }
10196
10197 static int
10198 api_set_ipfix_classify_stream (vat_main_t * vam)
10199 {
10200   unformat_input_t *i = vam->input;
10201   vl_api_set_ipfix_classify_stream_t *mp;
10202   u32 domain_id = 0;
10203   u32 src_port = UDP_DST_PORT_ipfix;
10204   int ret;
10205
10206   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10207     {
10208       if (unformat (i, "domain %d", &domain_id))
10209         ;
10210       else if (unformat (i, "src_port %d", &src_port))
10211         ;
10212       else
10213         {
10214           errmsg ("unknown input `%U'", format_unformat_error, i);
10215           return -99;
10216         }
10217     }
10218
10219   M (SET_IPFIX_CLASSIFY_STREAM, mp);
10220
10221   mp->domain_id = htonl (domain_id);
10222   mp->src_port = htons ((u16) src_port);
10223
10224   S (mp);
10225   W (ret);
10226   return ret;
10227 }
10228
10229 static int
10230 api_ipfix_classify_table_add_del (vat_main_t * vam)
10231 {
10232   unformat_input_t *i = vam->input;
10233   vl_api_ipfix_classify_table_add_del_t *mp;
10234   int is_add = -1;
10235   u32 classify_table_index = ~0;
10236   u8 ip_version = 0;
10237   u8 transport_protocol = 255;
10238   int ret;
10239
10240   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10241     {
10242       if (unformat (i, "add"))
10243         is_add = 1;
10244       else if (unformat (i, "del"))
10245         is_add = 0;
10246       else if (unformat (i, "table %d", &classify_table_index))
10247         ;
10248       else if (unformat (i, "ip4"))
10249         ip_version = 4;
10250       else if (unformat (i, "ip6"))
10251         ip_version = 6;
10252       else if (unformat (i, "tcp"))
10253         transport_protocol = 6;
10254       else if (unformat (i, "udp"))
10255         transport_protocol = 17;
10256       else
10257         {
10258           errmsg ("unknown input `%U'", format_unformat_error, i);
10259           return -99;
10260         }
10261     }
10262
10263   if (is_add == -1)
10264     {
10265       errmsg ("expecting: add|del");
10266       return -99;
10267     }
10268   if (classify_table_index == ~0)
10269     {
10270       errmsg ("classifier table not specified");
10271       return -99;
10272     }
10273   if (ip_version == 0)
10274     {
10275       errmsg ("IP version not specified");
10276       return -99;
10277     }
10278
10279   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
10280
10281   mp->is_add = is_add;
10282   mp->table_id = htonl (classify_table_index);
10283   mp->ip_version = ip_version;
10284   mp->transport_protocol = transport_protocol;
10285
10286   S (mp);
10287   W (ret);
10288   return ret;
10289 }
10290
10291 static int
10292 api_get_node_index (vat_main_t * vam)
10293 {
10294   unformat_input_t *i = vam->input;
10295   vl_api_get_node_index_t *mp;
10296   u8 *name = 0;
10297   int ret;
10298
10299   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10300     {
10301       if (unformat (i, "node %s", &name))
10302         ;
10303       else
10304         break;
10305     }
10306   if (name == 0)
10307     {
10308       errmsg ("node name required");
10309       return -99;
10310     }
10311   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
10312     {
10313       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10314       return -99;
10315     }
10316
10317   M (GET_NODE_INDEX, mp);
10318   clib_memcpy (mp->node_name, name, vec_len (name));
10319   vec_free (name);
10320
10321   S (mp);
10322   W (ret);
10323   return ret;
10324 }
10325
10326 static int
10327 api_get_next_index (vat_main_t * vam)
10328 {
10329   unformat_input_t *i = vam->input;
10330   vl_api_get_next_index_t *mp;
10331   u8 *node_name = 0, *next_node_name = 0;
10332   int ret;
10333
10334   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10335     {
10336       if (unformat (i, "node-name %s", &node_name))
10337         ;
10338       else if (unformat (i, "next-node-name %s", &next_node_name))
10339         break;
10340     }
10341
10342   if (node_name == 0)
10343     {
10344       errmsg ("node name required");
10345       return -99;
10346     }
10347   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
10348     {
10349       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10350       return -99;
10351     }
10352
10353   if (next_node_name == 0)
10354     {
10355       errmsg ("next node name required");
10356       return -99;
10357     }
10358   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
10359     {
10360       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
10361       return -99;
10362     }
10363
10364   M (GET_NEXT_INDEX, mp);
10365   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
10366   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
10367   vec_free (node_name);
10368   vec_free (next_node_name);
10369
10370   S (mp);
10371   W (ret);
10372   return ret;
10373 }
10374
10375 static int
10376 api_add_node_next (vat_main_t * vam)
10377 {
10378   unformat_input_t *i = vam->input;
10379   vl_api_add_node_next_t *mp;
10380   u8 *name = 0;
10381   u8 *next = 0;
10382   int ret;
10383
10384   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10385     {
10386       if (unformat (i, "node %s", &name))
10387         ;
10388       else if (unformat (i, "next %s", &next))
10389         ;
10390       else
10391         break;
10392     }
10393   if (name == 0)
10394     {
10395       errmsg ("node name required");
10396       return -99;
10397     }
10398   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
10399     {
10400       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10401       return -99;
10402     }
10403   if (next == 0)
10404     {
10405       errmsg ("next node required");
10406       return -99;
10407     }
10408   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
10409     {
10410       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
10411       return -99;
10412     }
10413
10414   M (ADD_NODE_NEXT, mp);
10415   clib_memcpy (mp->node_name, name, vec_len (name));
10416   clib_memcpy (mp->next_name, next, vec_len (next));
10417   vec_free (name);
10418   vec_free (next);
10419
10420   S (mp);
10421   W (ret);
10422   return ret;
10423 }
10424
10425 static int
10426 api_l2tpv3_create_tunnel (vat_main_t * vam)
10427 {
10428   unformat_input_t *i = vam->input;
10429   ip6_address_t client_address, our_address;
10430   int client_address_set = 0;
10431   int our_address_set = 0;
10432   u32 local_session_id = 0;
10433   u32 remote_session_id = 0;
10434   u64 local_cookie = 0;
10435   u64 remote_cookie = 0;
10436   u8 l2_sublayer_present = 0;
10437   vl_api_l2tpv3_create_tunnel_t *mp;
10438   int ret;
10439
10440   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10441     {
10442       if (unformat (i, "client_address %U", unformat_ip6_address,
10443                     &client_address))
10444         client_address_set = 1;
10445       else if (unformat (i, "our_address %U", unformat_ip6_address,
10446                          &our_address))
10447         our_address_set = 1;
10448       else if (unformat (i, "local_session_id %d", &local_session_id))
10449         ;
10450       else if (unformat (i, "remote_session_id %d", &remote_session_id))
10451         ;
10452       else if (unformat (i, "local_cookie %lld", &local_cookie))
10453         ;
10454       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
10455         ;
10456       else if (unformat (i, "l2-sublayer-present"))
10457         l2_sublayer_present = 1;
10458       else
10459         break;
10460     }
10461
10462   if (client_address_set == 0)
10463     {
10464       errmsg ("client_address required");
10465       return -99;
10466     }
10467
10468   if (our_address_set == 0)
10469     {
10470       errmsg ("our_address required");
10471       return -99;
10472     }
10473
10474   M (L2TPV3_CREATE_TUNNEL, mp);
10475
10476   clib_memcpy (mp->client_address, client_address.as_u8,
10477                sizeof (mp->client_address));
10478
10479   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
10480
10481   mp->local_session_id = ntohl (local_session_id);
10482   mp->remote_session_id = ntohl (remote_session_id);
10483   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
10484   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
10485   mp->l2_sublayer_present = l2_sublayer_present;
10486   mp->is_ipv6 = 1;
10487
10488   S (mp);
10489   W (ret);
10490   return ret;
10491 }
10492
10493 static int
10494 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
10495 {
10496   unformat_input_t *i = vam->input;
10497   u32 sw_if_index;
10498   u8 sw_if_index_set = 0;
10499   u64 new_local_cookie = 0;
10500   u64 new_remote_cookie = 0;
10501   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
10502   int ret;
10503
10504   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10505     {
10506       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10507         sw_if_index_set = 1;
10508       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10509         sw_if_index_set = 1;
10510       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
10511         ;
10512       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
10513         ;
10514       else
10515         break;
10516     }
10517
10518   if (sw_if_index_set == 0)
10519     {
10520       errmsg ("missing interface name or sw_if_index");
10521       return -99;
10522     }
10523
10524   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
10525
10526   mp->sw_if_index = ntohl (sw_if_index);
10527   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
10528   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
10529
10530   S (mp);
10531   W (ret);
10532   return ret;
10533 }
10534
10535 static int
10536 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
10537 {
10538   unformat_input_t *i = vam->input;
10539   vl_api_l2tpv3_interface_enable_disable_t *mp;
10540   u32 sw_if_index;
10541   u8 sw_if_index_set = 0;
10542   u8 enable_disable = 1;
10543   int ret;
10544
10545   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10546     {
10547       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10548         sw_if_index_set = 1;
10549       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10550         sw_if_index_set = 1;
10551       else if (unformat (i, "enable"))
10552         enable_disable = 1;
10553       else if (unformat (i, "disable"))
10554         enable_disable = 0;
10555       else
10556         break;
10557     }
10558
10559   if (sw_if_index_set == 0)
10560     {
10561       errmsg ("missing interface name or sw_if_index");
10562       return -99;
10563     }
10564
10565   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
10566
10567   mp->sw_if_index = ntohl (sw_if_index);
10568   mp->enable_disable = enable_disable;
10569
10570   S (mp);
10571   W (ret);
10572   return ret;
10573 }
10574
10575 static int
10576 api_l2tpv3_set_lookup_key (vat_main_t * vam)
10577 {
10578   unformat_input_t *i = vam->input;
10579   vl_api_l2tpv3_set_lookup_key_t *mp;
10580   u8 key = ~0;
10581   int ret;
10582
10583   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10584     {
10585       if (unformat (i, "lookup_v6_src"))
10586         key = L2T_LOOKUP_SRC_ADDRESS;
10587       else if (unformat (i, "lookup_v6_dst"))
10588         key = L2T_LOOKUP_DST_ADDRESS;
10589       else if (unformat (i, "lookup_session_id"))
10590         key = L2T_LOOKUP_SESSION_ID;
10591       else
10592         break;
10593     }
10594
10595   if (key == (u8) ~ 0)
10596     {
10597       errmsg ("l2tp session lookup key unset");
10598       return -99;
10599     }
10600
10601   M (L2TPV3_SET_LOOKUP_KEY, mp);
10602
10603   mp->key = key;
10604
10605   S (mp);
10606   W (ret);
10607   return ret;
10608 }
10609
10610 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
10611   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
10612 {
10613   vat_main_t *vam = &vat_main;
10614
10615   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
10616          format_ip6_address, mp->our_address,
10617          format_ip6_address, mp->client_address,
10618          clib_net_to_host_u32 (mp->sw_if_index));
10619
10620   print (vam->ofp,
10621          "   local cookies %016llx %016llx remote cookie %016llx",
10622          clib_net_to_host_u64 (mp->local_cookie[0]),
10623          clib_net_to_host_u64 (mp->local_cookie[1]),
10624          clib_net_to_host_u64 (mp->remote_cookie));
10625
10626   print (vam->ofp, "   local session-id %d remote session-id %d",
10627          clib_net_to_host_u32 (mp->local_session_id),
10628          clib_net_to_host_u32 (mp->remote_session_id));
10629
10630   print (vam->ofp, "   l2 specific sublayer %s\n",
10631          mp->l2_sublayer_present ? "preset" : "absent");
10632
10633 }
10634
10635 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
10636   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
10637 {
10638   vat_main_t *vam = &vat_main;
10639   vat_json_node_t *node = NULL;
10640   struct in6_addr addr;
10641
10642   if (VAT_JSON_ARRAY != vam->json_tree.type)
10643     {
10644       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10645       vat_json_init_array (&vam->json_tree);
10646     }
10647   node = vat_json_array_add (&vam->json_tree);
10648
10649   vat_json_init_object (node);
10650
10651   clib_memcpy (&addr, mp->our_address, sizeof (addr));
10652   vat_json_object_add_ip6 (node, "our_address", addr);
10653   clib_memcpy (&addr, mp->client_address, sizeof (addr));
10654   vat_json_object_add_ip6 (node, "client_address", addr);
10655
10656   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
10657   vat_json_init_array (lc);
10658   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
10659   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
10660   vat_json_object_add_uint (node, "remote_cookie",
10661                             clib_net_to_host_u64 (mp->remote_cookie));
10662
10663   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
10664   vat_json_object_add_uint (node, "local_session_id",
10665                             clib_net_to_host_u32 (mp->local_session_id));
10666   vat_json_object_add_uint (node, "remote_session_id",
10667                             clib_net_to_host_u32 (mp->remote_session_id));
10668   vat_json_object_add_string_copy (node, "l2_sublayer",
10669                                    mp->l2_sublayer_present ? (u8 *) "present"
10670                                    : (u8 *) "absent");
10671 }
10672
10673 static int
10674 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
10675 {
10676   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
10677   vl_api_control_ping_t *mp_ping;
10678   int ret;
10679
10680   /* Get list of l2tpv3-tunnel interfaces */
10681   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
10682   S (mp);
10683
10684   /* Use a control ping for synchronization */
10685   M (CONTROL_PING, mp_ping);
10686   S (mp_ping);
10687
10688   W (ret);
10689   return ret;
10690 }
10691
10692
10693 static void vl_api_sw_interface_tap_details_t_handler
10694   (vl_api_sw_interface_tap_details_t * mp)
10695 {
10696   vat_main_t *vam = &vat_main;
10697
10698   print (vam->ofp, "%-16s %d",
10699          mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
10700 }
10701
10702 static void vl_api_sw_interface_tap_details_t_handler_json
10703   (vl_api_sw_interface_tap_details_t * mp)
10704 {
10705   vat_main_t *vam = &vat_main;
10706   vat_json_node_t *node = NULL;
10707
10708   if (VAT_JSON_ARRAY != vam->json_tree.type)
10709     {
10710       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10711       vat_json_init_array (&vam->json_tree);
10712     }
10713   node = vat_json_array_add (&vam->json_tree);
10714
10715   vat_json_init_object (node);
10716   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10717   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
10718 }
10719
10720 static int
10721 api_sw_interface_tap_dump (vat_main_t * vam)
10722 {
10723   vl_api_sw_interface_tap_dump_t *mp;
10724   vl_api_control_ping_t *mp_ping;
10725   int ret;
10726
10727   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
10728   /* Get list of tap interfaces */
10729   M (SW_INTERFACE_TAP_DUMP, mp);
10730   S (mp);
10731
10732   /* Use a control ping for synchronization */
10733   M (CONTROL_PING, mp_ping);
10734   S (mp_ping);
10735
10736   W (ret);
10737   return ret;
10738 }
10739
10740 static uword unformat_vxlan_decap_next
10741   (unformat_input_t * input, va_list * args)
10742 {
10743   u32 *result = va_arg (*args, u32 *);
10744   u32 tmp;
10745
10746   if (unformat (input, "l2"))
10747     *result = VXLAN_INPUT_NEXT_L2_INPUT;
10748   else if (unformat (input, "%d", &tmp))
10749     *result = tmp;
10750   else
10751     return 0;
10752   return 1;
10753 }
10754
10755 static int
10756 api_vxlan_add_del_tunnel (vat_main_t * vam)
10757 {
10758   unformat_input_t *line_input = vam->input;
10759   vl_api_vxlan_add_del_tunnel_t *mp;
10760   ip46_address_t src, dst;
10761   u8 is_add = 1;
10762   u8 ipv4_set = 0, ipv6_set = 0;
10763   u8 src_set = 0;
10764   u8 dst_set = 0;
10765   u8 grp_set = 0;
10766   u32 mcast_sw_if_index = ~0;
10767   u32 encap_vrf_id = 0;
10768   u32 decap_next_index = ~0;
10769   u32 vni = 0;
10770   int ret;
10771
10772   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
10773   memset (&src, 0, sizeof src);
10774   memset (&dst, 0, sizeof dst);
10775
10776   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10777     {
10778       if (unformat (line_input, "del"))
10779         is_add = 0;
10780       else
10781         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
10782         {
10783           ipv4_set = 1;
10784           src_set = 1;
10785         }
10786       else
10787         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
10788         {
10789           ipv4_set = 1;
10790           dst_set = 1;
10791         }
10792       else
10793         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
10794         {
10795           ipv6_set = 1;
10796           src_set = 1;
10797         }
10798       else
10799         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
10800         {
10801           ipv6_set = 1;
10802           dst_set = 1;
10803         }
10804       else if (unformat (line_input, "group %U %U",
10805                          unformat_ip4_address, &dst.ip4,
10806                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
10807         {
10808           grp_set = dst_set = 1;
10809           ipv4_set = 1;
10810         }
10811       else if (unformat (line_input, "group %U",
10812                          unformat_ip4_address, &dst.ip4))
10813         {
10814           grp_set = dst_set = 1;
10815           ipv4_set = 1;
10816         }
10817       else if (unformat (line_input, "group %U %U",
10818                          unformat_ip6_address, &dst.ip6,
10819                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
10820         {
10821           grp_set = dst_set = 1;
10822           ipv6_set = 1;
10823         }
10824       else if (unformat (line_input, "group %U",
10825                          unformat_ip6_address, &dst.ip6))
10826         {
10827           grp_set = dst_set = 1;
10828           ipv6_set = 1;
10829         }
10830       else
10831         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
10832         ;
10833       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
10834         ;
10835       else if (unformat (line_input, "decap-next %U",
10836                          unformat_vxlan_decap_next, &decap_next_index))
10837         ;
10838       else if (unformat (line_input, "vni %d", &vni))
10839         ;
10840       else
10841         {
10842           errmsg ("parse error '%U'", format_unformat_error, line_input);
10843           return -99;
10844         }
10845     }
10846
10847   if (src_set == 0)
10848     {
10849       errmsg ("tunnel src address not specified");
10850       return -99;
10851     }
10852   if (dst_set == 0)
10853     {
10854       errmsg ("tunnel dst address not specified");
10855       return -99;
10856     }
10857
10858   if (grp_set && !ip46_address_is_multicast (&dst))
10859     {
10860       errmsg ("tunnel group address not multicast");
10861       return -99;
10862     }
10863   if (grp_set && mcast_sw_if_index == ~0)
10864     {
10865       errmsg ("tunnel nonexistent multicast device");
10866       return -99;
10867     }
10868   if (grp_set == 0 && ip46_address_is_multicast (&dst))
10869     {
10870       errmsg ("tunnel dst address must be unicast");
10871       return -99;
10872     }
10873
10874
10875   if (ipv4_set && ipv6_set)
10876     {
10877       errmsg ("both IPv4 and IPv6 addresses specified");
10878       return -99;
10879     }
10880
10881   if ((vni == 0) || (vni >> 24))
10882     {
10883       errmsg ("vni not specified or out of range");
10884       return -99;
10885     }
10886
10887   M (VXLAN_ADD_DEL_TUNNEL, mp);
10888
10889   if (ipv6_set)
10890     {
10891       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
10892       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
10893     }
10894   else
10895     {
10896       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
10897       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
10898     }
10899   mp->encap_vrf_id = ntohl (encap_vrf_id);
10900   mp->decap_next_index = ntohl (decap_next_index);
10901   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
10902   mp->vni = ntohl (vni);
10903   mp->is_add = is_add;
10904   mp->is_ipv6 = ipv6_set;
10905
10906   S (mp);
10907   W (ret);
10908   return ret;
10909 }
10910
10911 static void vl_api_vxlan_tunnel_details_t_handler
10912   (vl_api_vxlan_tunnel_details_t * mp)
10913 {
10914   vat_main_t *vam = &vat_main;
10915   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
10916   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
10917
10918   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
10919          ntohl (mp->sw_if_index),
10920          format_ip46_address, &src, IP46_TYPE_ANY,
10921          format_ip46_address, &dst, IP46_TYPE_ANY,
10922          ntohl (mp->encap_vrf_id),
10923          ntohl (mp->decap_next_index), ntohl (mp->vni),
10924          ntohl (mp->mcast_sw_if_index));
10925 }
10926
10927 static void vl_api_vxlan_tunnel_details_t_handler_json
10928   (vl_api_vxlan_tunnel_details_t * mp)
10929 {
10930   vat_main_t *vam = &vat_main;
10931   vat_json_node_t *node = NULL;
10932
10933   if (VAT_JSON_ARRAY != vam->json_tree.type)
10934     {
10935       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10936       vat_json_init_array (&vam->json_tree);
10937     }
10938   node = vat_json_array_add (&vam->json_tree);
10939
10940   vat_json_init_object (node);
10941   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10942   if (mp->is_ipv6)
10943     {
10944       struct in6_addr ip6;
10945
10946       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
10947       vat_json_object_add_ip6 (node, "src_address", ip6);
10948       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
10949       vat_json_object_add_ip6 (node, "dst_address", ip6);
10950     }
10951   else
10952     {
10953       struct in_addr ip4;
10954
10955       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
10956       vat_json_object_add_ip4 (node, "src_address", ip4);
10957       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
10958       vat_json_object_add_ip4 (node, "dst_address", ip4);
10959     }
10960   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
10961   vat_json_object_add_uint (node, "decap_next_index",
10962                             ntohl (mp->decap_next_index));
10963   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
10964   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
10965   vat_json_object_add_uint (node, "mcast_sw_if_index",
10966                             ntohl (mp->mcast_sw_if_index));
10967 }
10968
10969 static int
10970 api_vxlan_tunnel_dump (vat_main_t * vam)
10971 {
10972   unformat_input_t *i = vam->input;
10973   vl_api_vxlan_tunnel_dump_t *mp;
10974   vl_api_control_ping_t *mp_ping;
10975   u32 sw_if_index;
10976   u8 sw_if_index_set = 0;
10977   int ret;
10978
10979   /* Parse args required to build the message */
10980   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10981     {
10982       if (unformat (i, "sw_if_index %d", &sw_if_index))
10983         sw_if_index_set = 1;
10984       else
10985         break;
10986     }
10987
10988   if (sw_if_index_set == 0)
10989     {
10990       sw_if_index = ~0;
10991     }
10992
10993   if (!vam->json_output)
10994     {
10995       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
10996              "sw_if_index", "src_address", "dst_address",
10997              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
10998     }
10999
11000   /* Get list of vxlan-tunnel interfaces */
11001   M (VXLAN_TUNNEL_DUMP, mp);
11002
11003   mp->sw_if_index = htonl (sw_if_index);
11004
11005   S (mp);
11006
11007   /* Use a control ping for synchronization */
11008   M (CONTROL_PING, mp_ping);
11009   S (mp_ping);
11010
11011   W (ret);
11012   return ret;
11013 }
11014
11015 static int
11016 api_gre_add_del_tunnel (vat_main_t * vam)
11017 {
11018   unformat_input_t *line_input = vam->input;
11019   vl_api_gre_add_del_tunnel_t *mp;
11020   ip4_address_t src4, dst4;
11021   ip6_address_t src6, dst6;
11022   u8 is_add = 1;
11023   u8 ipv4_set = 0;
11024   u8 ipv6_set = 0;
11025   u8 teb = 0;
11026   u8 src_set = 0;
11027   u8 dst_set = 0;
11028   u32 outer_fib_id = 0;
11029   int ret;
11030
11031   memset (&src4, 0, sizeof src4);
11032   memset (&dst4, 0, sizeof dst4);
11033   memset (&src6, 0, sizeof src6);
11034   memset (&dst6, 0, sizeof dst6);
11035
11036   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11037     {
11038       if (unformat (line_input, "del"))
11039         is_add = 0;
11040       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
11041         {
11042           src_set = 1;
11043           ipv4_set = 1;
11044         }
11045       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
11046         {
11047           dst_set = 1;
11048           ipv4_set = 1;
11049         }
11050       else if (unformat (line_input, "src %U", unformat_ip6_address, &src6))
11051         {
11052           src_set = 1;
11053           ipv6_set = 1;
11054         }
11055       else if (unformat (line_input, "dst %U", unformat_ip6_address, &dst6))
11056         {
11057           dst_set = 1;
11058           ipv6_set = 1;
11059         }
11060       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
11061         ;
11062       else if (unformat (line_input, "teb"))
11063         teb = 1;
11064       else
11065         {
11066           errmsg ("parse error '%U'", format_unformat_error, line_input);
11067           return -99;
11068         }
11069     }
11070
11071   if (src_set == 0)
11072     {
11073       errmsg ("tunnel src address not specified");
11074       return -99;
11075     }
11076   if (dst_set == 0)
11077     {
11078       errmsg ("tunnel dst address not specified");
11079       return -99;
11080     }
11081   if (ipv4_set && ipv6_set)
11082     {
11083       errmsg ("both IPv4 and IPv6 addresses specified");
11084       return -99;
11085     }
11086
11087
11088   M (GRE_ADD_DEL_TUNNEL, mp);
11089
11090   if (ipv4_set)
11091     {
11092       clib_memcpy (&mp->src_address, &src4, 4);
11093       clib_memcpy (&mp->dst_address, &dst4, 4);
11094     }
11095   else
11096     {
11097       clib_memcpy (&mp->src_address, &src6, 16);
11098       clib_memcpy (&mp->dst_address, &dst6, 16);
11099     }
11100   mp->outer_fib_id = ntohl (outer_fib_id);
11101   mp->is_add = is_add;
11102   mp->teb = teb;
11103   mp->is_ipv6 = ipv6_set;
11104
11105   S (mp);
11106   W (ret);
11107   return ret;
11108 }
11109
11110 static void vl_api_gre_tunnel_details_t_handler
11111   (vl_api_gre_tunnel_details_t * mp)
11112 {
11113   vat_main_t *vam = &vat_main;
11114   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->src_address);
11115   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->dst_address);
11116
11117   print (vam->ofp, "%11d%24U%24U%6d%14d",
11118          ntohl (mp->sw_if_index),
11119          format_ip46_address, &src, IP46_TYPE_ANY,
11120          format_ip46_address, &dst, IP46_TYPE_ANY,
11121          mp->teb, ntohl (mp->outer_fib_id));
11122 }
11123
11124 static void vl_api_gre_tunnel_details_t_handler_json
11125   (vl_api_gre_tunnel_details_t * mp)
11126 {
11127   vat_main_t *vam = &vat_main;
11128   vat_json_node_t *node = NULL;
11129   struct in_addr ip4;
11130   struct in6_addr ip6;
11131
11132   if (VAT_JSON_ARRAY != vam->json_tree.type)
11133     {
11134       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11135       vat_json_init_array (&vam->json_tree);
11136     }
11137   node = vat_json_array_add (&vam->json_tree);
11138
11139   vat_json_init_object (node);
11140   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11141   if (!mp->is_ipv6)
11142     {
11143       clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
11144       vat_json_object_add_ip4 (node, "src_address", ip4);
11145       clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
11146       vat_json_object_add_ip4 (node, "dst_address", ip4);
11147     }
11148   else
11149     {
11150       clib_memcpy (&ip6, &mp->src_address, sizeof (ip6));
11151       vat_json_object_add_ip6 (node, "src_address", ip6);
11152       clib_memcpy (&ip6, &mp->dst_address, sizeof (ip6));
11153       vat_json_object_add_ip6 (node, "dst_address", ip6);
11154     }
11155   vat_json_object_add_uint (node, "teb", mp->teb);
11156   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
11157   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6);
11158 }
11159
11160 static int
11161 api_gre_tunnel_dump (vat_main_t * vam)
11162 {
11163   unformat_input_t *i = vam->input;
11164   vl_api_gre_tunnel_dump_t *mp;
11165   vl_api_control_ping_t *mp_ping;
11166   u32 sw_if_index;
11167   u8 sw_if_index_set = 0;
11168   int ret;
11169
11170   /* Parse args required to build the message */
11171   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11172     {
11173       if (unformat (i, "sw_if_index %d", &sw_if_index))
11174         sw_if_index_set = 1;
11175       else
11176         break;
11177     }
11178
11179   if (sw_if_index_set == 0)
11180     {
11181       sw_if_index = ~0;
11182     }
11183
11184   if (!vam->json_output)
11185     {
11186       print (vam->ofp, "%11s%24s%24s%6s%14s",
11187              "sw_if_index", "src_address", "dst_address", "teb",
11188              "outer_fib_id");
11189     }
11190
11191   /* Get list of gre-tunnel interfaces */
11192   M (GRE_TUNNEL_DUMP, mp);
11193
11194   mp->sw_if_index = htonl (sw_if_index);
11195
11196   S (mp);
11197
11198   /* Use a control ping for synchronization */
11199   M (CONTROL_PING, mp_ping);
11200   S (mp_ping);
11201
11202   W (ret);
11203   return ret;
11204 }
11205
11206 static int
11207 api_l2_fib_clear_table (vat_main_t * vam)
11208 {
11209 //  unformat_input_t * i = vam->input;
11210   vl_api_l2_fib_clear_table_t *mp;
11211   int ret;
11212
11213   M (L2_FIB_CLEAR_TABLE, mp);
11214
11215   S (mp);
11216   W (ret);
11217   return ret;
11218 }
11219
11220 static int
11221 api_l2_interface_efp_filter (vat_main_t * vam)
11222 {
11223   unformat_input_t *i = vam->input;
11224   vl_api_l2_interface_efp_filter_t *mp;
11225   u32 sw_if_index;
11226   u8 enable = 1;
11227   u8 sw_if_index_set = 0;
11228   int ret;
11229
11230   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11231     {
11232       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11233         sw_if_index_set = 1;
11234       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11235         sw_if_index_set = 1;
11236       else if (unformat (i, "enable"))
11237         enable = 1;
11238       else if (unformat (i, "disable"))
11239         enable = 0;
11240       else
11241         {
11242           clib_warning ("parse error '%U'", format_unformat_error, i);
11243           return -99;
11244         }
11245     }
11246
11247   if (sw_if_index_set == 0)
11248     {
11249       errmsg ("missing sw_if_index");
11250       return -99;
11251     }
11252
11253   M (L2_INTERFACE_EFP_FILTER, mp);
11254
11255   mp->sw_if_index = ntohl (sw_if_index);
11256   mp->enable_disable = enable;
11257
11258   S (mp);
11259   W (ret);
11260   return ret;
11261 }
11262
11263 #define foreach_vtr_op                          \
11264 _("disable",  L2_VTR_DISABLED)                  \
11265 _("push-1",  L2_VTR_PUSH_1)                     \
11266 _("push-2",  L2_VTR_PUSH_2)                     \
11267 _("pop-1",  L2_VTR_POP_1)                       \
11268 _("pop-2",  L2_VTR_POP_2)                       \
11269 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
11270 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
11271 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
11272 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
11273
11274 static int
11275 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
11276 {
11277   unformat_input_t *i = vam->input;
11278   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
11279   u32 sw_if_index;
11280   u8 sw_if_index_set = 0;
11281   u8 vtr_op_set = 0;
11282   u32 vtr_op = 0;
11283   u32 push_dot1q = 1;
11284   u32 tag1 = ~0;
11285   u32 tag2 = ~0;
11286   int ret;
11287
11288   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11289     {
11290       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11291         sw_if_index_set = 1;
11292       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11293         sw_if_index_set = 1;
11294       else if (unformat (i, "vtr_op %d", &vtr_op))
11295         vtr_op_set = 1;
11296 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
11297       foreach_vtr_op
11298 #undef _
11299         else if (unformat (i, "push_dot1q %d", &push_dot1q))
11300         ;
11301       else if (unformat (i, "tag1 %d", &tag1))
11302         ;
11303       else if (unformat (i, "tag2 %d", &tag2))
11304         ;
11305       else
11306         {
11307           clib_warning ("parse error '%U'", format_unformat_error, i);
11308           return -99;
11309         }
11310     }
11311
11312   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
11313     {
11314       errmsg ("missing vtr operation or sw_if_index");
11315       return -99;
11316     }
11317
11318   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
11319   mp->sw_if_index = ntohl (sw_if_index);
11320   mp->vtr_op = ntohl (vtr_op);
11321   mp->push_dot1q = ntohl (push_dot1q);
11322   mp->tag1 = ntohl (tag1);
11323   mp->tag2 = ntohl (tag2);
11324
11325   S (mp);
11326   W (ret);
11327   return ret;
11328 }
11329
11330 static int
11331 api_create_vhost_user_if (vat_main_t * vam)
11332 {
11333   unformat_input_t *i = vam->input;
11334   vl_api_create_vhost_user_if_t *mp;
11335   u8 *file_name;
11336   u8 is_server = 0;
11337   u8 file_name_set = 0;
11338   u32 custom_dev_instance = ~0;
11339   u8 hwaddr[6];
11340   u8 use_custom_mac = 0;
11341   u8 *tag = 0;
11342   int ret;
11343   u8 operation_mode = VHOST_USER_POLLING_MODE;
11344
11345   /* Shut up coverity */
11346   memset (hwaddr, 0, sizeof (hwaddr));
11347
11348   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11349     {
11350       if (unformat (i, "socket %s", &file_name))
11351         {
11352           file_name_set = 1;
11353         }
11354       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
11355         ;
11356       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
11357         use_custom_mac = 1;
11358       else if (unformat (i, "server"))
11359         is_server = 1;
11360       else if (unformat (i, "tag %s", &tag))
11361         ;
11362       else if (unformat (i, "mode %U",
11363                          api_unformat_vhost_user_operation_mode,
11364                          &operation_mode))
11365         ;
11366       else
11367         break;
11368     }
11369
11370   if (file_name_set == 0)
11371     {
11372       errmsg ("missing socket file name");
11373       return -99;
11374     }
11375
11376   if (vec_len (file_name) > 255)
11377     {
11378       errmsg ("socket file name too long");
11379       return -99;
11380     }
11381   vec_add1 (file_name, 0);
11382
11383   M (CREATE_VHOST_USER_IF, mp);
11384
11385   mp->operation_mode = operation_mode;
11386   mp->is_server = is_server;
11387   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
11388   vec_free (file_name);
11389   if (custom_dev_instance != ~0)
11390     {
11391       mp->renumber = 1;
11392       mp->custom_dev_instance = ntohl (custom_dev_instance);
11393     }
11394   mp->use_custom_mac = use_custom_mac;
11395   clib_memcpy (mp->mac_address, hwaddr, 6);
11396   if (tag)
11397     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
11398   vec_free (tag);
11399
11400   S (mp);
11401   W (ret);
11402   return ret;
11403 }
11404
11405 static int
11406 api_modify_vhost_user_if (vat_main_t * vam)
11407 {
11408   unformat_input_t *i = vam->input;
11409   vl_api_modify_vhost_user_if_t *mp;
11410   u8 *file_name;
11411   u8 is_server = 0;
11412   u8 file_name_set = 0;
11413   u32 custom_dev_instance = ~0;
11414   u8 sw_if_index_set = 0;
11415   u32 sw_if_index = (u32) ~ 0;
11416   int ret;
11417   u8 operation_mode = VHOST_USER_POLLING_MODE;
11418
11419   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11420     {
11421       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11422         sw_if_index_set = 1;
11423       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11424         sw_if_index_set = 1;
11425       else if (unformat (i, "socket %s", &file_name))
11426         {
11427           file_name_set = 1;
11428         }
11429       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
11430         ;
11431       else if (unformat (i, "server"))
11432         is_server = 1;
11433       else if (unformat (i, "mode %U",
11434                          api_unformat_vhost_user_operation_mode,
11435                          &operation_mode))
11436         ;
11437       else
11438         break;
11439     }
11440
11441   if (sw_if_index_set == 0)
11442     {
11443       errmsg ("missing sw_if_index or interface name");
11444       return -99;
11445     }
11446
11447   if (file_name_set == 0)
11448     {
11449       errmsg ("missing socket file name");
11450       return -99;
11451     }
11452
11453   if (vec_len (file_name) > 255)
11454     {
11455       errmsg ("socket file name too long");
11456       return -99;
11457     }
11458   vec_add1 (file_name, 0);
11459
11460   M (MODIFY_VHOST_USER_IF, mp);
11461
11462   mp->operation_mode = operation_mode;
11463   mp->sw_if_index = ntohl (sw_if_index);
11464   mp->is_server = is_server;
11465   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
11466   vec_free (file_name);
11467   if (custom_dev_instance != ~0)
11468     {
11469       mp->renumber = 1;
11470       mp->custom_dev_instance = ntohl (custom_dev_instance);
11471     }
11472
11473   S (mp);
11474   W (ret);
11475   return ret;
11476 }
11477
11478 static int
11479 api_delete_vhost_user_if (vat_main_t * vam)
11480 {
11481   unformat_input_t *i = vam->input;
11482   vl_api_delete_vhost_user_if_t *mp;
11483   u32 sw_if_index = ~0;
11484   u8 sw_if_index_set = 0;
11485   int ret;
11486
11487   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11488     {
11489       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11490         sw_if_index_set = 1;
11491       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11492         sw_if_index_set = 1;
11493       else
11494         break;
11495     }
11496
11497   if (sw_if_index_set == 0)
11498     {
11499       errmsg ("missing sw_if_index or interface name");
11500       return -99;
11501     }
11502
11503
11504   M (DELETE_VHOST_USER_IF, mp);
11505
11506   mp->sw_if_index = ntohl (sw_if_index);
11507
11508   S (mp);
11509   W (ret);
11510   return ret;
11511 }
11512
11513 static void vl_api_sw_interface_vhost_user_details_t_handler
11514   (vl_api_sw_interface_vhost_user_details_t * mp)
11515 {
11516   vat_main_t *vam = &vat_main;
11517
11518   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %U %s",
11519          (char *) mp->interface_name,
11520          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
11521          clib_net_to_host_u64 (mp->features), mp->is_server,
11522          ntohl (mp->num_regions), api_format_vhost_user_operation_mode,
11523          mp->operation_mode, (char *) mp->sock_filename);
11524   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
11525 }
11526
11527 static void vl_api_sw_interface_vhost_user_details_t_handler_json
11528   (vl_api_sw_interface_vhost_user_details_t * mp)
11529 {
11530   vat_main_t *vam = &vat_main;
11531   vat_json_node_t *node = NULL;
11532
11533   if (VAT_JSON_ARRAY != vam->json_tree.type)
11534     {
11535       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11536       vat_json_init_array (&vam->json_tree);
11537     }
11538   node = vat_json_array_add (&vam->json_tree);
11539
11540   vat_json_init_object (node);
11541   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11542   vat_json_object_add_string_copy (node, "interface_name",
11543                                    mp->interface_name);
11544   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
11545                             ntohl (mp->virtio_net_hdr_sz));
11546   vat_json_object_add_uint (node, "features",
11547                             clib_net_to_host_u64 (mp->features));
11548   vat_json_object_add_uint (node, "is_server", mp->is_server);
11549   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
11550   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
11551   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
11552   vat_json_object_add_uint (node, "mode", mp->operation_mode);
11553 }
11554
11555 static int
11556 api_sw_interface_vhost_user_dump (vat_main_t * vam)
11557 {
11558   vl_api_sw_interface_vhost_user_dump_t *mp;
11559   vl_api_control_ping_t *mp_ping;
11560   int ret;
11561   print (vam->ofp,
11562          "Interface name            idx hdr_sz features server regions mode"
11563          "      filename");
11564
11565   /* Get list of vhost-user interfaces */
11566   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
11567   S (mp);
11568
11569   /* Use a control ping for synchronization */
11570   M (CONTROL_PING, mp_ping);
11571   S (mp_ping);
11572
11573   W (ret);
11574   return ret;
11575 }
11576
11577 static int
11578 api_show_version (vat_main_t * vam)
11579 {
11580   vl_api_show_version_t *mp;
11581   int ret;
11582
11583   M (SHOW_VERSION, mp);
11584
11585   S (mp);
11586   W (ret);
11587   return ret;
11588 }
11589
11590
11591 static int
11592 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
11593 {
11594   unformat_input_t *line_input = vam->input;
11595   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
11596   ip4_address_t local4, remote4;
11597   ip6_address_t local6, remote6;
11598   u8 is_add = 1;
11599   u8 ipv4_set = 0, ipv6_set = 0;
11600   u8 local_set = 0;
11601   u8 remote_set = 0;
11602   u32 encap_vrf_id = 0;
11603   u32 decap_vrf_id = 0;
11604   u8 protocol = ~0;
11605   u32 vni;
11606   u8 vni_set = 0;
11607   int ret;
11608
11609   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11610     {
11611       if (unformat (line_input, "del"))
11612         is_add = 0;
11613       else if (unformat (line_input, "local %U",
11614                          unformat_ip4_address, &local4))
11615         {
11616           local_set = 1;
11617           ipv4_set = 1;
11618         }
11619       else if (unformat (line_input, "remote %U",
11620                          unformat_ip4_address, &remote4))
11621         {
11622           remote_set = 1;
11623           ipv4_set = 1;
11624         }
11625       else if (unformat (line_input, "local %U",
11626                          unformat_ip6_address, &local6))
11627         {
11628           local_set = 1;
11629           ipv6_set = 1;
11630         }
11631       else if (unformat (line_input, "remote %U",
11632                          unformat_ip6_address, &remote6))
11633         {
11634           remote_set = 1;
11635           ipv6_set = 1;
11636         }
11637       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
11638         ;
11639       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
11640         ;
11641       else if (unformat (line_input, "vni %d", &vni))
11642         vni_set = 1;
11643       else if (unformat (line_input, "next-ip4"))
11644         protocol = 1;
11645       else if (unformat (line_input, "next-ip6"))
11646         protocol = 2;
11647       else if (unformat (line_input, "next-ethernet"))
11648         protocol = 3;
11649       else if (unformat (line_input, "next-nsh"))
11650         protocol = 4;
11651       else
11652         {
11653           errmsg ("parse error '%U'", format_unformat_error, line_input);
11654           return -99;
11655         }
11656     }
11657
11658   if (local_set == 0)
11659     {
11660       errmsg ("tunnel local address not specified");
11661       return -99;
11662     }
11663   if (remote_set == 0)
11664     {
11665       errmsg ("tunnel remote address not specified");
11666       return -99;
11667     }
11668   if (ipv4_set && ipv6_set)
11669     {
11670       errmsg ("both IPv4 and IPv6 addresses specified");
11671       return -99;
11672     }
11673
11674   if (vni_set == 0)
11675     {
11676       errmsg ("vni not specified");
11677       return -99;
11678     }
11679
11680   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
11681
11682
11683   if (ipv6_set)
11684     {
11685       clib_memcpy (&mp->local, &local6, sizeof (local6));
11686       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
11687     }
11688   else
11689     {
11690       clib_memcpy (&mp->local, &local4, sizeof (local4));
11691       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
11692     }
11693
11694   mp->encap_vrf_id = ntohl (encap_vrf_id);
11695   mp->decap_vrf_id = ntohl (decap_vrf_id);
11696   mp->protocol = protocol;
11697   mp->vni = ntohl (vni);
11698   mp->is_add = is_add;
11699   mp->is_ipv6 = ipv6_set;
11700
11701   S (mp);
11702   W (ret);
11703   return ret;
11704 }
11705
11706 static void vl_api_vxlan_gpe_tunnel_details_t_handler
11707   (vl_api_vxlan_gpe_tunnel_details_t * mp)
11708 {
11709   vat_main_t *vam = &vat_main;
11710
11711   print (vam->ofp, "%11d%24U%24U%13d%12d%14d%14d",
11712          ntohl (mp->sw_if_index),
11713          format_ip46_address, &(mp->local[0]),
11714          format_ip46_address, &(mp->remote[0]),
11715          ntohl (mp->vni),
11716          ntohl (mp->protocol),
11717          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
11718 }
11719
11720 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
11721   (vl_api_vxlan_gpe_tunnel_details_t * mp)
11722 {
11723   vat_main_t *vam = &vat_main;
11724   vat_json_node_t *node = NULL;
11725   struct in_addr ip4;
11726   struct in6_addr ip6;
11727
11728   if (VAT_JSON_ARRAY != vam->json_tree.type)
11729     {
11730       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11731       vat_json_init_array (&vam->json_tree);
11732     }
11733   node = vat_json_array_add (&vam->json_tree);
11734
11735   vat_json_init_object (node);
11736   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11737   if (mp->is_ipv6)
11738     {
11739       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
11740       vat_json_object_add_ip6 (node, "local", ip6);
11741       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
11742       vat_json_object_add_ip6 (node, "remote", ip6);
11743     }
11744   else
11745     {
11746       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
11747       vat_json_object_add_ip4 (node, "local", ip4);
11748       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
11749       vat_json_object_add_ip4 (node, "remote", ip4);
11750     }
11751   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
11752   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
11753   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
11754   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
11755   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
11756 }
11757
11758 static int
11759 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
11760 {
11761   unformat_input_t *i = vam->input;
11762   vl_api_vxlan_gpe_tunnel_dump_t *mp;
11763   vl_api_control_ping_t *mp_ping;
11764   u32 sw_if_index;
11765   u8 sw_if_index_set = 0;
11766   int ret;
11767
11768   /* Parse args required to build the message */
11769   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11770     {
11771       if (unformat (i, "sw_if_index %d", &sw_if_index))
11772         sw_if_index_set = 1;
11773       else
11774         break;
11775     }
11776
11777   if (sw_if_index_set == 0)
11778     {
11779       sw_if_index = ~0;
11780     }
11781
11782   if (!vam->json_output)
11783     {
11784       print (vam->ofp, "%11s%24s%24s%13s%15s%14s%14s",
11785              "sw_if_index", "local", "remote", "vni",
11786              "protocol", "encap_vrf_id", "decap_vrf_id");
11787     }
11788
11789   /* Get list of vxlan-tunnel interfaces */
11790   M (VXLAN_GPE_TUNNEL_DUMP, mp);
11791
11792   mp->sw_if_index = htonl (sw_if_index);
11793
11794   S (mp);
11795
11796   /* Use a control ping for synchronization */
11797   M (CONTROL_PING, mp_ping);
11798   S (mp_ping);
11799
11800   W (ret);
11801   return ret;
11802 }
11803
11804 u8 *
11805 format_l2_fib_mac_address (u8 * s, va_list * args)
11806 {
11807   u8 *a = va_arg (*args, u8 *);
11808
11809   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
11810                  a[2], a[3], a[4], a[5], a[6], a[7]);
11811 }
11812
11813 static void vl_api_l2_fib_table_entry_t_handler
11814   (vl_api_l2_fib_table_entry_t * mp)
11815 {
11816   vat_main_t *vam = &vat_main;
11817
11818   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
11819          "       %d       %d     %d",
11820          ntohl (mp->bd_id), format_l2_fib_mac_address, &mp->mac,
11821          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
11822          mp->bvi_mac);
11823 }
11824
11825 static void vl_api_l2_fib_table_entry_t_handler_json
11826   (vl_api_l2_fib_table_entry_t * mp)
11827 {
11828   vat_main_t *vam = &vat_main;
11829   vat_json_node_t *node = NULL;
11830
11831   if (VAT_JSON_ARRAY != vam->json_tree.type)
11832     {
11833       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11834       vat_json_init_array (&vam->json_tree);
11835     }
11836   node = vat_json_array_add (&vam->json_tree);
11837
11838   vat_json_init_object (node);
11839   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
11840   vat_json_object_add_uint (node, "mac", clib_net_to_host_u64 (mp->mac));
11841   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11842   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
11843   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
11844   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
11845 }
11846
11847 static int
11848 api_l2_fib_table_dump (vat_main_t * vam)
11849 {
11850   unformat_input_t *i = vam->input;
11851   vl_api_l2_fib_table_dump_t *mp;
11852   vl_api_control_ping_t *mp_ping;
11853   u32 bd_id;
11854   u8 bd_id_set = 0;
11855   int ret;
11856
11857   /* Parse args required to build the message */
11858   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11859     {
11860       if (unformat (i, "bd_id %d", &bd_id))
11861         bd_id_set = 1;
11862       else
11863         break;
11864     }
11865
11866   if (bd_id_set == 0)
11867     {
11868       errmsg ("missing bridge domain");
11869       return -99;
11870     }
11871
11872   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
11873
11874   /* Get list of l2 fib entries */
11875   M (L2_FIB_TABLE_DUMP, mp);
11876
11877   mp->bd_id = ntohl (bd_id);
11878   S (mp);
11879
11880   /* Use a control ping for synchronization */
11881   M (CONTROL_PING, mp_ping);
11882   S (mp_ping);
11883
11884   W (ret);
11885   return ret;
11886 }
11887
11888
11889 static int
11890 api_interface_name_renumber (vat_main_t * vam)
11891 {
11892   unformat_input_t *line_input = vam->input;
11893   vl_api_interface_name_renumber_t *mp;
11894   u32 sw_if_index = ~0;
11895   u32 new_show_dev_instance = ~0;
11896   int ret;
11897
11898   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11899     {
11900       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
11901                     &sw_if_index))
11902         ;
11903       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
11904         ;
11905       else if (unformat (line_input, "new_show_dev_instance %d",
11906                          &new_show_dev_instance))
11907         ;
11908       else
11909         break;
11910     }
11911
11912   if (sw_if_index == ~0)
11913     {
11914       errmsg ("missing interface name or sw_if_index");
11915       return -99;
11916     }
11917
11918   if (new_show_dev_instance == ~0)
11919     {
11920       errmsg ("missing new_show_dev_instance");
11921       return -99;
11922     }
11923
11924   M (INTERFACE_NAME_RENUMBER, mp);
11925
11926   mp->sw_if_index = ntohl (sw_if_index);
11927   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
11928
11929   S (mp);
11930   W (ret);
11931   return ret;
11932 }
11933
11934 static int
11935 api_want_ip4_arp_events (vat_main_t * vam)
11936 {
11937   unformat_input_t *line_input = vam->input;
11938   vl_api_want_ip4_arp_events_t *mp;
11939   ip4_address_t address;
11940   int address_set = 0;
11941   u32 enable_disable = 1;
11942   int ret;
11943
11944   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11945     {
11946       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
11947         address_set = 1;
11948       else if (unformat (line_input, "del"))
11949         enable_disable = 0;
11950       else
11951         break;
11952     }
11953
11954   if (address_set == 0)
11955     {
11956       errmsg ("missing addresses");
11957       return -99;
11958     }
11959
11960   M (WANT_IP4_ARP_EVENTS, mp);
11961   mp->enable_disable = enable_disable;
11962   mp->pid = htonl (getpid ());
11963   mp->address = address.as_u32;
11964
11965   S (mp);
11966   W (ret);
11967   return ret;
11968 }
11969
11970 static int
11971 api_want_ip6_nd_events (vat_main_t * vam)
11972 {
11973   unformat_input_t *line_input = vam->input;
11974   vl_api_want_ip6_nd_events_t *mp;
11975   ip6_address_t address;
11976   int address_set = 0;
11977   u32 enable_disable = 1;
11978   int ret;
11979
11980   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11981     {
11982       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
11983         address_set = 1;
11984       else if (unformat (line_input, "del"))
11985         enable_disable = 0;
11986       else
11987         break;
11988     }
11989
11990   if (address_set == 0)
11991     {
11992       errmsg ("missing addresses");
11993       return -99;
11994     }
11995
11996   M (WANT_IP6_ND_EVENTS, mp);
11997   mp->enable_disable = enable_disable;
11998   mp->pid = htonl (getpid ());
11999   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
12000
12001   S (mp);
12002   W (ret);
12003   return ret;
12004 }
12005
12006 static int
12007 api_input_acl_set_interface (vat_main_t * vam)
12008 {
12009   unformat_input_t *i = vam->input;
12010   vl_api_input_acl_set_interface_t *mp;
12011   u32 sw_if_index;
12012   int sw_if_index_set;
12013   u32 ip4_table_index = ~0;
12014   u32 ip6_table_index = ~0;
12015   u32 l2_table_index = ~0;
12016   u8 is_add = 1;
12017   int ret;
12018
12019   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12020     {
12021       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12022         sw_if_index_set = 1;
12023       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12024         sw_if_index_set = 1;
12025       else if (unformat (i, "del"))
12026         is_add = 0;
12027       else if (unformat (i, "ip4-table %d", &ip4_table_index))
12028         ;
12029       else if (unformat (i, "ip6-table %d", &ip6_table_index))
12030         ;
12031       else if (unformat (i, "l2-table %d", &l2_table_index))
12032         ;
12033       else
12034         {
12035           clib_warning ("parse error '%U'", format_unformat_error, i);
12036           return -99;
12037         }
12038     }
12039
12040   if (sw_if_index_set == 0)
12041     {
12042       errmsg ("missing interface name or sw_if_index");
12043       return -99;
12044     }
12045
12046   M (INPUT_ACL_SET_INTERFACE, mp);
12047
12048   mp->sw_if_index = ntohl (sw_if_index);
12049   mp->ip4_table_index = ntohl (ip4_table_index);
12050   mp->ip6_table_index = ntohl (ip6_table_index);
12051   mp->l2_table_index = ntohl (l2_table_index);
12052   mp->is_add = is_add;
12053
12054   S (mp);
12055   W (ret);
12056   return ret;
12057 }
12058
12059 static int
12060 api_ip_address_dump (vat_main_t * vam)
12061 {
12062   unformat_input_t *i = vam->input;
12063   vl_api_ip_address_dump_t *mp;
12064   vl_api_control_ping_t *mp_ping;
12065   u32 sw_if_index = ~0;
12066   u8 sw_if_index_set = 0;
12067   u8 ipv4_set = 0;
12068   u8 ipv6_set = 0;
12069   int ret;
12070
12071   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12072     {
12073       if (unformat (i, "sw_if_index %d", &sw_if_index))
12074         sw_if_index_set = 1;
12075       else
12076         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12077         sw_if_index_set = 1;
12078       else if (unformat (i, "ipv4"))
12079         ipv4_set = 1;
12080       else if (unformat (i, "ipv6"))
12081         ipv6_set = 1;
12082       else
12083         break;
12084     }
12085
12086   if (ipv4_set && ipv6_set)
12087     {
12088       errmsg ("ipv4 and ipv6 flags cannot be both set");
12089       return -99;
12090     }
12091
12092   if ((!ipv4_set) && (!ipv6_set))
12093     {
12094       errmsg ("no ipv4 nor ipv6 flag set");
12095       return -99;
12096     }
12097
12098   if (sw_if_index_set == 0)
12099     {
12100       errmsg ("missing interface name or sw_if_index");
12101       return -99;
12102     }
12103
12104   vam->current_sw_if_index = sw_if_index;
12105   vam->is_ipv6 = ipv6_set;
12106
12107   M (IP_ADDRESS_DUMP, mp);
12108   mp->sw_if_index = ntohl (sw_if_index);
12109   mp->is_ipv6 = ipv6_set;
12110   S (mp);
12111
12112   /* Use a control ping for synchronization */
12113   M (CONTROL_PING, mp_ping);
12114   S (mp_ping);
12115
12116   W (ret);
12117   return ret;
12118 }
12119
12120 static int
12121 api_ip_dump (vat_main_t * vam)
12122 {
12123   vl_api_ip_dump_t *mp;
12124   vl_api_control_ping_t *mp_ping;
12125   unformat_input_t *in = vam->input;
12126   int ipv4_set = 0;
12127   int ipv6_set = 0;
12128   int is_ipv6;
12129   int i;
12130   int ret;
12131
12132   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
12133     {
12134       if (unformat (in, "ipv4"))
12135         ipv4_set = 1;
12136       else if (unformat (in, "ipv6"))
12137         ipv6_set = 1;
12138       else
12139         break;
12140     }
12141
12142   if (ipv4_set && ipv6_set)
12143     {
12144       errmsg ("ipv4 and ipv6 flags cannot be both set");
12145       return -99;
12146     }
12147
12148   if ((!ipv4_set) && (!ipv6_set))
12149     {
12150       errmsg ("no ipv4 nor ipv6 flag set");
12151       return -99;
12152     }
12153
12154   is_ipv6 = ipv6_set;
12155   vam->is_ipv6 = is_ipv6;
12156
12157   /* free old data */
12158   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
12159     {
12160       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
12161     }
12162   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
12163
12164   M (IP_DUMP, mp);
12165   mp->is_ipv6 = ipv6_set;
12166   S (mp);
12167
12168   /* Use a control ping for synchronization */
12169   M (CONTROL_PING, mp_ping);
12170   S (mp_ping);
12171
12172   W (ret);
12173   return ret;
12174 }
12175
12176 static int
12177 api_ipsec_spd_add_del (vat_main_t * vam)
12178 {
12179   unformat_input_t *i = vam->input;
12180   vl_api_ipsec_spd_add_del_t *mp;
12181   u32 spd_id = ~0;
12182   u8 is_add = 1;
12183   int ret;
12184
12185   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12186     {
12187       if (unformat (i, "spd_id %d", &spd_id))
12188         ;
12189       else if (unformat (i, "del"))
12190         is_add = 0;
12191       else
12192         {
12193           clib_warning ("parse error '%U'", format_unformat_error, i);
12194           return -99;
12195         }
12196     }
12197   if (spd_id == ~0)
12198     {
12199       errmsg ("spd_id must be set");
12200       return -99;
12201     }
12202
12203   M (IPSEC_SPD_ADD_DEL, mp);
12204
12205   mp->spd_id = ntohl (spd_id);
12206   mp->is_add = is_add;
12207
12208   S (mp);
12209   W (ret);
12210   return ret;
12211 }
12212
12213 static int
12214 api_ipsec_interface_add_del_spd (vat_main_t * vam)
12215 {
12216   unformat_input_t *i = vam->input;
12217   vl_api_ipsec_interface_add_del_spd_t *mp;
12218   u32 sw_if_index;
12219   u8 sw_if_index_set = 0;
12220   u32 spd_id = (u32) ~ 0;
12221   u8 is_add = 1;
12222   int ret;
12223
12224   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12225     {
12226       if (unformat (i, "del"))
12227         is_add = 0;
12228       else if (unformat (i, "spd_id %d", &spd_id))
12229         ;
12230       else
12231         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12232         sw_if_index_set = 1;
12233       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12234         sw_if_index_set = 1;
12235       else
12236         {
12237           clib_warning ("parse error '%U'", format_unformat_error, i);
12238           return -99;
12239         }
12240
12241     }
12242
12243   if (spd_id == (u32) ~ 0)
12244     {
12245       errmsg ("spd_id must be set");
12246       return -99;
12247     }
12248
12249   if (sw_if_index_set == 0)
12250     {
12251       errmsg ("missing interface name or sw_if_index");
12252       return -99;
12253     }
12254
12255   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
12256
12257   mp->spd_id = ntohl (spd_id);
12258   mp->sw_if_index = ntohl (sw_if_index);
12259   mp->is_add = is_add;
12260
12261   S (mp);
12262   W (ret);
12263   return ret;
12264 }
12265
12266 static int
12267 api_ipsec_spd_add_del_entry (vat_main_t * vam)
12268 {
12269   unformat_input_t *i = vam->input;
12270   vl_api_ipsec_spd_add_del_entry_t *mp;
12271   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
12272   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
12273   i32 priority = 0;
12274   u32 rport_start = 0, rport_stop = (u32) ~ 0;
12275   u32 lport_start = 0, lport_stop = (u32) ~ 0;
12276   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
12277   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
12278   int ret;
12279
12280   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
12281   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
12282   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
12283   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
12284   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
12285   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
12286
12287   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12288     {
12289       if (unformat (i, "del"))
12290         is_add = 0;
12291       if (unformat (i, "outbound"))
12292         is_outbound = 1;
12293       if (unformat (i, "inbound"))
12294         is_outbound = 0;
12295       else if (unformat (i, "spd_id %d", &spd_id))
12296         ;
12297       else if (unformat (i, "sa_id %d", &sa_id))
12298         ;
12299       else if (unformat (i, "priority %d", &priority))
12300         ;
12301       else if (unformat (i, "protocol %d", &protocol))
12302         ;
12303       else if (unformat (i, "lport_start %d", &lport_start))
12304         ;
12305       else if (unformat (i, "lport_stop %d", &lport_stop))
12306         ;
12307       else if (unformat (i, "rport_start %d", &rport_start))
12308         ;
12309       else if (unformat (i, "rport_stop %d", &rport_stop))
12310         ;
12311       else
12312         if (unformat
12313             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
12314         {
12315           is_ipv6 = 0;
12316           is_ip_any = 0;
12317         }
12318       else
12319         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
12320         {
12321           is_ipv6 = 0;
12322           is_ip_any = 0;
12323         }
12324       else
12325         if (unformat
12326             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
12327         {
12328           is_ipv6 = 0;
12329           is_ip_any = 0;
12330         }
12331       else
12332         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
12333         {
12334           is_ipv6 = 0;
12335           is_ip_any = 0;
12336         }
12337       else
12338         if (unformat
12339             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
12340         {
12341           is_ipv6 = 1;
12342           is_ip_any = 0;
12343         }
12344       else
12345         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
12346         {
12347           is_ipv6 = 1;
12348           is_ip_any = 0;
12349         }
12350       else
12351         if (unformat
12352             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
12353         {
12354           is_ipv6 = 1;
12355           is_ip_any = 0;
12356         }
12357       else
12358         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
12359         {
12360           is_ipv6 = 1;
12361           is_ip_any = 0;
12362         }
12363       else
12364         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
12365         {
12366           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
12367             {
12368               clib_warning ("unsupported action: 'resolve'");
12369               return -99;
12370             }
12371         }
12372       else
12373         {
12374           clib_warning ("parse error '%U'", format_unformat_error, i);
12375           return -99;
12376         }
12377
12378     }
12379
12380   M (IPSEC_SPD_ADD_DEL_ENTRY, mp);
12381
12382   mp->spd_id = ntohl (spd_id);
12383   mp->priority = ntohl (priority);
12384   mp->is_outbound = is_outbound;
12385
12386   mp->is_ipv6 = is_ipv6;
12387   if (is_ipv6 || is_ip_any)
12388     {
12389       clib_memcpy (mp->remote_address_start, &raddr6_start,
12390                    sizeof (ip6_address_t));
12391       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
12392                    sizeof (ip6_address_t));
12393       clib_memcpy (mp->local_address_start, &laddr6_start,
12394                    sizeof (ip6_address_t));
12395       clib_memcpy (mp->local_address_stop, &laddr6_stop,
12396                    sizeof (ip6_address_t));
12397     }
12398   else
12399     {
12400       clib_memcpy (mp->remote_address_start, &raddr4_start,
12401                    sizeof (ip4_address_t));
12402       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
12403                    sizeof (ip4_address_t));
12404       clib_memcpy (mp->local_address_start, &laddr4_start,
12405                    sizeof (ip4_address_t));
12406       clib_memcpy (mp->local_address_stop, &laddr4_stop,
12407                    sizeof (ip4_address_t));
12408     }
12409   mp->protocol = (u8) protocol;
12410   mp->local_port_start = ntohs ((u16) lport_start);
12411   mp->local_port_stop = ntohs ((u16) lport_stop);
12412   mp->remote_port_start = ntohs ((u16) rport_start);
12413   mp->remote_port_stop = ntohs ((u16) rport_stop);
12414   mp->policy = (u8) policy;
12415   mp->sa_id = ntohl (sa_id);
12416   mp->is_add = is_add;
12417   mp->is_ip_any = is_ip_any;
12418   S (mp);
12419   W (ret);
12420   return ret;
12421 }
12422
12423 static int
12424 api_ipsec_sad_add_del_entry (vat_main_t * vam)
12425 {
12426   unformat_input_t *i = vam->input;
12427   vl_api_ipsec_sad_add_del_entry_t *mp;
12428   u32 sad_id = 0, spi = 0;
12429   u8 *ck = 0, *ik = 0;
12430   u8 is_add = 1;
12431
12432   u8 protocol = IPSEC_PROTOCOL_AH;
12433   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
12434   u32 crypto_alg = 0, integ_alg = 0;
12435   ip4_address_t tun_src4;
12436   ip4_address_t tun_dst4;
12437   ip6_address_t tun_src6;
12438   ip6_address_t tun_dst6;
12439   int ret;
12440
12441   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12442     {
12443       if (unformat (i, "del"))
12444         is_add = 0;
12445       else if (unformat (i, "sad_id %d", &sad_id))
12446         ;
12447       else if (unformat (i, "spi %d", &spi))
12448         ;
12449       else if (unformat (i, "esp"))
12450         protocol = IPSEC_PROTOCOL_ESP;
12451       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
12452         {
12453           is_tunnel = 1;
12454           is_tunnel_ipv6 = 0;
12455         }
12456       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
12457         {
12458           is_tunnel = 1;
12459           is_tunnel_ipv6 = 0;
12460         }
12461       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
12462         {
12463           is_tunnel = 1;
12464           is_tunnel_ipv6 = 1;
12465         }
12466       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
12467         {
12468           is_tunnel = 1;
12469           is_tunnel_ipv6 = 1;
12470         }
12471       else
12472         if (unformat
12473             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
12474         {
12475           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
12476               crypto_alg >= IPSEC_CRYPTO_N_ALG)
12477             {
12478               clib_warning ("unsupported crypto-alg: '%U'",
12479                             format_ipsec_crypto_alg, crypto_alg);
12480               return -99;
12481             }
12482         }
12483       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
12484         ;
12485       else
12486         if (unformat
12487             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
12488         {
12489           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
12490               integ_alg >= IPSEC_INTEG_N_ALG)
12491             {
12492               clib_warning ("unsupported integ-alg: '%U'",
12493                             format_ipsec_integ_alg, integ_alg);
12494               return -99;
12495             }
12496         }
12497       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
12498         ;
12499       else
12500         {
12501           clib_warning ("parse error '%U'", format_unformat_error, i);
12502           return -99;
12503         }
12504
12505     }
12506
12507   M (IPSEC_SAD_ADD_DEL_ENTRY, mp);
12508
12509   mp->sad_id = ntohl (sad_id);
12510   mp->is_add = is_add;
12511   mp->protocol = protocol;
12512   mp->spi = ntohl (spi);
12513   mp->is_tunnel = is_tunnel;
12514   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
12515   mp->crypto_algorithm = crypto_alg;
12516   mp->integrity_algorithm = integ_alg;
12517   mp->crypto_key_length = vec_len (ck);
12518   mp->integrity_key_length = vec_len (ik);
12519
12520   if (mp->crypto_key_length > sizeof (mp->crypto_key))
12521     mp->crypto_key_length = sizeof (mp->crypto_key);
12522
12523   if (mp->integrity_key_length > sizeof (mp->integrity_key))
12524     mp->integrity_key_length = sizeof (mp->integrity_key);
12525
12526   if (ck)
12527     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
12528   if (ik)
12529     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
12530
12531   if (is_tunnel)
12532     {
12533       if (is_tunnel_ipv6)
12534         {
12535           clib_memcpy (mp->tunnel_src_address, &tun_src6,
12536                        sizeof (ip6_address_t));
12537           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
12538                        sizeof (ip6_address_t));
12539         }
12540       else
12541         {
12542           clib_memcpy (mp->tunnel_src_address, &tun_src4,
12543                        sizeof (ip4_address_t));
12544           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
12545                        sizeof (ip4_address_t));
12546         }
12547     }
12548
12549   S (mp);
12550   W (ret);
12551   return ret;
12552 }
12553
12554 static int
12555 api_ipsec_sa_set_key (vat_main_t * vam)
12556 {
12557   unformat_input_t *i = vam->input;
12558   vl_api_ipsec_sa_set_key_t *mp;
12559   u32 sa_id;
12560   u8 *ck = 0, *ik = 0;
12561   int ret;
12562
12563   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12564     {
12565       if (unformat (i, "sa_id %d", &sa_id))
12566         ;
12567       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
12568         ;
12569       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
12570         ;
12571       else
12572         {
12573           clib_warning ("parse error '%U'", format_unformat_error, i);
12574           return -99;
12575         }
12576     }
12577
12578   M (IPSEC_SA_SET_KEY, mp);
12579
12580   mp->sa_id = ntohl (sa_id);
12581   mp->crypto_key_length = vec_len (ck);
12582   mp->integrity_key_length = vec_len (ik);
12583
12584   if (mp->crypto_key_length > sizeof (mp->crypto_key))
12585     mp->crypto_key_length = sizeof (mp->crypto_key);
12586
12587   if (mp->integrity_key_length > sizeof (mp->integrity_key))
12588     mp->integrity_key_length = sizeof (mp->integrity_key);
12589
12590   if (ck)
12591     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
12592   if (ik)
12593     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
12594
12595   S (mp);
12596   W (ret);
12597   return ret;
12598 }
12599
12600 static int
12601 api_ikev2_profile_add_del (vat_main_t * vam)
12602 {
12603   unformat_input_t *i = vam->input;
12604   vl_api_ikev2_profile_add_del_t *mp;
12605   u8 is_add = 1;
12606   u8 *name = 0;
12607   int ret;
12608
12609   const char *valid_chars = "a-zA-Z0-9_";
12610
12611   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12612     {
12613       if (unformat (i, "del"))
12614         is_add = 0;
12615       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12616         vec_add1 (name, 0);
12617       else
12618         {
12619           errmsg ("parse error '%U'", format_unformat_error, i);
12620           return -99;
12621         }
12622     }
12623
12624   if (!vec_len (name))
12625     {
12626       errmsg ("profile name must be specified");
12627       return -99;
12628     }
12629
12630   if (vec_len (name) > 64)
12631     {
12632       errmsg ("profile name too long");
12633       return -99;
12634     }
12635
12636   M (IKEV2_PROFILE_ADD_DEL, mp);
12637
12638   clib_memcpy (mp->name, name, vec_len (name));
12639   mp->is_add = is_add;
12640   vec_free (name);
12641
12642   S (mp);
12643   W (ret);
12644   return ret;
12645 }
12646
12647 static int
12648 api_ikev2_profile_set_auth (vat_main_t * vam)
12649 {
12650   unformat_input_t *i = vam->input;
12651   vl_api_ikev2_profile_set_auth_t *mp;
12652   u8 *name = 0;
12653   u8 *data = 0;
12654   u32 auth_method = 0;
12655   u8 is_hex = 0;
12656   int ret;
12657
12658   const char *valid_chars = "a-zA-Z0-9_";
12659
12660   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12661     {
12662       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12663         vec_add1 (name, 0);
12664       else if (unformat (i, "auth_method %U",
12665                          unformat_ikev2_auth_method, &auth_method))
12666         ;
12667       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
12668         is_hex = 1;
12669       else if (unformat (i, "auth_data %v", &data))
12670         ;
12671       else
12672         {
12673           errmsg ("parse error '%U'", format_unformat_error, i);
12674           return -99;
12675         }
12676     }
12677
12678   if (!vec_len (name))
12679     {
12680       errmsg ("profile name must be specified");
12681       return -99;
12682     }
12683
12684   if (vec_len (name) > 64)
12685     {
12686       errmsg ("profile name too long");
12687       return -99;
12688     }
12689
12690   if (!vec_len (data))
12691     {
12692       errmsg ("auth_data must be specified");
12693       return -99;
12694     }
12695
12696   if (!auth_method)
12697     {
12698       errmsg ("auth_method must be specified");
12699       return -99;
12700     }
12701
12702   M (IKEV2_PROFILE_SET_AUTH, mp);
12703
12704   mp->is_hex = is_hex;
12705   mp->auth_method = (u8) auth_method;
12706   mp->data_len = vec_len (data);
12707   clib_memcpy (mp->name, name, vec_len (name));
12708   clib_memcpy (mp->data, data, vec_len (data));
12709   vec_free (name);
12710   vec_free (data);
12711
12712   S (mp);
12713   W (ret);
12714   return ret;
12715 }
12716
12717 static int
12718 api_ikev2_profile_set_id (vat_main_t * vam)
12719 {
12720   unformat_input_t *i = vam->input;
12721   vl_api_ikev2_profile_set_id_t *mp;
12722   u8 *name = 0;
12723   u8 *data = 0;
12724   u8 is_local = 0;
12725   u32 id_type = 0;
12726   ip4_address_t ip4;
12727   int ret;
12728
12729   const char *valid_chars = "a-zA-Z0-9_";
12730
12731   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12732     {
12733       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12734         vec_add1 (name, 0);
12735       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
12736         ;
12737       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
12738         {
12739           data = vec_new (u8, 4);
12740           clib_memcpy (data, ip4.as_u8, 4);
12741         }
12742       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
12743         ;
12744       else if (unformat (i, "id_data %v", &data))
12745         ;
12746       else if (unformat (i, "local"))
12747         is_local = 1;
12748       else if (unformat (i, "remote"))
12749         is_local = 0;
12750       else
12751         {
12752           errmsg ("parse error '%U'", format_unformat_error, i);
12753           return -99;
12754         }
12755     }
12756
12757   if (!vec_len (name))
12758     {
12759       errmsg ("profile name must be specified");
12760       return -99;
12761     }
12762
12763   if (vec_len (name) > 64)
12764     {
12765       errmsg ("profile name too long");
12766       return -99;
12767     }
12768
12769   if (!vec_len (data))
12770     {
12771       errmsg ("id_data must be specified");
12772       return -99;
12773     }
12774
12775   if (!id_type)
12776     {
12777       errmsg ("id_type must be specified");
12778       return -99;
12779     }
12780
12781   M (IKEV2_PROFILE_SET_ID, mp);
12782
12783   mp->is_local = is_local;
12784   mp->id_type = (u8) id_type;
12785   mp->data_len = vec_len (data);
12786   clib_memcpy (mp->name, name, vec_len (name));
12787   clib_memcpy (mp->data, data, vec_len (data));
12788   vec_free (name);
12789   vec_free (data);
12790
12791   S (mp);
12792   W (ret);
12793   return ret;
12794 }
12795
12796 static int
12797 api_ikev2_profile_set_ts (vat_main_t * vam)
12798 {
12799   unformat_input_t *i = vam->input;
12800   vl_api_ikev2_profile_set_ts_t *mp;
12801   u8 *name = 0;
12802   u8 is_local = 0;
12803   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
12804   ip4_address_t start_addr, end_addr;
12805
12806   const char *valid_chars = "a-zA-Z0-9_";
12807   int ret;
12808
12809   start_addr.as_u32 = 0;
12810   end_addr.as_u32 = (u32) ~ 0;
12811
12812   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12813     {
12814       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12815         vec_add1 (name, 0);
12816       else if (unformat (i, "protocol %d", &proto))
12817         ;
12818       else if (unformat (i, "start_port %d", &start_port))
12819         ;
12820       else if (unformat (i, "end_port %d", &end_port))
12821         ;
12822       else
12823         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
12824         ;
12825       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
12826         ;
12827       else if (unformat (i, "local"))
12828         is_local = 1;
12829       else if (unformat (i, "remote"))
12830         is_local = 0;
12831       else
12832         {
12833           errmsg ("parse error '%U'", format_unformat_error, i);
12834           return -99;
12835         }
12836     }
12837
12838   if (!vec_len (name))
12839     {
12840       errmsg ("profile name must be specified");
12841       return -99;
12842     }
12843
12844   if (vec_len (name) > 64)
12845     {
12846       errmsg ("profile name too long");
12847       return -99;
12848     }
12849
12850   M (IKEV2_PROFILE_SET_TS, mp);
12851
12852   mp->is_local = is_local;
12853   mp->proto = (u8) proto;
12854   mp->start_port = (u16) start_port;
12855   mp->end_port = (u16) end_port;
12856   mp->start_addr = start_addr.as_u32;
12857   mp->end_addr = end_addr.as_u32;
12858   clib_memcpy (mp->name, name, vec_len (name));
12859   vec_free (name);
12860
12861   S (mp);
12862   W (ret);
12863   return ret;
12864 }
12865
12866 static int
12867 api_ikev2_set_local_key (vat_main_t * vam)
12868 {
12869   unformat_input_t *i = vam->input;
12870   vl_api_ikev2_set_local_key_t *mp;
12871   u8 *file = 0;
12872   int ret;
12873
12874   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12875     {
12876       if (unformat (i, "file %v", &file))
12877         vec_add1 (file, 0);
12878       else
12879         {
12880           errmsg ("parse error '%U'", format_unformat_error, i);
12881           return -99;
12882         }
12883     }
12884
12885   if (!vec_len (file))
12886     {
12887       errmsg ("RSA key file must be specified");
12888       return -99;
12889     }
12890
12891   if (vec_len (file) > 256)
12892     {
12893       errmsg ("file name too long");
12894       return -99;
12895     }
12896
12897   M (IKEV2_SET_LOCAL_KEY, mp);
12898
12899   clib_memcpy (mp->key_file, file, vec_len (file));
12900   vec_free (file);
12901
12902   S (mp);
12903   W (ret);
12904   return ret;
12905 }
12906
12907 static int
12908 api_ikev2_set_responder (vat_main_t * vam)
12909 {
12910   unformat_input_t *i = vam->input;
12911   vl_api_ikev2_set_responder_t *mp;
12912   int ret;
12913   u8 *name = 0;
12914   u32 sw_if_index = ~0;
12915   ip4_address_t address;
12916
12917   const char *valid_chars = "a-zA-Z0-9_";
12918
12919   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12920     {
12921       if (unformat
12922           (i, "%U interface %d address %U", unformat_token, valid_chars,
12923            &name, &sw_if_index, unformat_ip4_address, &address))
12924         vec_add1 (name, 0);
12925       else
12926         {
12927           errmsg ("parse error '%U'", format_unformat_error, i);
12928           return -99;
12929         }
12930     }
12931
12932   if (!vec_len (name))
12933     {
12934       errmsg ("profile name must be specified");
12935       return -99;
12936     }
12937
12938   if (vec_len (name) > 64)
12939     {
12940       errmsg ("profile name too long");
12941       return -99;
12942     }
12943
12944   M (IKEV2_SET_RESPONDER, mp);
12945
12946   clib_memcpy (mp->name, name, vec_len (name));
12947   vec_free (name);
12948
12949   mp->sw_if_index = sw_if_index;
12950   clib_memcpy (mp->address, &address, sizeof (address));
12951
12952   S (mp);
12953   W (ret);
12954   return ret;
12955 }
12956
12957 static int
12958 api_ikev2_set_ike_transforms (vat_main_t * vam)
12959 {
12960   unformat_input_t *i = vam->input;
12961   vl_api_ikev2_set_ike_transforms_t *mp;
12962   int ret;
12963   u8 *name = 0;
12964   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
12965
12966   const char *valid_chars = "a-zA-Z0-9_";
12967
12968   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12969     {
12970       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
12971                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
12972         vec_add1 (name, 0);
12973       else
12974         {
12975           errmsg ("parse error '%U'", format_unformat_error, i);
12976           return -99;
12977         }
12978     }
12979
12980   if (!vec_len (name))
12981     {
12982       errmsg ("profile name must be specified");
12983       return -99;
12984     }
12985
12986   if (vec_len (name) > 64)
12987     {
12988       errmsg ("profile name too long");
12989       return -99;
12990     }
12991
12992   M (IKEV2_SET_IKE_TRANSFORMS, mp);
12993
12994   clib_memcpy (mp->name, name, vec_len (name));
12995   vec_free (name);
12996   mp->crypto_alg = crypto_alg;
12997   mp->crypto_key_size = crypto_key_size;
12998   mp->integ_alg = integ_alg;
12999   mp->dh_group = dh_group;
13000
13001   S (mp);
13002   W (ret);
13003   return ret;
13004 }
13005
13006
13007 static int
13008 api_ikev2_set_esp_transforms (vat_main_t * vam)
13009 {
13010   unformat_input_t *i = vam->input;
13011   vl_api_ikev2_set_esp_transforms_t *mp;
13012   int ret;
13013   u8 *name = 0;
13014   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
13015
13016   const char *valid_chars = "a-zA-Z0-9_";
13017
13018   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13019     {
13020       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
13021                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
13022         vec_add1 (name, 0);
13023       else
13024         {
13025           errmsg ("parse error '%U'", format_unformat_error, i);
13026           return -99;
13027         }
13028     }
13029
13030   if (!vec_len (name))
13031     {
13032       errmsg ("profile name must be specified");
13033       return -99;
13034     }
13035
13036   if (vec_len (name) > 64)
13037     {
13038       errmsg ("profile name too long");
13039       return -99;
13040     }
13041
13042   M (IKEV2_SET_ESP_TRANSFORMS, mp);
13043
13044   clib_memcpy (mp->name, name, vec_len (name));
13045   vec_free (name);
13046   mp->crypto_alg = crypto_alg;
13047   mp->crypto_key_size = crypto_key_size;
13048   mp->integ_alg = integ_alg;
13049   mp->dh_group = dh_group;
13050
13051   S (mp);
13052   W (ret);
13053   return ret;
13054 }
13055
13056 static int
13057 api_ikev2_set_sa_lifetime (vat_main_t * vam)
13058 {
13059   unformat_input_t *i = vam->input;
13060   vl_api_ikev2_set_sa_lifetime_t *mp;
13061   int ret;
13062   u8 *name = 0;
13063   u64 lifetime, lifetime_maxdata;
13064   u32 lifetime_jitter, handover;
13065
13066   const char *valid_chars = "a-zA-Z0-9_";
13067
13068   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13069     {
13070       if (unformat (i, "%U %lu %u %u %lu", unformat_token, valid_chars, &name,
13071                     &lifetime, &lifetime_jitter, &handover,
13072                     &lifetime_maxdata))
13073         vec_add1 (name, 0);
13074       else
13075         {
13076           errmsg ("parse error '%U'", format_unformat_error, i);
13077           return -99;
13078         }
13079     }
13080
13081   if (!vec_len (name))
13082     {
13083       errmsg ("profile name must be specified");
13084       return -99;
13085     }
13086
13087   if (vec_len (name) > 64)
13088     {
13089       errmsg ("profile name too long");
13090       return -99;
13091     }
13092
13093   M (IKEV2_SET_SA_LIFETIME, mp);
13094
13095   clib_memcpy (mp->name, name, vec_len (name));
13096   vec_free (name);
13097   mp->lifetime = lifetime;
13098   mp->lifetime_jitter = lifetime_jitter;
13099   mp->handover = handover;
13100   mp->lifetime_maxdata = lifetime_maxdata;
13101
13102   S (mp);
13103   W (ret);
13104   return ret;
13105 }
13106
13107 static int
13108 api_ikev2_initiate_sa_init (vat_main_t * vam)
13109 {
13110   unformat_input_t *i = vam->input;
13111   vl_api_ikev2_initiate_sa_init_t *mp;
13112   int ret;
13113   u8 *name = 0;
13114
13115   const char *valid_chars = "a-zA-Z0-9_";
13116
13117   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13118     {
13119       if (unformat (i, "%U", unformat_token, valid_chars, &name))
13120         vec_add1 (name, 0);
13121       else
13122         {
13123           errmsg ("parse error '%U'", format_unformat_error, i);
13124           return -99;
13125         }
13126     }
13127
13128   if (!vec_len (name))
13129     {
13130       errmsg ("profile name must be specified");
13131       return -99;
13132     }
13133
13134   if (vec_len (name) > 64)
13135     {
13136       errmsg ("profile name too long");
13137       return -99;
13138     }
13139
13140   M (IKEV2_INITIATE_SA_INIT, mp);
13141
13142   clib_memcpy (mp->name, name, vec_len (name));
13143   vec_free (name);
13144
13145   S (mp);
13146   W (ret);
13147   return ret;
13148 }
13149
13150 static int
13151 api_ikev2_initiate_del_ike_sa (vat_main_t * vam)
13152 {
13153   unformat_input_t *i = vam->input;
13154   vl_api_ikev2_initiate_del_ike_sa_t *mp;
13155   int ret;
13156   u64 ispi;
13157
13158
13159   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13160     {
13161       if (unformat (i, "%lx", &ispi))
13162         ;
13163       else
13164         {
13165           errmsg ("parse error '%U'", format_unformat_error, i);
13166           return -99;
13167         }
13168     }
13169
13170   M (IKEV2_INITIATE_DEL_IKE_SA, mp);
13171
13172   mp->ispi = ispi;
13173
13174   S (mp);
13175   W (ret);
13176   return ret;
13177 }
13178
13179 static int
13180 api_ikev2_initiate_del_child_sa (vat_main_t * vam)
13181 {
13182   unformat_input_t *i = vam->input;
13183   vl_api_ikev2_initiate_del_child_sa_t *mp;
13184   int ret;
13185   u32 ispi;
13186
13187
13188   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13189     {
13190       if (unformat (i, "%x", &ispi))
13191         ;
13192       else
13193         {
13194           errmsg ("parse error '%U'", format_unformat_error, i);
13195           return -99;
13196         }
13197     }
13198
13199   M (IKEV2_INITIATE_DEL_CHILD_SA, mp);
13200
13201   mp->ispi = ispi;
13202
13203   S (mp);
13204   W (ret);
13205   return ret;
13206 }
13207
13208 static int
13209 api_ikev2_initiate_rekey_child_sa (vat_main_t * vam)
13210 {
13211   unformat_input_t *i = vam->input;
13212   vl_api_ikev2_initiate_rekey_child_sa_t *mp;
13213   int ret;
13214   u32 ispi;
13215
13216
13217   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13218     {
13219       if (unformat (i, "%x", &ispi))
13220         ;
13221       else
13222         {
13223           errmsg ("parse error '%U'", format_unformat_error, i);
13224           return -99;
13225         }
13226     }
13227
13228   M (IKEV2_INITIATE_REKEY_CHILD_SA, mp);
13229
13230   mp->ispi = ispi;
13231
13232   S (mp);
13233   W (ret);
13234   return ret;
13235 }
13236
13237 /*
13238  * MAP
13239  */
13240 static int
13241 api_map_add_domain (vat_main_t * vam)
13242 {
13243   unformat_input_t *i = vam->input;
13244   vl_api_map_add_domain_t *mp;
13245
13246   ip4_address_t ip4_prefix;
13247   ip6_address_t ip6_prefix;
13248   ip6_address_t ip6_src;
13249   u32 num_m_args = 0;
13250   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
13251     0, psid_length = 0;
13252   u8 is_translation = 0;
13253   u32 mtu = 0;
13254   u32 ip6_src_len = 128;
13255   int ret;
13256
13257   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13258     {
13259       if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
13260                     &ip4_prefix, &ip4_prefix_len))
13261         num_m_args++;
13262       else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
13263                          &ip6_prefix, &ip6_prefix_len))
13264         num_m_args++;
13265       else
13266         if (unformat
13267             (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
13268              &ip6_src_len))
13269         num_m_args++;
13270       else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
13271         num_m_args++;
13272       else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
13273         num_m_args++;
13274       else if (unformat (i, "psid-offset %d", &psid_offset))
13275         num_m_args++;
13276       else if (unformat (i, "psid-len %d", &psid_length))
13277         num_m_args++;
13278       else if (unformat (i, "mtu %d", &mtu))
13279         num_m_args++;
13280       else if (unformat (i, "map-t"))
13281         is_translation = 1;
13282       else
13283         {
13284           clib_warning ("parse error '%U'", format_unformat_error, i);
13285           return -99;
13286         }
13287     }
13288
13289   if (num_m_args < 3)
13290     {
13291       errmsg ("mandatory argument(s) missing");
13292       return -99;
13293     }
13294
13295   /* Construct the API message */
13296   M (MAP_ADD_DOMAIN, mp);
13297
13298   clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
13299   mp->ip4_prefix_len = ip4_prefix_len;
13300
13301   clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
13302   mp->ip6_prefix_len = ip6_prefix_len;
13303
13304   clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
13305   mp->ip6_src_prefix_len = ip6_src_len;
13306
13307   mp->ea_bits_len = ea_bits_len;
13308   mp->psid_offset = psid_offset;
13309   mp->psid_length = psid_length;
13310   mp->is_translation = is_translation;
13311   mp->mtu = htons (mtu);
13312
13313   /* send it... */
13314   S (mp);
13315
13316   /* Wait for a reply, return good/bad news  */
13317   W (ret);
13318   return ret;
13319 }
13320
13321 static int
13322 api_map_del_domain (vat_main_t * vam)
13323 {
13324   unformat_input_t *i = vam->input;
13325   vl_api_map_del_domain_t *mp;
13326
13327   u32 num_m_args = 0;
13328   u32 index;
13329   int ret;
13330
13331   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13332     {
13333       if (unformat (i, "index %d", &index))
13334         num_m_args++;
13335       else
13336         {
13337           clib_warning ("parse error '%U'", format_unformat_error, i);
13338           return -99;
13339         }
13340     }
13341
13342   if (num_m_args != 1)
13343     {
13344       errmsg ("mandatory argument(s) missing");
13345       return -99;
13346     }
13347
13348   /* Construct the API message */
13349   M (MAP_DEL_DOMAIN, mp);
13350
13351   mp->index = ntohl (index);
13352
13353   /* send it... */
13354   S (mp);
13355
13356   /* Wait for a reply, return good/bad news  */
13357   W (ret);
13358   return ret;
13359 }
13360
13361 static int
13362 api_map_add_del_rule (vat_main_t * vam)
13363 {
13364   unformat_input_t *i = vam->input;
13365   vl_api_map_add_del_rule_t *mp;
13366   u8 is_add = 1;
13367   ip6_address_t ip6_dst;
13368   u32 num_m_args = 0, index, psid = 0;
13369   int ret;
13370
13371   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13372     {
13373       if (unformat (i, "index %d", &index))
13374         num_m_args++;
13375       else if (unformat (i, "psid %d", &psid))
13376         num_m_args++;
13377       else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
13378         num_m_args++;
13379       else if (unformat (i, "del"))
13380         {
13381           is_add = 0;
13382         }
13383       else
13384         {
13385           clib_warning ("parse error '%U'", format_unformat_error, i);
13386           return -99;
13387         }
13388     }
13389
13390   /* Construct the API message */
13391   M (MAP_ADD_DEL_RULE, mp);
13392
13393   mp->index = ntohl (index);
13394   mp->is_add = is_add;
13395   clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
13396   mp->psid = ntohs (psid);
13397
13398   /* send it... */
13399   S (mp);
13400
13401   /* Wait for a reply, return good/bad news  */
13402   W (ret);
13403   return ret;
13404 }
13405
13406 static int
13407 api_map_domain_dump (vat_main_t * vam)
13408 {
13409   vl_api_map_domain_dump_t *mp;
13410   vl_api_control_ping_t *mp_ping;
13411   int ret;
13412
13413   /* Construct the API message */
13414   M (MAP_DOMAIN_DUMP, mp);
13415
13416   /* send it... */
13417   S (mp);
13418
13419   /* Use a control ping for synchronization */
13420   M (CONTROL_PING, mp_ping);
13421   S (mp_ping);
13422
13423   W (ret);
13424   return ret;
13425 }
13426
13427 static int
13428 api_map_rule_dump (vat_main_t * vam)
13429 {
13430   unformat_input_t *i = vam->input;
13431   vl_api_map_rule_dump_t *mp;
13432   vl_api_control_ping_t *mp_ping;
13433   u32 domain_index = ~0;
13434   int ret;
13435
13436   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13437     {
13438       if (unformat (i, "index %u", &domain_index))
13439         ;
13440       else
13441         break;
13442     }
13443
13444   if (domain_index == ~0)
13445     {
13446       clib_warning ("parse error: domain index expected");
13447       return -99;
13448     }
13449
13450   /* Construct the API message */
13451   M (MAP_RULE_DUMP, mp);
13452
13453   mp->domain_index = htonl (domain_index);
13454
13455   /* send it... */
13456   S (mp);
13457
13458   /* Use a control ping for synchronization */
13459   M (CONTROL_PING, mp_ping);
13460   S (mp_ping);
13461
13462   W (ret);
13463   return ret;
13464 }
13465
13466 static void vl_api_map_add_domain_reply_t_handler
13467   (vl_api_map_add_domain_reply_t * mp)
13468 {
13469   vat_main_t *vam = &vat_main;
13470   i32 retval = ntohl (mp->retval);
13471
13472   if (vam->async_mode)
13473     {
13474       vam->async_errors += (retval < 0);
13475     }
13476   else
13477     {
13478       vam->retval = retval;
13479       vam->result_ready = 1;
13480     }
13481 }
13482
13483 static void vl_api_map_add_domain_reply_t_handler_json
13484   (vl_api_map_add_domain_reply_t * mp)
13485 {
13486   vat_main_t *vam = &vat_main;
13487   vat_json_node_t node;
13488
13489   vat_json_init_object (&node);
13490   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
13491   vat_json_object_add_uint (&node, "index", ntohl (mp->index));
13492
13493   vat_json_print (vam->ofp, &node);
13494   vat_json_free (&node);
13495
13496   vam->retval = ntohl (mp->retval);
13497   vam->result_ready = 1;
13498 }
13499
13500 static int
13501 api_get_first_msg_id (vat_main_t * vam)
13502 {
13503   vl_api_get_first_msg_id_t *mp;
13504   unformat_input_t *i = vam->input;
13505   u8 *name;
13506   u8 name_set = 0;
13507   int ret;
13508
13509   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13510     {
13511       if (unformat (i, "client %s", &name))
13512         name_set = 1;
13513       else
13514         break;
13515     }
13516
13517   if (name_set == 0)
13518     {
13519       errmsg ("missing client name");
13520       return -99;
13521     }
13522   vec_add1 (name, 0);
13523
13524   if (vec_len (name) > 63)
13525     {
13526       errmsg ("client name too long");
13527       return -99;
13528     }
13529
13530   M (GET_FIRST_MSG_ID, mp);
13531   clib_memcpy (mp->name, name, vec_len (name));
13532   S (mp);
13533   W (ret);
13534   return ret;
13535 }
13536
13537 static int
13538 api_cop_interface_enable_disable (vat_main_t * vam)
13539 {
13540   unformat_input_t *line_input = vam->input;
13541   vl_api_cop_interface_enable_disable_t *mp;
13542   u32 sw_if_index = ~0;
13543   u8 enable_disable = 1;
13544   int ret;
13545
13546   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13547     {
13548       if (unformat (line_input, "disable"))
13549         enable_disable = 0;
13550       if (unformat (line_input, "enable"))
13551         enable_disable = 1;
13552       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
13553                          vam, &sw_if_index))
13554         ;
13555       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13556         ;
13557       else
13558         break;
13559     }
13560
13561   if (sw_if_index == ~0)
13562     {
13563       errmsg ("missing interface name or sw_if_index");
13564       return -99;
13565     }
13566
13567   /* Construct the API message */
13568   M (COP_INTERFACE_ENABLE_DISABLE, mp);
13569   mp->sw_if_index = ntohl (sw_if_index);
13570   mp->enable_disable = enable_disable;
13571
13572   /* send it... */
13573   S (mp);
13574   /* Wait for the reply */
13575   W (ret);
13576   return ret;
13577 }
13578
13579 static int
13580 api_cop_whitelist_enable_disable (vat_main_t * vam)
13581 {
13582   unformat_input_t *line_input = vam->input;
13583   vl_api_cop_whitelist_enable_disable_t *mp;
13584   u32 sw_if_index = ~0;
13585   u8 ip4 = 0, ip6 = 0, default_cop = 0;
13586   u32 fib_id = 0;
13587   int ret;
13588
13589   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13590     {
13591       if (unformat (line_input, "ip4"))
13592         ip4 = 1;
13593       else if (unformat (line_input, "ip6"))
13594         ip6 = 1;
13595       else if (unformat (line_input, "default"))
13596         default_cop = 1;
13597       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
13598                          vam, &sw_if_index))
13599         ;
13600       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13601         ;
13602       else if (unformat (line_input, "fib-id %d", &fib_id))
13603         ;
13604       else
13605         break;
13606     }
13607
13608   if (sw_if_index == ~0)
13609     {
13610       errmsg ("missing interface name or sw_if_index");
13611       return -99;
13612     }
13613
13614   /* Construct the API message */
13615   M (COP_WHITELIST_ENABLE_DISABLE, mp);
13616   mp->sw_if_index = ntohl (sw_if_index);
13617   mp->fib_id = ntohl (fib_id);
13618   mp->ip4 = ip4;
13619   mp->ip6 = ip6;
13620   mp->default_cop = default_cop;
13621
13622   /* send it... */
13623   S (mp);
13624   /* Wait for the reply */
13625   W (ret);
13626   return ret;
13627 }
13628
13629 static int
13630 api_get_node_graph (vat_main_t * vam)
13631 {
13632   vl_api_get_node_graph_t *mp;
13633   int ret;
13634
13635   M (GET_NODE_GRAPH, mp);
13636
13637   /* send it... */
13638   S (mp);
13639   /* Wait for the reply */
13640   W (ret);
13641   return ret;
13642 }
13643
13644 /* *INDENT-OFF* */
13645 /** Used for parsing LISP eids */
13646 typedef CLIB_PACKED(struct{
13647   u8 addr[16];   /**< eid address */
13648   u32 len;       /**< prefix length if IP */
13649   u8 type;      /**< type of eid */
13650 }) lisp_eid_vat_t;
13651 /* *INDENT-ON* */
13652
13653 static uword
13654 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
13655 {
13656   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
13657
13658   memset (a, 0, sizeof (a[0]));
13659
13660   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
13661     {
13662       a->type = 0;              /* ipv4 type */
13663     }
13664   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
13665     {
13666       a->type = 1;              /* ipv6 type */
13667     }
13668   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
13669     {
13670       a->type = 2;              /* mac type */
13671     }
13672   else
13673     {
13674       return 0;
13675     }
13676
13677   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
13678     {
13679       return 0;
13680     }
13681
13682   return 1;
13683 }
13684
13685 static int
13686 lisp_eid_size_vat (u8 type)
13687 {
13688   switch (type)
13689     {
13690     case 0:
13691       return 4;
13692     case 1:
13693       return 16;
13694     case 2:
13695       return 6;
13696     }
13697   return 0;
13698 }
13699
13700 static void
13701 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
13702 {
13703   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
13704 }
13705
13706 static int
13707 api_one_add_del_locator_set (vat_main_t * vam)
13708 {
13709   unformat_input_t *input = vam->input;
13710   vl_api_one_add_del_locator_set_t *mp;
13711   u8 is_add = 1;
13712   u8 *locator_set_name = NULL;
13713   u8 locator_set_name_set = 0;
13714   vl_api_local_locator_t locator, *locators = 0;
13715   u32 sw_if_index, priority, weight;
13716   u32 data_len = 0;
13717
13718   int ret;
13719   /* Parse args required to build the message */
13720   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13721     {
13722       if (unformat (input, "del"))
13723         {
13724           is_add = 0;
13725         }
13726       else if (unformat (input, "locator-set %s", &locator_set_name))
13727         {
13728           locator_set_name_set = 1;
13729         }
13730       else if (unformat (input, "sw_if_index %u p %u w %u",
13731                          &sw_if_index, &priority, &weight))
13732         {
13733           locator.sw_if_index = htonl (sw_if_index);
13734           locator.priority = priority;
13735           locator.weight = weight;
13736           vec_add1 (locators, locator);
13737         }
13738       else
13739         if (unformat
13740             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
13741              &sw_if_index, &priority, &weight))
13742         {
13743           locator.sw_if_index = htonl (sw_if_index);
13744           locator.priority = priority;
13745           locator.weight = weight;
13746           vec_add1 (locators, locator);
13747         }
13748       else
13749         break;
13750     }
13751
13752   if (locator_set_name_set == 0)
13753     {
13754       errmsg ("missing locator-set name");
13755       vec_free (locators);
13756       return -99;
13757     }
13758
13759   if (vec_len (locator_set_name) > 64)
13760     {
13761       errmsg ("locator-set name too long");
13762       vec_free (locator_set_name);
13763       vec_free (locators);
13764       return -99;
13765     }
13766   vec_add1 (locator_set_name, 0);
13767
13768   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
13769
13770   /* Construct the API message */
13771   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
13772
13773   mp->is_add = is_add;
13774   clib_memcpy (mp->locator_set_name, locator_set_name,
13775                vec_len (locator_set_name));
13776   vec_free (locator_set_name);
13777
13778   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
13779   if (locators)
13780     clib_memcpy (mp->locators, locators, data_len);
13781   vec_free (locators);
13782
13783   /* send it... */
13784   S (mp);
13785
13786   /* Wait for a reply... */
13787   W (ret);
13788   return ret;
13789 }
13790
13791 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
13792
13793 static int
13794 api_one_add_del_locator (vat_main_t * vam)
13795 {
13796   unformat_input_t *input = vam->input;
13797   vl_api_one_add_del_locator_t *mp;
13798   u32 tmp_if_index = ~0;
13799   u32 sw_if_index = ~0;
13800   u8 sw_if_index_set = 0;
13801   u8 sw_if_index_if_name_set = 0;
13802   u32 priority = ~0;
13803   u8 priority_set = 0;
13804   u32 weight = ~0;
13805   u8 weight_set = 0;
13806   u8 is_add = 1;
13807   u8 *locator_set_name = NULL;
13808   u8 locator_set_name_set = 0;
13809   int ret;
13810
13811   /* Parse args required to build the message */
13812   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13813     {
13814       if (unformat (input, "del"))
13815         {
13816           is_add = 0;
13817         }
13818       else if (unformat (input, "locator-set %s", &locator_set_name))
13819         {
13820           locator_set_name_set = 1;
13821         }
13822       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
13823                          &tmp_if_index))
13824         {
13825           sw_if_index_if_name_set = 1;
13826           sw_if_index = tmp_if_index;
13827         }
13828       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
13829         {
13830           sw_if_index_set = 1;
13831           sw_if_index = tmp_if_index;
13832         }
13833       else if (unformat (input, "p %d", &priority))
13834         {
13835           priority_set = 1;
13836         }
13837       else if (unformat (input, "w %d", &weight))
13838         {
13839           weight_set = 1;
13840         }
13841       else
13842         break;
13843     }
13844
13845   if (locator_set_name_set == 0)
13846     {
13847       errmsg ("missing locator-set name");
13848       return -99;
13849     }
13850
13851   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
13852     {
13853       errmsg ("missing sw_if_index");
13854       vec_free (locator_set_name);
13855       return -99;
13856     }
13857
13858   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
13859     {
13860       errmsg ("cannot use both params interface name and sw_if_index");
13861       vec_free (locator_set_name);
13862       return -99;
13863     }
13864
13865   if (priority_set == 0)
13866     {
13867       errmsg ("missing locator-set priority");
13868       vec_free (locator_set_name);
13869       return -99;
13870     }
13871
13872   if (weight_set == 0)
13873     {
13874       errmsg ("missing locator-set weight");
13875       vec_free (locator_set_name);
13876       return -99;
13877     }
13878
13879   if (vec_len (locator_set_name) > 64)
13880     {
13881       errmsg ("locator-set name too long");
13882       vec_free (locator_set_name);
13883       return -99;
13884     }
13885   vec_add1 (locator_set_name, 0);
13886
13887   /* Construct the API message */
13888   M (ONE_ADD_DEL_LOCATOR, mp);
13889
13890   mp->is_add = is_add;
13891   mp->sw_if_index = ntohl (sw_if_index);
13892   mp->priority = priority;
13893   mp->weight = weight;
13894   clib_memcpy (mp->locator_set_name, locator_set_name,
13895                vec_len (locator_set_name));
13896   vec_free (locator_set_name);
13897
13898   /* send it... */
13899   S (mp);
13900
13901   /* Wait for a reply... */
13902   W (ret);
13903   return ret;
13904 }
13905
13906 #define api_lisp_add_del_locator api_one_add_del_locator
13907
13908 uword
13909 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
13910 {
13911   u32 *key_id = va_arg (*args, u32 *);
13912   u8 *s = 0;
13913
13914   if (unformat (input, "%s", &s))
13915     {
13916       if (!strcmp ((char *) s, "sha1"))
13917         key_id[0] = HMAC_SHA_1_96;
13918       else if (!strcmp ((char *) s, "sha256"))
13919         key_id[0] = HMAC_SHA_256_128;
13920       else
13921         {
13922           clib_warning ("invalid key_id: '%s'", s);
13923           key_id[0] = HMAC_NO_KEY;
13924         }
13925     }
13926   else
13927     return 0;
13928
13929   vec_free (s);
13930   return 1;
13931 }
13932
13933 static int
13934 api_one_add_del_local_eid (vat_main_t * vam)
13935 {
13936   unformat_input_t *input = vam->input;
13937   vl_api_one_add_del_local_eid_t *mp;
13938   u8 is_add = 1;
13939   u8 eid_set = 0;
13940   lisp_eid_vat_t _eid, *eid = &_eid;
13941   u8 *locator_set_name = 0;
13942   u8 locator_set_name_set = 0;
13943   u32 vni = 0;
13944   u16 key_id = 0;
13945   u8 *key = 0;
13946   int ret;
13947
13948   /* Parse args required to build the message */
13949   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13950     {
13951       if (unformat (input, "del"))
13952         {
13953           is_add = 0;
13954         }
13955       else if (unformat (input, "vni %d", &vni))
13956         {
13957           ;
13958         }
13959       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
13960         {
13961           eid_set = 1;
13962         }
13963       else if (unformat (input, "locator-set %s", &locator_set_name))
13964         {
13965           locator_set_name_set = 1;
13966         }
13967       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
13968         ;
13969       else if (unformat (input, "secret-key %_%v%_", &key))
13970         ;
13971       else
13972         break;
13973     }
13974
13975   if (locator_set_name_set == 0)
13976     {
13977       errmsg ("missing locator-set name");
13978       return -99;
13979     }
13980
13981   if (0 == eid_set)
13982     {
13983       errmsg ("EID address not set!");
13984       vec_free (locator_set_name);
13985       return -99;
13986     }
13987
13988   if (key && (0 == key_id))
13989     {
13990       errmsg ("invalid key_id!");
13991       return -99;
13992     }
13993
13994   if (vec_len (key) > 64)
13995     {
13996       errmsg ("key too long");
13997       vec_free (key);
13998       return -99;
13999     }
14000
14001   if (vec_len (locator_set_name) > 64)
14002     {
14003       errmsg ("locator-set name too long");
14004       vec_free (locator_set_name);
14005       return -99;
14006     }
14007   vec_add1 (locator_set_name, 0);
14008
14009   /* Construct the API message */
14010   M (ONE_ADD_DEL_LOCAL_EID, mp);
14011
14012   mp->is_add = is_add;
14013   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
14014   mp->eid_type = eid->type;
14015   mp->prefix_len = eid->len;
14016   mp->vni = clib_host_to_net_u32 (vni);
14017   mp->key_id = clib_host_to_net_u16 (key_id);
14018   clib_memcpy (mp->locator_set_name, locator_set_name,
14019                vec_len (locator_set_name));
14020   clib_memcpy (mp->key, key, vec_len (key));
14021
14022   vec_free (locator_set_name);
14023   vec_free (key);
14024
14025   /* send it... */
14026   S (mp);
14027
14028   /* Wait for a reply... */
14029   W (ret);
14030   return ret;
14031 }
14032
14033 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
14034
14035 static int
14036 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
14037 {
14038   u32 dp_table = 0, vni = 0;;
14039   unformat_input_t *input = vam->input;
14040   vl_api_gpe_add_del_fwd_entry_t *mp;
14041   u8 is_add = 1;
14042   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
14043   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
14044   u8 rmt_eid_set = 0, lcl_eid_set = 0;
14045   u32 action = ~0, w;
14046   ip4_address_t rmt_rloc4, lcl_rloc4;
14047   ip6_address_t rmt_rloc6, lcl_rloc6;
14048   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
14049   int ret;
14050
14051   memset (&rloc, 0, sizeof (rloc));
14052
14053   /* Parse args required to build the message */
14054   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14055     {
14056       if (unformat (input, "del"))
14057         is_add = 0;
14058       else if (unformat (input, "add"))
14059         is_add = 1;
14060       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
14061         {
14062           rmt_eid_set = 1;
14063         }
14064       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
14065         {
14066           lcl_eid_set = 1;
14067         }
14068       else if (unformat (input, "vrf %d", &dp_table))
14069         ;
14070       else if (unformat (input, "bd %d", &dp_table))
14071         ;
14072       else if (unformat (input, "vni %d", &vni))
14073         ;
14074       else if (unformat (input, "w %d", &w))
14075         {
14076           if (!curr_rloc)
14077             {
14078               errmsg ("No RLOC configured for setting priority/weight!");
14079               return -99;
14080             }
14081           curr_rloc->weight = w;
14082         }
14083       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
14084                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
14085         {
14086           rloc.is_ip4 = 1;
14087
14088           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
14089           rloc.weight = 0;
14090           vec_add1 (lcl_locs, rloc);
14091
14092           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
14093           vec_add1 (rmt_locs, rloc);
14094           /* weight saved in rmt loc */
14095           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
14096         }
14097       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
14098                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
14099         {
14100           rloc.is_ip4 = 0;
14101           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
14102           rloc.weight = 0;
14103           vec_add1 (lcl_locs, rloc);
14104
14105           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
14106           vec_add1 (rmt_locs, rloc);
14107           /* weight saved in rmt loc */
14108           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
14109         }
14110       else if (unformat (input, "action %d", &action))
14111         {
14112           ;
14113         }
14114       else
14115         {
14116           clib_warning ("parse error '%U'", format_unformat_error, input);
14117           return -99;
14118         }
14119     }
14120
14121   if (!rmt_eid_set)
14122     {
14123       errmsg ("remote eid addresses not set");
14124       return -99;
14125     }
14126
14127   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
14128     {
14129       errmsg ("eid types don't match");
14130       return -99;
14131     }
14132
14133   if (0 == rmt_locs && (u32) ~ 0 == action)
14134     {
14135       errmsg ("action not set for negative mapping");
14136       return -99;
14137     }
14138
14139   /* Construct the API message */
14140   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
14141       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
14142
14143   mp->is_add = is_add;
14144   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
14145   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
14146   mp->eid_type = rmt_eid->type;
14147   mp->dp_table = clib_host_to_net_u32 (dp_table);
14148   mp->vni = clib_host_to_net_u32 (vni);
14149   mp->rmt_len = rmt_eid->len;
14150   mp->lcl_len = lcl_eid->len;
14151   mp->action = action;
14152
14153   if (0 != rmt_locs && 0 != lcl_locs)
14154     {
14155       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
14156       clib_memcpy (mp->locs, lcl_locs,
14157                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
14158
14159       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
14160       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
14161                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
14162     }
14163   vec_free (lcl_locs);
14164   vec_free (rmt_locs);
14165
14166   /* send it... */
14167   S (mp);
14168
14169   /* Wait for a reply... */
14170   W (ret);
14171   return ret;
14172 }
14173
14174 static int
14175 api_one_add_del_map_server (vat_main_t * vam)
14176 {
14177   unformat_input_t *input = vam->input;
14178   vl_api_one_add_del_map_server_t *mp;
14179   u8 is_add = 1;
14180   u8 ipv4_set = 0;
14181   u8 ipv6_set = 0;
14182   ip4_address_t ipv4;
14183   ip6_address_t ipv6;
14184   int ret;
14185
14186   /* Parse args required to build the message */
14187   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14188     {
14189       if (unformat (input, "del"))
14190         {
14191           is_add = 0;
14192         }
14193       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
14194         {
14195           ipv4_set = 1;
14196         }
14197       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
14198         {
14199           ipv6_set = 1;
14200         }
14201       else
14202         break;
14203     }
14204
14205   if (ipv4_set && ipv6_set)
14206     {
14207       errmsg ("both eid v4 and v6 addresses set");
14208       return -99;
14209     }
14210
14211   if (!ipv4_set && !ipv6_set)
14212     {
14213       errmsg ("eid addresses not set");
14214       return -99;
14215     }
14216
14217   /* Construct the API message */
14218   M (ONE_ADD_DEL_MAP_SERVER, mp);
14219
14220   mp->is_add = is_add;
14221   if (ipv6_set)
14222     {
14223       mp->is_ipv6 = 1;
14224       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
14225     }
14226   else
14227     {
14228       mp->is_ipv6 = 0;
14229       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
14230     }
14231
14232   /* send it... */
14233   S (mp);
14234
14235   /* Wait for a reply... */
14236   W (ret);
14237   return ret;
14238 }
14239
14240 #define api_lisp_add_del_map_server api_one_add_del_map_server
14241
14242 static int
14243 api_one_add_del_map_resolver (vat_main_t * vam)
14244 {
14245   unformat_input_t *input = vam->input;
14246   vl_api_one_add_del_map_resolver_t *mp;
14247   u8 is_add = 1;
14248   u8 ipv4_set = 0;
14249   u8 ipv6_set = 0;
14250   ip4_address_t ipv4;
14251   ip6_address_t ipv6;
14252   int ret;
14253
14254   /* Parse args required to build the message */
14255   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14256     {
14257       if (unformat (input, "del"))
14258         {
14259           is_add = 0;
14260         }
14261       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
14262         {
14263           ipv4_set = 1;
14264         }
14265       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
14266         {
14267           ipv6_set = 1;
14268         }
14269       else
14270         break;
14271     }
14272
14273   if (ipv4_set && ipv6_set)
14274     {
14275       errmsg ("both eid v4 and v6 addresses set");
14276       return -99;
14277     }
14278
14279   if (!ipv4_set && !ipv6_set)
14280     {
14281       errmsg ("eid addresses not set");
14282       return -99;
14283     }
14284
14285   /* Construct the API message */
14286   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
14287
14288   mp->is_add = is_add;
14289   if (ipv6_set)
14290     {
14291       mp->is_ipv6 = 1;
14292       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
14293     }
14294   else
14295     {
14296       mp->is_ipv6 = 0;
14297       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
14298     }
14299
14300   /* send it... */
14301   S (mp);
14302
14303   /* Wait for a reply... */
14304   W (ret);
14305   return ret;
14306 }
14307
14308 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
14309
14310 static int
14311 api_lisp_gpe_enable_disable (vat_main_t * vam)
14312 {
14313   unformat_input_t *input = vam->input;
14314   vl_api_gpe_enable_disable_t *mp;
14315   u8 is_set = 0;
14316   u8 is_en = 1;
14317   int ret;
14318
14319   /* Parse args required to build the message */
14320   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14321     {
14322       if (unformat (input, "enable"))
14323         {
14324           is_set = 1;
14325           is_en = 1;
14326         }
14327       else if (unformat (input, "disable"))
14328         {
14329           is_set = 1;
14330           is_en = 0;
14331         }
14332       else
14333         break;
14334     }
14335
14336   if (is_set == 0)
14337     {
14338       errmsg ("Value not set");
14339       return -99;
14340     }
14341
14342   /* Construct the API message */
14343   M (GPE_ENABLE_DISABLE, mp);
14344
14345   mp->is_en = is_en;
14346
14347   /* send it... */
14348   S (mp);
14349
14350   /* Wait for a reply... */
14351   W (ret);
14352   return ret;
14353 }
14354
14355 static int
14356 api_one_rloc_probe_enable_disable (vat_main_t * vam)
14357 {
14358   unformat_input_t *input = vam->input;
14359   vl_api_one_rloc_probe_enable_disable_t *mp;
14360   u8 is_set = 0;
14361   u8 is_en = 0;
14362   int ret;
14363
14364   /* Parse args required to build the message */
14365   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14366     {
14367       if (unformat (input, "enable"))
14368         {
14369           is_set = 1;
14370           is_en = 1;
14371         }
14372       else if (unformat (input, "disable"))
14373         is_set = 1;
14374       else
14375         break;
14376     }
14377
14378   if (!is_set)
14379     {
14380       errmsg ("Value not set");
14381       return -99;
14382     }
14383
14384   /* Construct the API message */
14385   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
14386
14387   mp->is_enabled = is_en;
14388
14389   /* send it... */
14390   S (mp);
14391
14392   /* Wait for a reply... */
14393   W (ret);
14394   return ret;
14395 }
14396
14397 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
14398
14399 static int
14400 api_one_map_register_enable_disable (vat_main_t * vam)
14401 {
14402   unformat_input_t *input = vam->input;
14403   vl_api_one_map_register_enable_disable_t *mp;
14404   u8 is_set = 0;
14405   u8 is_en = 0;
14406   int ret;
14407
14408   /* Parse args required to build the message */
14409   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14410     {
14411       if (unformat (input, "enable"))
14412         {
14413           is_set = 1;
14414           is_en = 1;
14415         }
14416       else if (unformat (input, "disable"))
14417         is_set = 1;
14418       else
14419         break;
14420     }
14421
14422   if (!is_set)
14423     {
14424       errmsg ("Value not set");
14425       return -99;
14426     }
14427
14428   /* Construct the API message */
14429   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
14430
14431   mp->is_enabled = is_en;
14432
14433   /* send it... */
14434   S (mp);
14435
14436   /* Wait for a reply... */
14437   W (ret);
14438   return ret;
14439 }
14440
14441 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
14442
14443 static int
14444 api_one_enable_disable (vat_main_t * vam)
14445 {
14446   unformat_input_t *input = vam->input;
14447   vl_api_one_enable_disable_t *mp;
14448   u8 is_set = 0;
14449   u8 is_en = 0;
14450   int ret;
14451
14452   /* Parse args required to build the message */
14453   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14454     {
14455       if (unformat (input, "enable"))
14456         {
14457           is_set = 1;
14458           is_en = 1;
14459         }
14460       else if (unformat (input, "disable"))
14461         {
14462           is_set = 1;
14463         }
14464       else
14465         break;
14466     }
14467
14468   if (!is_set)
14469     {
14470       errmsg ("Value not set");
14471       return -99;
14472     }
14473
14474   /* Construct the API message */
14475   M (ONE_ENABLE_DISABLE, mp);
14476
14477   mp->is_en = is_en;
14478
14479   /* send it... */
14480   S (mp);
14481
14482   /* Wait for a reply... */
14483   W (ret);
14484   return ret;
14485 }
14486
14487 #define api_lisp_enable_disable api_one_enable_disable
14488
14489 static int
14490 api_show_one_map_register_state (vat_main_t * vam)
14491 {
14492   vl_api_show_one_map_register_state_t *mp;
14493   int ret;
14494
14495   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
14496
14497   /* send */
14498   S (mp);
14499
14500   /* wait for reply */
14501   W (ret);
14502   return ret;
14503 }
14504
14505 #define api_show_lisp_map_register_state api_show_one_map_register_state
14506
14507 static int
14508 api_show_one_rloc_probe_state (vat_main_t * vam)
14509 {
14510   vl_api_show_one_rloc_probe_state_t *mp;
14511   int ret;
14512
14513   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
14514
14515   /* send */
14516   S (mp);
14517
14518   /* wait for reply */
14519   W (ret);
14520   return ret;
14521 }
14522
14523 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
14524
14525 static int
14526 api_one_stats_enable_disable (vat_main_t * vam)
14527 {
14528   vl_api_one_stats_enable_disable_t *mp;
14529   unformat_input_t *input = vam->input;
14530   u8 is_set = 0;
14531   u8 is_en = 0;
14532   int ret;
14533
14534   /* Parse args required to build the message */
14535   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14536     {
14537       if (unformat (input, "enable"))
14538         {
14539           is_set = 1;
14540           is_en = 1;
14541         }
14542       else if (unformat (input, "disable"))
14543         {
14544           is_set = 1;
14545         }
14546       else
14547         break;
14548     }
14549
14550   if (!is_set)
14551     {
14552       errmsg ("Value not set");
14553       return -99;
14554     }
14555
14556   M (ONE_STATS_ENABLE_DISABLE, mp);
14557   mp->is_en = is_en;
14558
14559   /* send */
14560   S (mp);
14561
14562   /* wait for reply */
14563   W (ret);
14564   return ret;
14565 }
14566
14567 static int
14568 api_show_one_stats_enable_disable (vat_main_t * vam)
14569 {
14570   vl_api_show_one_stats_enable_disable_t *mp;
14571   int ret;
14572
14573   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
14574
14575   /* send */
14576   S (mp);
14577
14578   /* wait for reply */
14579   W (ret);
14580   return ret;
14581 }
14582
14583 static int
14584 api_show_one_map_request_mode (vat_main_t * vam)
14585 {
14586   vl_api_show_one_map_request_mode_t *mp;
14587   int ret;
14588
14589   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
14590
14591   /* send */
14592   S (mp);
14593
14594   /* wait for reply */
14595   W (ret);
14596   return ret;
14597 }
14598
14599 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
14600
14601 static int
14602 api_one_map_request_mode (vat_main_t * vam)
14603 {
14604   unformat_input_t *input = vam->input;
14605   vl_api_one_map_request_mode_t *mp;
14606   u8 mode = 0;
14607   int ret;
14608
14609   /* Parse args required to build the message */
14610   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14611     {
14612       if (unformat (input, "dst-only"))
14613         mode = 0;
14614       else if (unformat (input, "src-dst"))
14615         mode = 1;
14616       else
14617         {
14618           errmsg ("parse error '%U'", format_unformat_error, input);
14619           return -99;
14620         }
14621     }
14622
14623   M (ONE_MAP_REQUEST_MODE, mp);
14624
14625   mp->mode = mode;
14626
14627   /* send */
14628   S (mp);
14629
14630   /* wait for reply */
14631   W (ret);
14632   return ret;
14633 }
14634
14635 #define api_lisp_map_request_mode api_one_map_request_mode
14636
14637 /**
14638  * Enable/disable ONE proxy ITR.
14639  *
14640  * @param vam vpp API test context
14641  * @return return code
14642  */
14643 static int
14644 api_one_pitr_set_locator_set (vat_main_t * vam)
14645 {
14646   u8 ls_name_set = 0;
14647   unformat_input_t *input = vam->input;
14648   vl_api_one_pitr_set_locator_set_t *mp;
14649   u8 is_add = 1;
14650   u8 *ls_name = 0;
14651   int ret;
14652
14653   /* Parse args required to build the message */
14654   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14655     {
14656       if (unformat (input, "del"))
14657         is_add = 0;
14658       else if (unformat (input, "locator-set %s", &ls_name))
14659         ls_name_set = 1;
14660       else
14661         {
14662           errmsg ("parse error '%U'", format_unformat_error, input);
14663           return -99;
14664         }
14665     }
14666
14667   if (!ls_name_set)
14668     {
14669       errmsg ("locator-set name not set!");
14670       return -99;
14671     }
14672
14673   M (ONE_PITR_SET_LOCATOR_SET, mp);
14674
14675   mp->is_add = is_add;
14676   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
14677   vec_free (ls_name);
14678
14679   /* send */
14680   S (mp);
14681
14682   /* wait for reply */
14683   W (ret);
14684   return ret;
14685 }
14686
14687 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
14688
14689 static int
14690 api_show_one_pitr (vat_main_t * vam)
14691 {
14692   vl_api_show_one_pitr_t *mp;
14693   int ret;
14694
14695   if (!vam->json_output)
14696     {
14697       print (vam->ofp, "%=20s", "lisp status:");
14698     }
14699
14700   M (SHOW_ONE_PITR, mp);
14701   /* send it... */
14702   S (mp);
14703
14704   /* Wait for a reply... */
14705   W (ret);
14706   return ret;
14707 }
14708
14709 #define api_show_lisp_pitr api_show_one_pitr
14710
14711 static int
14712 api_one_use_petr (vat_main_t * vam)
14713 {
14714   unformat_input_t *input = vam->input;
14715   vl_api_one_use_petr_t *mp;
14716   u8 is_add = 0;
14717   ip_address_t ip;
14718   int ret;
14719
14720   memset (&ip, 0, sizeof (ip));
14721
14722   /* Parse args required to build the message */
14723   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14724     {
14725       if (unformat (input, "disable"))
14726         is_add = 0;
14727       else
14728         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
14729         {
14730           is_add = 1;
14731           ip_addr_version (&ip) = IP4;
14732         }
14733       else
14734         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
14735         {
14736           is_add = 1;
14737           ip_addr_version (&ip) = IP6;
14738         }
14739       else
14740         {
14741           errmsg ("parse error '%U'", format_unformat_error, input);
14742           return -99;
14743         }
14744     }
14745
14746   M (ONE_USE_PETR, mp);
14747
14748   mp->is_add = is_add;
14749   if (is_add)
14750     {
14751       mp->is_ip4 = ip_addr_version (&ip) == IP4 ? 1 : 0;
14752       if (mp->is_ip4)
14753         clib_memcpy (mp->address, &ip, 4);
14754       else
14755         clib_memcpy (mp->address, &ip, 16);
14756     }
14757
14758   /* send */
14759   S (mp);
14760
14761   /* wait for reply */
14762   W (ret);
14763   return ret;
14764 }
14765
14766 #define api_lisp_use_petr api_one_use_petr
14767
14768 static int
14769 api_show_one_use_petr (vat_main_t * vam)
14770 {
14771   vl_api_show_one_use_petr_t *mp;
14772   int ret;
14773
14774   if (!vam->json_output)
14775     {
14776       print (vam->ofp, "%=20s", "Proxy-ETR status:");
14777     }
14778
14779   M (SHOW_ONE_USE_PETR, mp);
14780   /* send it... */
14781   S (mp);
14782
14783   /* Wait for a reply... */
14784   W (ret);
14785   return ret;
14786 }
14787
14788 #define api_show_lisp_use_petr api_show_one_use_petr
14789
14790 /**
14791  * Add/delete mapping between vni and vrf
14792  */
14793 static int
14794 api_one_eid_table_add_del_map (vat_main_t * vam)
14795 {
14796   unformat_input_t *input = vam->input;
14797   vl_api_one_eid_table_add_del_map_t *mp;
14798   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
14799   u32 vni, vrf, bd_index;
14800   int ret;
14801
14802   /* Parse args required to build the message */
14803   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14804     {
14805       if (unformat (input, "del"))
14806         is_add = 0;
14807       else if (unformat (input, "vrf %d", &vrf))
14808         vrf_set = 1;
14809       else if (unformat (input, "bd_index %d", &bd_index))
14810         bd_index_set = 1;
14811       else if (unformat (input, "vni %d", &vni))
14812         vni_set = 1;
14813       else
14814         break;
14815     }
14816
14817   if (!vni_set || (!vrf_set && !bd_index_set))
14818     {
14819       errmsg ("missing arguments!");
14820       return -99;
14821     }
14822
14823   if (vrf_set && bd_index_set)
14824     {
14825       errmsg ("error: both vrf and bd entered!");
14826       return -99;
14827     }
14828
14829   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
14830
14831   mp->is_add = is_add;
14832   mp->vni = htonl (vni);
14833   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
14834   mp->is_l2 = bd_index_set;
14835
14836   /* send */
14837   S (mp);
14838
14839   /* wait for reply */
14840   W (ret);
14841   return ret;
14842 }
14843
14844 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
14845
14846 uword
14847 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
14848 {
14849   u32 *action = va_arg (*args, u32 *);
14850   u8 *s = 0;
14851
14852   if (unformat (input, "%s", &s))
14853     {
14854       if (!strcmp ((char *) s, "no-action"))
14855         action[0] = 0;
14856       else if (!strcmp ((char *) s, "natively-forward"))
14857         action[0] = 1;
14858       else if (!strcmp ((char *) s, "send-map-request"))
14859         action[0] = 2;
14860       else if (!strcmp ((char *) s, "drop"))
14861         action[0] = 3;
14862       else
14863         {
14864           clib_warning ("invalid action: '%s'", s);
14865           action[0] = 3;
14866         }
14867     }
14868   else
14869     return 0;
14870
14871   vec_free (s);
14872   return 1;
14873 }
14874
14875 /**
14876  * Add/del remote mapping to/from ONE control plane
14877  *
14878  * @param vam vpp API test context
14879  * @return return code
14880  */
14881 static int
14882 api_one_add_del_remote_mapping (vat_main_t * vam)
14883 {
14884   unformat_input_t *input = vam->input;
14885   vl_api_one_add_del_remote_mapping_t *mp;
14886   u32 vni = 0;
14887   lisp_eid_vat_t _eid, *eid = &_eid;
14888   lisp_eid_vat_t _seid, *seid = &_seid;
14889   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
14890   u32 action = ~0, p, w, data_len;
14891   ip4_address_t rloc4;
14892   ip6_address_t rloc6;
14893   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
14894   int ret;
14895
14896   memset (&rloc, 0, sizeof (rloc));
14897
14898   /* Parse args required to build the message */
14899   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14900     {
14901       if (unformat (input, "del-all"))
14902         {
14903           del_all = 1;
14904         }
14905       else if (unformat (input, "del"))
14906         {
14907           is_add = 0;
14908         }
14909       else if (unformat (input, "add"))
14910         {
14911           is_add = 1;
14912         }
14913       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
14914         {
14915           eid_set = 1;
14916         }
14917       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
14918         {
14919           seid_set = 1;
14920         }
14921       else if (unformat (input, "vni %d", &vni))
14922         {
14923           ;
14924         }
14925       else if (unformat (input, "p %d w %d", &p, &w))
14926         {
14927           if (!curr_rloc)
14928             {
14929               errmsg ("No RLOC configured for setting priority/weight!");
14930               return -99;
14931             }
14932           curr_rloc->priority = p;
14933           curr_rloc->weight = w;
14934         }
14935       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
14936         {
14937           rloc.is_ip4 = 1;
14938           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
14939           vec_add1 (rlocs, rloc);
14940           curr_rloc = &rlocs[vec_len (rlocs) - 1];
14941         }
14942       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
14943         {
14944           rloc.is_ip4 = 0;
14945           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
14946           vec_add1 (rlocs, rloc);
14947           curr_rloc = &rlocs[vec_len (rlocs) - 1];
14948         }
14949       else if (unformat (input, "action %U",
14950                          unformat_negative_mapping_action, &action))
14951         {
14952           ;
14953         }
14954       else
14955         {
14956           clib_warning ("parse error '%U'", format_unformat_error, input);
14957           return -99;
14958         }
14959     }
14960
14961   if (0 == eid_set)
14962     {
14963       errmsg ("missing params!");
14964       return -99;
14965     }
14966
14967   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
14968     {
14969       errmsg ("no action set for negative map-reply!");
14970       return -99;
14971     }
14972
14973   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
14974
14975   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
14976   mp->is_add = is_add;
14977   mp->vni = htonl (vni);
14978   mp->action = (u8) action;
14979   mp->is_src_dst = seid_set;
14980   mp->eid_len = eid->len;
14981   mp->seid_len = seid->len;
14982   mp->del_all = del_all;
14983   mp->eid_type = eid->type;
14984   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
14985   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
14986
14987   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
14988   clib_memcpy (mp->rlocs, rlocs, data_len);
14989   vec_free (rlocs);
14990
14991   /* send it... */
14992   S (mp);
14993
14994   /* Wait for a reply... */
14995   W (ret);
14996   return ret;
14997 }
14998
14999 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
15000
15001 /**
15002  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
15003  * forwarding entries in data-plane accordingly.
15004  *
15005  * @param vam vpp API test context
15006  * @return return code
15007  */
15008 static int
15009 api_one_add_del_adjacency (vat_main_t * vam)
15010 {
15011   unformat_input_t *input = vam->input;
15012   vl_api_one_add_del_adjacency_t *mp;
15013   u32 vni = 0;
15014   ip4_address_t leid4, reid4;
15015   ip6_address_t leid6, reid6;
15016   u8 reid_mac[6] = { 0 };
15017   u8 leid_mac[6] = { 0 };
15018   u8 reid_type, leid_type;
15019   u32 leid_len = 0, reid_len = 0, len;
15020   u8 is_add = 1;
15021   int ret;
15022
15023   leid_type = reid_type = (u8) ~ 0;
15024
15025   /* Parse args required to build the message */
15026   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15027     {
15028       if (unformat (input, "del"))
15029         {
15030           is_add = 0;
15031         }
15032       else if (unformat (input, "add"))
15033         {
15034           is_add = 1;
15035         }
15036       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
15037                          &reid4, &len))
15038         {
15039           reid_type = 0;        /* ipv4 */
15040           reid_len = len;
15041         }
15042       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
15043                          &reid6, &len))
15044         {
15045           reid_type = 1;        /* ipv6 */
15046           reid_len = len;
15047         }
15048       else if (unformat (input, "reid %U", unformat_ethernet_address,
15049                          reid_mac))
15050         {
15051           reid_type = 2;        /* mac */
15052         }
15053       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
15054                          &leid4, &len))
15055         {
15056           leid_type = 0;        /* ipv4 */
15057           leid_len = len;
15058         }
15059       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
15060                          &leid6, &len))
15061         {
15062           leid_type = 1;        /* ipv6 */
15063           leid_len = len;
15064         }
15065       else if (unformat (input, "leid %U", unformat_ethernet_address,
15066                          leid_mac))
15067         {
15068           leid_type = 2;        /* mac */
15069         }
15070       else if (unformat (input, "vni %d", &vni))
15071         {
15072           ;
15073         }
15074       else
15075         {
15076           errmsg ("parse error '%U'", format_unformat_error, input);
15077           return -99;
15078         }
15079     }
15080
15081   if ((u8) ~ 0 == reid_type)
15082     {
15083       errmsg ("missing params!");
15084       return -99;
15085     }
15086
15087   if (leid_type != reid_type)
15088     {
15089       errmsg ("remote and local EIDs are of different types!");
15090       return -99;
15091     }
15092
15093   M (ONE_ADD_DEL_ADJACENCY, mp);
15094   mp->is_add = is_add;
15095   mp->vni = htonl (vni);
15096   mp->leid_len = leid_len;
15097   mp->reid_len = reid_len;
15098   mp->eid_type = reid_type;
15099
15100   switch (mp->eid_type)
15101     {
15102     case 0:
15103       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
15104       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
15105       break;
15106     case 1:
15107       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
15108       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
15109       break;
15110     case 2:
15111       clib_memcpy (mp->leid, leid_mac, 6);
15112       clib_memcpy (mp->reid, reid_mac, 6);
15113       break;
15114     default:
15115       errmsg ("unknown EID type %d!", mp->eid_type);
15116       return 0;
15117     }
15118
15119   /* send it... */
15120   S (mp);
15121
15122   /* Wait for a reply... */
15123   W (ret);
15124   return ret;
15125 }
15126
15127 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
15128
15129 uword
15130 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
15131 {
15132   u32 *mode = va_arg (*args, u32 *);
15133
15134   if (unformat (input, "lisp"))
15135     *mode = 0;
15136   else if (unformat (input, "vxlan"))
15137     *mode = 1;
15138   else
15139     return 0;
15140
15141   return 1;
15142 }
15143
15144 static int
15145 api_gpe_get_encap_mode (vat_main_t * vam)
15146 {
15147   vl_api_gpe_get_encap_mode_t *mp;
15148   int ret;
15149
15150   /* Construct the API message */
15151   M (GPE_GET_ENCAP_MODE, mp);
15152
15153   /* send it... */
15154   S (mp);
15155
15156   /* Wait for a reply... */
15157   W (ret);
15158   return ret;
15159 }
15160
15161 static int
15162 api_gpe_set_encap_mode (vat_main_t * vam)
15163 {
15164   unformat_input_t *input = vam->input;
15165   vl_api_gpe_set_encap_mode_t *mp;
15166   int ret;
15167   u32 mode = 0;
15168
15169   /* Parse args required to build the message */
15170   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15171     {
15172       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
15173         ;
15174       else
15175         break;
15176     }
15177
15178   /* Construct the API message */
15179   M (GPE_SET_ENCAP_MODE, mp);
15180
15181   mp->mode = mode;
15182
15183   /* send it... */
15184   S (mp);
15185
15186   /* Wait for a reply... */
15187   W (ret);
15188   return ret;
15189 }
15190
15191 static int
15192 api_lisp_gpe_add_del_iface (vat_main_t * vam)
15193 {
15194   unformat_input_t *input = vam->input;
15195   vl_api_gpe_add_del_iface_t *mp;
15196   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
15197   u32 dp_table = 0, vni = 0;
15198   int ret;
15199
15200   /* Parse args required to build the message */
15201   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15202     {
15203       if (unformat (input, "up"))
15204         {
15205           action_set = 1;
15206           is_add = 1;
15207         }
15208       else if (unformat (input, "down"))
15209         {
15210           action_set = 1;
15211           is_add = 0;
15212         }
15213       else if (unformat (input, "table_id %d", &dp_table))
15214         {
15215           dp_table_set = 1;
15216         }
15217       else if (unformat (input, "bd_id %d", &dp_table))
15218         {
15219           dp_table_set = 1;
15220           is_l2 = 1;
15221         }
15222       else if (unformat (input, "vni %d", &vni))
15223         {
15224           vni_set = 1;
15225         }
15226       else
15227         break;
15228     }
15229
15230   if (action_set == 0)
15231     {
15232       errmsg ("Action not set");
15233       return -99;
15234     }
15235   if (dp_table_set == 0 || vni_set == 0)
15236     {
15237       errmsg ("vni and dp_table must be set");
15238       return -99;
15239     }
15240
15241   /* Construct the API message */
15242   M (GPE_ADD_DEL_IFACE, mp);
15243
15244   mp->is_add = is_add;
15245   mp->dp_table = dp_table;
15246   mp->is_l2 = is_l2;
15247   mp->vni = vni;
15248
15249   /* send it... */
15250   S (mp);
15251
15252   /* Wait for a reply... */
15253   W (ret);
15254   return ret;
15255 }
15256
15257 /**
15258  * Add/del map request itr rlocs from ONE control plane and updates
15259  *
15260  * @param vam vpp API test context
15261  * @return return code
15262  */
15263 static int
15264 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
15265 {
15266   unformat_input_t *input = vam->input;
15267   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
15268   u8 *locator_set_name = 0;
15269   u8 locator_set_name_set = 0;
15270   u8 is_add = 1;
15271   int ret;
15272
15273   /* Parse args required to build the message */
15274   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15275     {
15276       if (unformat (input, "del"))
15277         {
15278           is_add = 0;
15279         }
15280       else if (unformat (input, "%_%v%_", &locator_set_name))
15281         {
15282           locator_set_name_set = 1;
15283         }
15284       else
15285         {
15286           clib_warning ("parse error '%U'", format_unformat_error, input);
15287           return -99;
15288         }
15289     }
15290
15291   if (is_add && !locator_set_name_set)
15292     {
15293       errmsg ("itr-rloc is not set!");
15294       return -99;
15295     }
15296
15297   if (is_add && vec_len (locator_set_name) > 64)
15298     {
15299       errmsg ("itr-rloc locator-set name too long");
15300       vec_free (locator_set_name);
15301       return -99;
15302     }
15303
15304   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
15305   mp->is_add = is_add;
15306   if (is_add)
15307     {
15308       clib_memcpy (mp->locator_set_name, locator_set_name,
15309                    vec_len (locator_set_name));
15310     }
15311   else
15312     {
15313       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
15314     }
15315   vec_free (locator_set_name);
15316
15317   /* send it... */
15318   S (mp);
15319
15320   /* Wait for a reply... */
15321   W (ret);
15322   return ret;
15323 }
15324
15325 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
15326
15327 static int
15328 api_one_locator_dump (vat_main_t * vam)
15329 {
15330   unformat_input_t *input = vam->input;
15331   vl_api_one_locator_dump_t *mp;
15332   vl_api_control_ping_t *mp_ping;
15333   u8 is_index_set = 0, is_name_set = 0;
15334   u8 *ls_name = 0;
15335   u32 ls_index = ~0;
15336   int ret;
15337
15338   /* Parse args required to build the message */
15339   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15340     {
15341       if (unformat (input, "ls_name %_%v%_", &ls_name))
15342         {
15343           is_name_set = 1;
15344         }
15345       else if (unformat (input, "ls_index %d", &ls_index))
15346         {
15347           is_index_set = 1;
15348         }
15349       else
15350         {
15351           errmsg ("parse error '%U'", format_unformat_error, input);
15352           return -99;
15353         }
15354     }
15355
15356   if (!is_index_set && !is_name_set)
15357     {
15358       errmsg ("error: expected one of index or name!");
15359       return -99;
15360     }
15361
15362   if (is_index_set && is_name_set)
15363     {
15364       errmsg ("error: only one param expected!");
15365       return -99;
15366     }
15367
15368   if (vec_len (ls_name) > 62)
15369     {
15370       errmsg ("error: locator set name too long!");
15371       return -99;
15372     }
15373
15374   if (!vam->json_output)
15375     {
15376       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
15377     }
15378
15379   M (ONE_LOCATOR_DUMP, mp);
15380   mp->is_index_set = is_index_set;
15381
15382   if (is_index_set)
15383     mp->ls_index = clib_host_to_net_u32 (ls_index);
15384   else
15385     {
15386       vec_add1 (ls_name, 0);
15387       strncpy ((char *) mp->ls_name, (char *) ls_name,
15388                sizeof (mp->ls_name) - 1);
15389     }
15390
15391   /* send it... */
15392   S (mp);
15393
15394   /* Use a control ping for synchronization */
15395   M (CONTROL_PING, mp_ping);
15396   S (mp_ping);
15397
15398   /* Wait for a reply... */
15399   W (ret);
15400   return ret;
15401 }
15402
15403 #define api_lisp_locator_dump api_one_locator_dump
15404
15405 static int
15406 api_one_locator_set_dump (vat_main_t * vam)
15407 {
15408   vl_api_one_locator_set_dump_t *mp;
15409   vl_api_control_ping_t *mp_ping;
15410   unformat_input_t *input = vam->input;
15411   u8 filter = 0;
15412   int ret;
15413
15414   /* Parse args required to build the message */
15415   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15416     {
15417       if (unformat (input, "local"))
15418         {
15419           filter = 1;
15420         }
15421       else if (unformat (input, "remote"))
15422         {
15423           filter = 2;
15424         }
15425       else
15426         {
15427           errmsg ("parse error '%U'", format_unformat_error, input);
15428           return -99;
15429         }
15430     }
15431
15432   if (!vam->json_output)
15433     {
15434       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
15435     }
15436
15437   M (ONE_LOCATOR_SET_DUMP, mp);
15438
15439   mp->filter = filter;
15440
15441   /* send it... */
15442   S (mp);
15443
15444   /* Use a control ping for synchronization */
15445   M (CONTROL_PING, mp_ping);
15446   S (mp_ping);
15447
15448   /* Wait for a reply... */
15449   W (ret);
15450   return ret;
15451 }
15452
15453 #define api_lisp_locator_set_dump api_one_locator_set_dump
15454
15455 static int
15456 api_one_eid_table_map_dump (vat_main_t * vam)
15457 {
15458   u8 is_l2 = 0;
15459   u8 mode_set = 0;
15460   unformat_input_t *input = vam->input;
15461   vl_api_one_eid_table_map_dump_t *mp;
15462   vl_api_control_ping_t *mp_ping;
15463   int ret;
15464
15465   /* Parse args required to build the message */
15466   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15467     {
15468       if (unformat (input, "l2"))
15469         {
15470           is_l2 = 1;
15471           mode_set = 1;
15472         }
15473       else if (unformat (input, "l3"))
15474         {
15475           is_l2 = 0;
15476           mode_set = 1;
15477         }
15478       else
15479         {
15480           errmsg ("parse error '%U'", format_unformat_error, input);
15481           return -99;
15482         }
15483     }
15484
15485   if (!mode_set)
15486     {
15487       errmsg ("expected one of 'l2' or 'l3' parameter!");
15488       return -99;
15489     }
15490
15491   if (!vam->json_output)
15492     {
15493       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
15494     }
15495
15496   M (ONE_EID_TABLE_MAP_DUMP, mp);
15497   mp->is_l2 = is_l2;
15498
15499   /* send it... */
15500   S (mp);
15501
15502   /* Use a control ping for synchronization */
15503   M (CONTROL_PING, mp_ping);
15504   S (mp_ping);
15505
15506   /* Wait for a reply... */
15507   W (ret);
15508   return ret;
15509 }
15510
15511 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
15512
15513 static int
15514 api_one_eid_table_vni_dump (vat_main_t * vam)
15515 {
15516   vl_api_one_eid_table_vni_dump_t *mp;
15517   vl_api_control_ping_t *mp_ping;
15518   int ret;
15519
15520   if (!vam->json_output)
15521     {
15522       print (vam->ofp, "VNI");
15523     }
15524
15525   M (ONE_EID_TABLE_VNI_DUMP, mp);
15526
15527   /* send it... */
15528   S (mp);
15529
15530   /* Use a control ping for synchronization */
15531   M (CONTROL_PING, mp_ping);
15532   S (mp_ping);
15533
15534   /* Wait for a reply... */
15535   W (ret);
15536   return ret;
15537 }
15538
15539 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
15540
15541 static int
15542 api_one_eid_table_dump (vat_main_t * vam)
15543 {
15544   unformat_input_t *i = vam->input;
15545   vl_api_one_eid_table_dump_t *mp;
15546   vl_api_control_ping_t *mp_ping;
15547   struct in_addr ip4;
15548   struct in6_addr ip6;
15549   u8 mac[6];
15550   u8 eid_type = ~0, eid_set = 0;
15551   u32 prefix_length = ~0, t, vni = 0;
15552   u8 filter = 0;
15553   int ret;
15554
15555   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15556     {
15557       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
15558         {
15559           eid_set = 1;
15560           eid_type = 0;
15561           prefix_length = t;
15562         }
15563       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
15564         {
15565           eid_set = 1;
15566           eid_type = 1;
15567           prefix_length = t;
15568         }
15569       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
15570         {
15571           eid_set = 1;
15572           eid_type = 2;
15573         }
15574       else if (unformat (i, "vni %d", &t))
15575         {
15576           vni = t;
15577         }
15578       else if (unformat (i, "local"))
15579         {
15580           filter = 1;
15581         }
15582       else if (unformat (i, "remote"))
15583         {
15584           filter = 2;
15585         }
15586       else
15587         {
15588           errmsg ("parse error '%U'", format_unformat_error, i);
15589           return -99;
15590         }
15591     }
15592
15593   if (!vam->json_output)
15594     {
15595       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
15596              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
15597     }
15598
15599   M (ONE_EID_TABLE_DUMP, mp);
15600
15601   mp->filter = filter;
15602   if (eid_set)
15603     {
15604       mp->eid_set = 1;
15605       mp->vni = htonl (vni);
15606       mp->eid_type = eid_type;
15607       switch (eid_type)
15608         {
15609         case 0:
15610           mp->prefix_length = prefix_length;
15611           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
15612           break;
15613         case 1:
15614           mp->prefix_length = prefix_length;
15615           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
15616           break;
15617         case 2:
15618           clib_memcpy (mp->eid, mac, sizeof (mac));
15619           break;
15620         default:
15621           errmsg ("unknown EID type %d!", eid_type);
15622           return -99;
15623         }
15624     }
15625
15626   /* send it... */
15627   S (mp);
15628
15629   /* Use a control ping for synchronization */
15630   M (CONTROL_PING, mp_ping);
15631   S (mp_ping);
15632
15633   /* Wait for a reply... */
15634   W (ret);
15635   return ret;
15636 }
15637
15638 #define api_lisp_eid_table_dump api_one_eid_table_dump
15639
15640 static int
15641 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
15642 {
15643   unformat_input_t *i = vam->input;
15644   vl_api_gpe_fwd_entries_get_t *mp;
15645   u8 vni_set = 0;
15646   u32 vni = ~0;
15647   int ret;
15648
15649   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15650     {
15651       if (unformat (i, "vni %d", &vni))
15652         {
15653           vni_set = 1;
15654         }
15655       else
15656         {
15657           errmsg ("parse error '%U'", format_unformat_error, i);
15658           return -99;
15659         }
15660     }
15661
15662   if (!vni_set)
15663     {
15664       errmsg ("vni not set!");
15665       return -99;
15666     }
15667
15668   if (!vam->json_output)
15669     {
15670       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
15671              "leid", "reid");
15672     }
15673
15674   M (GPE_FWD_ENTRIES_GET, mp);
15675   mp->vni = clib_host_to_net_u32 (vni);
15676
15677   /* send it... */
15678   S (mp);
15679
15680   /* Wait for a reply... */
15681   W (ret);
15682   return ret;
15683 }
15684
15685 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
15686 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
15687 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
15688 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
15689
15690 static int
15691 api_one_adjacencies_get (vat_main_t * vam)
15692 {
15693   unformat_input_t *i = vam->input;
15694   vl_api_one_adjacencies_get_t *mp;
15695   u8 vni_set = 0;
15696   u32 vni = ~0;
15697   int ret;
15698
15699   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15700     {
15701       if (unformat (i, "vni %d", &vni))
15702         {
15703           vni_set = 1;
15704         }
15705       else
15706         {
15707           errmsg ("parse error '%U'", format_unformat_error, i);
15708           return -99;
15709         }
15710     }
15711
15712   if (!vni_set)
15713     {
15714       errmsg ("vni not set!");
15715       return -99;
15716     }
15717
15718   if (!vam->json_output)
15719     {
15720       print (vam->ofp, "%s %40s", "leid", "reid");
15721     }
15722
15723   M (ONE_ADJACENCIES_GET, mp);
15724   mp->vni = clib_host_to_net_u32 (vni);
15725
15726   /* send it... */
15727   S (mp);
15728
15729   /* Wait for a reply... */
15730   W (ret);
15731   return ret;
15732 }
15733
15734 #define api_lisp_adjacencies_get api_one_adjacencies_get
15735
15736 static int
15737 api_one_map_server_dump (vat_main_t * vam)
15738 {
15739   vl_api_one_map_server_dump_t *mp;
15740   vl_api_control_ping_t *mp_ping;
15741   int ret;
15742
15743   if (!vam->json_output)
15744     {
15745       print (vam->ofp, "%=20s", "Map server");
15746     }
15747
15748   M (ONE_MAP_SERVER_DUMP, mp);
15749   /* send it... */
15750   S (mp);
15751
15752   /* Use a control ping for synchronization */
15753   M (CONTROL_PING, mp_ping);
15754   S (mp_ping);
15755
15756   /* Wait for a reply... */
15757   W (ret);
15758   return ret;
15759 }
15760
15761 #define api_lisp_map_server_dump api_one_map_server_dump
15762
15763 static int
15764 api_one_map_resolver_dump (vat_main_t * vam)
15765 {
15766   vl_api_one_map_resolver_dump_t *mp;
15767   vl_api_control_ping_t *mp_ping;
15768   int ret;
15769
15770   if (!vam->json_output)
15771     {
15772       print (vam->ofp, "%=20s", "Map resolver");
15773     }
15774
15775   M (ONE_MAP_RESOLVER_DUMP, mp);
15776   /* send it... */
15777   S (mp);
15778
15779   /* Use a control ping for synchronization */
15780   M (CONTROL_PING, mp_ping);
15781   S (mp_ping);
15782
15783   /* Wait for a reply... */
15784   W (ret);
15785   return ret;
15786 }
15787
15788 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
15789
15790 static int
15791 api_one_stats_dump (vat_main_t * vam)
15792 {
15793   vl_api_one_stats_dump_t *mp;
15794   vl_api_control_ping_t *mp_ping;
15795   int ret;
15796
15797   M (ONE_STATS_DUMP, mp);
15798   /* send it... */
15799   S (mp);
15800
15801   /* Use a control ping for synchronization */
15802   M (CONTROL_PING, mp_ping);
15803   S (mp_ping);
15804
15805   /* Wait for a reply... */
15806   W (ret);
15807   return ret;
15808 }
15809
15810 static int
15811 api_show_one_status (vat_main_t * vam)
15812 {
15813   vl_api_show_one_status_t *mp;
15814   int ret;
15815
15816   if (!vam->json_output)
15817     {
15818       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
15819     }
15820
15821   M (SHOW_ONE_STATUS, mp);
15822   /* send it... */
15823   S (mp);
15824   /* Wait for a reply... */
15825   W (ret);
15826   return ret;
15827 }
15828
15829 #define api_show_lisp_status api_show_one_status
15830
15831 static int
15832 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
15833 {
15834   vl_api_gpe_fwd_entry_path_dump_t *mp;
15835   vl_api_control_ping_t *mp_ping;
15836   unformat_input_t *i = vam->input;
15837   u32 fwd_entry_index = ~0;
15838   int ret;
15839
15840   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15841     {
15842       if (unformat (i, "index %d", &fwd_entry_index))
15843         ;
15844       else
15845         break;
15846     }
15847
15848   if (~0 == fwd_entry_index)
15849     {
15850       errmsg ("no index specified!");
15851       return -99;
15852     }
15853
15854   if (!vam->json_output)
15855     {
15856       print (vam->ofp, "first line");
15857     }
15858
15859   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
15860
15861   /* send it... */
15862   S (mp);
15863   /* Use a control ping for synchronization */
15864   M (CONTROL_PING, mp_ping);
15865   S (mp_ping);
15866
15867   /* Wait for a reply... */
15868   W (ret);
15869   return ret;
15870 }
15871
15872 static int
15873 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
15874 {
15875   vl_api_one_get_map_request_itr_rlocs_t *mp;
15876   int ret;
15877
15878   if (!vam->json_output)
15879     {
15880       print (vam->ofp, "%=20s", "itr-rlocs:");
15881     }
15882
15883   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
15884   /* send it... */
15885   S (mp);
15886   /* Wait for a reply... */
15887   W (ret);
15888   return ret;
15889 }
15890
15891 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
15892
15893 static int
15894 api_af_packet_create (vat_main_t * vam)
15895 {
15896   unformat_input_t *i = vam->input;
15897   vl_api_af_packet_create_t *mp;
15898   u8 *host_if_name = 0;
15899   u8 hw_addr[6];
15900   u8 random_hw_addr = 1;
15901   int ret;
15902
15903   memset (hw_addr, 0, sizeof (hw_addr));
15904
15905   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15906     {
15907       if (unformat (i, "name %s", &host_if_name))
15908         vec_add1 (host_if_name, 0);
15909       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
15910         random_hw_addr = 0;
15911       else
15912         break;
15913     }
15914
15915   if (!vec_len (host_if_name))
15916     {
15917       errmsg ("host-interface name must be specified");
15918       return -99;
15919     }
15920
15921   if (vec_len (host_if_name) > 64)
15922     {
15923       errmsg ("host-interface name too long");
15924       return -99;
15925     }
15926
15927   M (AF_PACKET_CREATE, mp);
15928
15929   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
15930   clib_memcpy (mp->hw_addr, hw_addr, 6);
15931   mp->use_random_hw_addr = random_hw_addr;
15932   vec_free (host_if_name);
15933
15934   S (mp);
15935
15936   /* *INDENT-OFF* */
15937   W2 (ret,
15938       ({
15939         if (ret == 0)
15940           fprintf (vam->ofp ? vam->ofp : stderr,
15941                    " new sw_if_index = %d\n", vam->sw_if_index);
15942       }));
15943   /* *INDENT-ON* */
15944   return ret;
15945 }
15946
15947 static int
15948 api_af_packet_delete (vat_main_t * vam)
15949 {
15950   unformat_input_t *i = vam->input;
15951   vl_api_af_packet_delete_t *mp;
15952   u8 *host_if_name = 0;
15953   int ret;
15954
15955   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15956     {
15957       if (unformat (i, "name %s", &host_if_name))
15958         vec_add1 (host_if_name, 0);
15959       else
15960         break;
15961     }
15962
15963   if (!vec_len (host_if_name))
15964     {
15965       errmsg ("host-interface name must be specified");
15966       return -99;
15967     }
15968
15969   if (vec_len (host_if_name) > 64)
15970     {
15971       errmsg ("host-interface name too long");
15972       return -99;
15973     }
15974
15975   M (AF_PACKET_DELETE, mp);
15976
15977   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
15978   vec_free (host_if_name);
15979
15980   S (mp);
15981   W (ret);
15982   return ret;
15983 }
15984
15985 static int
15986 api_policer_add_del (vat_main_t * vam)
15987 {
15988   unformat_input_t *i = vam->input;
15989   vl_api_policer_add_del_t *mp;
15990   u8 is_add = 1;
15991   u8 *name = 0;
15992   u32 cir = 0;
15993   u32 eir = 0;
15994   u64 cb = 0;
15995   u64 eb = 0;
15996   u8 rate_type = 0;
15997   u8 round_type = 0;
15998   u8 type = 0;
15999   u8 color_aware = 0;
16000   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
16001   int ret;
16002
16003   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
16004   conform_action.dscp = 0;
16005   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
16006   exceed_action.dscp = 0;
16007   violate_action.action_type = SSE2_QOS_ACTION_DROP;
16008   violate_action.dscp = 0;
16009
16010   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16011     {
16012       if (unformat (i, "del"))
16013         is_add = 0;
16014       else if (unformat (i, "name %s", &name))
16015         vec_add1 (name, 0);
16016       else if (unformat (i, "cir %u", &cir))
16017         ;
16018       else if (unformat (i, "eir %u", &eir))
16019         ;
16020       else if (unformat (i, "cb %u", &cb))
16021         ;
16022       else if (unformat (i, "eb %u", &eb))
16023         ;
16024       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
16025                          &rate_type))
16026         ;
16027       else if (unformat (i, "round_type %U", unformat_policer_round_type,
16028                          &round_type))
16029         ;
16030       else if (unformat (i, "type %U", unformat_policer_type, &type))
16031         ;
16032       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
16033                          &conform_action))
16034         ;
16035       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
16036                          &exceed_action))
16037         ;
16038       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
16039                          &violate_action))
16040         ;
16041       else if (unformat (i, "color-aware"))
16042         color_aware = 1;
16043       else
16044         break;
16045     }
16046
16047   if (!vec_len (name))
16048     {
16049       errmsg ("policer name must be specified");
16050       return -99;
16051     }
16052
16053   if (vec_len (name) > 64)
16054     {
16055       errmsg ("policer name too long");
16056       return -99;
16057     }
16058
16059   M (POLICER_ADD_DEL, mp);
16060
16061   clib_memcpy (mp->name, name, vec_len (name));
16062   vec_free (name);
16063   mp->is_add = is_add;
16064   mp->cir = cir;
16065   mp->eir = eir;
16066   mp->cb = cb;
16067   mp->eb = eb;
16068   mp->rate_type = rate_type;
16069   mp->round_type = round_type;
16070   mp->type = type;
16071   mp->conform_action_type = conform_action.action_type;
16072   mp->conform_dscp = conform_action.dscp;
16073   mp->exceed_action_type = exceed_action.action_type;
16074   mp->exceed_dscp = exceed_action.dscp;
16075   mp->violate_action_type = violate_action.action_type;
16076   mp->violate_dscp = violate_action.dscp;
16077   mp->color_aware = color_aware;
16078
16079   S (mp);
16080   W (ret);
16081   return ret;
16082 }
16083
16084 static int
16085 api_policer_dump (vat_main_t * vam)
16086 {
16087   unformat_input_t *i = vam->input;
16088   vl_api_policer_dump_t *mp;
16089   vl_api_control_ping_t *mp_ping;
16090   u8 *match_name = 0;
16091   u8 match_name_valid = 0;
16092   int ret;
16093
16094   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16095     {
16096       if (unformat (i, "name %s", &match_name))
16097         {
16098           vec_add1 (match_name, 0);
16099           match_name_valid = 1;
16100         }
16101       else
16102         break;
16103     }
16104
16105   M (POLICER_DUMP, mp);
16106   mp->match_name_valid = match_name_valid;
16107   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
16108   vec_free (match_name);
16109   /* send it... */
16110   S (mp);
16111
16112   /* Use a control ping for synchronization */
16113   M (CONTROL_PING, mp_ping);
16114   S (mp_ping);
16115
16116   /* Wait for a reply... */
16117   W (ret);
16118   return ret;
16119 }
16120
16121 static int
16122 api_policer_classify_set_interface (vat_main_t * vam)
16123 {
16124   unformat_input_t *i = vam->input;
16125   vl_api_policer_classify_set_interface_t *mp;
16126   u32 sw_if_index;
16127   int sw_if_index_set;
16128   u32 ip4_table_index = ~0;
16129   u32 ip6_table_index = ~0;
16130   u32 l2_table_index = ~0;
16131   u8 is_add = 1;
16132   int ret;
16133
16134   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16135     {
16136       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16137         sw_if_index_set = 1;
16138       else if (unformat (i, "sw_if_index %d", &sw_if_index))
16139         sw_if_index_set = 1;
16140       else if (unformat (i, "del"))
16141         is_add = 0;
16142       else if (unformat (i, "ip4-table %d", &ip4_table_index))
16143         ;
16144       else if (unformat (i, "ip6-table %d", &ip6_table_index))
16145         ;
16146       else if (unformat (i, "l2-table %d", &l2_table_index))
16147         ;
16148       else
16149         {
16150           clib_warning ("parse error '%U'", format_unformat_error, i);
16151           return -99;
16152         }
16153     }
16154
16155   if (sw_if_index_set == 0)
16156     {
16157       errmsg ("missing interface name or sw_if_index");
16158       return -99;
16159     }
16160
16161   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
16162
16163   mp->sw_if_index = ntohl (sw_if_index);
16164   mp->ip4_table_index = ntohl (ip4_table_index);
16165   mp->ip6_table_index = ntohl (ip6_table_index);
16166   mp->l2_table_index = ntohl (l2_table_index);
16167   mp->is_add = is_add;
16168
16169   S (mp);
16170   W (ret);
16171   return ret;
16172 }
16173
16174 static int
16175 api_policer_classify_dump (vat_main_t * vam)
16176 {
16177   unformat_input_t *i = vam->input;
16178   vl_api_policer_classify_dump_t *mp;
16179   vl_api_control_ping_t *mp_ping;
16180   u8 type = POLICER_CLASSIFY_N_TABLES;
16181   int ret;
16182
16183   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
16184     ;
16185   else
16186     {
16187       errmsg ("classify table type must be specified");
16188       return -99;
16189     }
16190
16191   if (!vam->json_output)
16192     {
16193       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
16194     }
16195
16196   M (POLICER_CLASSIFY_DUMP, mp);
16197   mp->type = type;
16198   /* send it... */
16199   S (mp);
16200
16201   /* Use a control ping for synchronization */
16202   M (CONTROL_PING, mp_ping);
16203   S (mp_ping);
16204
16205   /* Wait for a reply... */
16206   W (ret);
16207   return ret;
16208 }
16209
16210 static int
16211 api_netmap_create (vat_main_t * vam)
16212 {
16213   unformat_input_t *i = vam->input;
16214   vl_api_netmap_create_t *mp;
16215   u8 *if_name = 0;
16216   u8 hw_addr[6];
16217   u8 random_hw_addr = 1;
16218   u8 is_pipe = 0;
16219   u8 is_master = 0;
16220   int ret;
16221
16222   memset (hw_addr, 0, sizeof (hw_addr));
16223
16224   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16225     {
16226       if (unformat (i, "name %s", &if_name))
16227         vec_add1 (if_name, 0);
16228       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
16229         random_hw_addr = 0;
16230       else if (unformat (i, "pipe"))
16231         is_pipe = 1;
16232       else if (unformat (i, "master"))
16233         is_master = 1;
16234       else if (unformat (i, "slave"))
16235         is_master = 0;
16236       else
16237         break;
16238     }
16239
16240   if (!vec_len (if_name))
16241     {
16242       errmsg ("interface name must be specified");
16243       return -99;
16244     }
16245
16246   if (vec_len (if_name) > 64)
16247     {
16248       errmsg ("interface name too long");
16249       return -99;
16250     }
16251
16252   M (NETMAP_CREATE, mp);
16253
16254   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
16255   clib_memcpy (mp->hw_addr, hw_addr, 6);
16256   mp->use_random_hw_addr = random_hw_addr;
16257   mp->is_pipe = is_pipe;
16258   mp->is_master = is_master;
16259   vec_free (if_name);
16260
16261   S (mp);
16262   W (ret);
16263   return ret;
16264 }
16265
16266 static int
16267 api_netmap_delete (vat_main_t * vam)
16268 {
16269   unformat_input_t *i = vam->input;
16270   vl_api_netmap_delete_t *mp;
16271   u8 *if_name = 0;
16272   int ret;
16273
16274   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16275     {
16276       if (unformat (i, "name %s", &if_name))
16277         vec_add1 (if_name, 0);
16278       else
16279         break;
16280     }
16281
16282   if (!vec_len (if_name))
16283     {
16284       errmsg ("interface name must be specified");
16285       return -99;
16286     }
16287
16288   if (vec_len (if_name) > 64)
16289     {
16290       errmsg ("interface name too long");
16291       return -99;
16292     }
16293
16294   M (NETMAP_DELETE, mp);
16295
16296   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
16297   vec_free (if_name);
16298
16299   S (mp);
16300   W (ret);
16301   return ret;
16302 }
16303
16304 static void vl_api_mpls_tunnel_details_t_handler
16305   (vl_api_mpls_tunnel_details_t * mp)
16306 {
16307   vat_main_t *vam = &vat_main;
16308   i32 len = mp->mt_next_hop_n_labels;
16309   i32 i;
16310
16311   print (vam->ofp, "[%d]: via %U %d labels ",
16312          mp->tunnel_index,
16313          format_ip4_address, mp->mt_next_hop,
16314          ntohl (mp->mt_next_hop_sw_if_index));
16315   for (i = 0; i < len; i++)
16316     {
16317       print (vam->ofp, "%u ", ntohl (mp->mt_next_hop_out_labels[i]));
16318     }
16319   print (vam->ofp, "");
16320 }
16321
16322 static void vl_api_mpls_tunnel_details_t_handler_json
16323   (vl_api_mpls_tunnel_details_t * mp)
16324 {
16325   vat_main_t *vam = &vat_main;
16326   vat_json_node_t *node = NULL;
16327   struct in_addr ip4;
16328   i32 i;
16329   i32 len = mp->mt_next_hop_n_labels;
16330
16331   if (VAT_JSON_ARRAY != vam->json_tree.type)
16332     {
16333       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16334       vat_json_init_array (&vam->json_tree);
16335     }
16336   node = vat_json_array_add (&vam->json_tree);
16337
16338   vat_json_init_object (node);
16339   vat_json_object_add_uint (node, "tunnel_index", ntohl (mp->tunnel_index));
16340   clib_memcpy (&ip4, &(mp->mt_next_hop), sizeof (ip4));
16341   vat_json_object_add_ip4 (node, "next_hop", ip4);
16342   vat_json_object_add_uint (node, "next_hop_sw_if_index",
16343                             ntohl (mp->mt_next_hop_sw_if_index));
16344   vat_json_object_add_uint (node, "l2_only", ntohl (mp->mt_l2_only));
16345   vat_json_object_add_uint (node, "label_count", len);
16346   for (i = 0; i < len; i++)
16347     {
16348       vat_json_object_add_uint (node, "label",
16349                                 ntohl (mp->mt_next_hop_out_labels[i]));
16350     }
16351 }
16352
16353 static int
16354 api_mpls_tunnel_dump (vat_main_t * vam)
16355 {
16356   vl_api_mpls_tunnel_dump_t *mp;
16357   vl_api_control_ping_t *mp_ping;
16358   i32 index = -1;
16359   int ret;
16360
16361   /* Parse args required to build the message */
16362   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
16363     {
16364       if (!unformat (vam->input, "tunnel_index %d", &index))
16365         {
16366           index = -1;
16367           break;
16368         }
16369     }
16370
16371   print (vam->ofp, "  tunnel_index %d", index);
16372
16373   M (MPLS_TUNNEL_DUMP, mp);
16374   mp->tunnel_index = htonl (index);
16375   S (mp);
16376
16377   /* Use a control ping for synchronization */
16378   M (CONTROL_PING, mp_ping);
16379   S (mp_ping);
16380
16381   W (ret);
16382   return ret;
16383 }
16384
16385 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
16386 #define vl_api_mpls_fib_details_t_print vl_noop_handler
16387
16388 static void
16389 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
16390 {
16391   vat_main_t *vam = &vat_main;
16392   int count = ntohl (mp->count);
16393   vl_api_fib_path2_t *fp;
16394   int i;
16395
16396   print (vam->ofp,
16397          "table-id %d, label %u, ess_bit %u",
16398          ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
16399   fp = mp->path;
16400   for (i = 0; i < count; i++)
16401     {
16402       if (fp->afi == IP46_TYPE_IP6)
16403         print (vam->ofp,
16404                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16405                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16406                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16407                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16408                format_ip6_address, fp->next_hop);
16409       else if (fp->afi == IP46_TYPE_IP4)
16410         print (vam->ofp,
16411                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16412                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16413                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16414                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16415                format_ip4_address, fp->next_hop);
16416       fp++;
16417     }
16418 }
16419
16420 static void vl_api_mpls_fib_details_t_handler_json
16421   (vl_api_mpls_fib_details_t * mp)
16422 {
16423   vat_main_t *vam = &vat_main;
16424   int count = ntohl (mp->count);
16425   vat_json_node_t *node = NULL;
16426   struct in_addr ip4;
16427   struct in6_addr ip6;
16428   vl_api_fib_path2_t *fp;
16429   int i;
16430
16431   if (VAT_JSON_ARRAY != vam->json_tree.type)
16432     {
16433       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16434       vat_json_init_array (&vam->json_tree);
16435     }
16436   node = vat_json_array_add (&vam->json_tree);
16437
16438   vat_json_init_object (node);
16439   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
16440   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
16441   vat_json_object_add_uint (node, "label", ntohl (mp->label));
16442   vat_json_object_add_uint (node, "path_count", count);
16443   fp = mp->path;
16444   for (i = 0; i < count; i++)
16445     {
16446       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
16447       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
16448       vat_json_object_add_uint (node, "is_local", fp->is_local);
16449       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
16450       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
16451       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
16452       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
16453       if (fp->afi == IP46_TYPE_IP4)
16454         {
16455           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
16456           vat_json_object_add_ip4 (node, "next_hop", ip4);
16457         }
16458       else if (fp->afi == IP46_TYPE_IP6)
16459         {
16460           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
16461           vat_json_object_add_ip6 (node, "next_hop", ip6);
16462         }
16463     }
16464 }
16465
16466 static int
16467 api_mpls_fib_dump (vat_main_t * vam)
16468 {
16469   vl_api_mpls_fib_dump_t *mp;
16470   vl_api_control_ping_t *mp_ping;
16471   int ret;
16472
16473   M (MPLS_FIB_DUMP, mp);
16474   S (mp);
16475
16476   /* Use a control ping for synchronization */
16477   M (CONTROL_PING, mp_ping);
16478   S (mp_ping);
16479
16480   W (ret);
16481   return ret;
16482 }
16483
16484 #define vl_api_ip_fib_details_t_endian vl_noop_handler
16485 #define vl_api_ip_fib_details_t_print vl_noop_handler
16486
16487 static void
16488 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
16489 {
16490   vat_main_t *vam = &vat_main;
16491   int count = ntohl (mp->count);
16492   vl_api_fib_path_t *fp;
16493   int i;
16494
16495   print (vam->ofp,
16496          "table-id %d, prefix %U/%d",
16497          ntohl (mp->table_id), format_ip4_address, mp->address,
16498          mp->address_length);
16499   fp = mp->path;
16500   for (i = 0; i < count; i++)
16501     {
16502       if (fp->afi == IP46_TYPE_IP6)
16503         print (vam->ofp,
16504                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16505                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16506                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16507                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16508                format_ip6_address, fp->next_hop);
16509       else if (fp->afi == IP46_TYPE_IP4)
16510         print (vam->ofp,
16511                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16512                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16513                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16514                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16515                format_ip4_address, fp->next_hop);
16516       fp++;
16517     }
16518 }
16519
16520 static void vl_api_ip_fib_details_t_handler_json
16521   (vl_api_ip_fib_details_t * mp)
16522 {
16523   vat_main_t *vam = &vat_main;
16524   int count = ntohl (mp->count);
16525   vat_json_node_t *node = NULL;
16526   struct in_addr ip4;
16527   struct in6_addr ip6;
16528   vl_api_fib_path_t *fp;
16529   int i;
16530
16531   if (VAT_JSON_ARRAY != vam->json_tree.type)
16532     {
16533       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16534       vat_json_init_array (&vam->json_tree);
16535     }
16536   node = vat_json_array_add (&vam->json_tree);
16537
16538   vat_json_init_object (node);
16539   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
16540   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
16541   vat_json_object_add_ip4 (node, "prefix", ip4);
16542   vat_json_object_add_uint (node, "mask_length", mp->address_length);
16543   vat_json_object_add_uint (node, "path_count", count);
16544   fp = mp->path;
16545   for (i = 0; i < count; i++)
16546     {
16547       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
16548       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
16549       vat_json_object_add_uint (node, "is_local", fp->is_local);
16550       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
16551       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
16552       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
16553       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
16554       if (fp->afi == IP46_TYPE_IP4)
16555         {
16556           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
16557           vat_json_object_add_ip4 (node, "next_hop", ip4);
16558         }
16559       else if (fp->afi == IP46_TYPE_IP6)
16560         {
16561           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
16562           vat_json_object_add_ip6 (node, "next_hop", ip6);
16563         }
16564     }
16565 }
16566
16567 static int
16568 api_ip_fib_dump (vat_main_t * vam)
16569 {
16570   vl_api_ip_fib_dump_t *mp;
16571   vl_api_control_ping_t *mp_ping;
16572   int ret;
16573
16574   M (IP_FIB_DUMP, mp);
16575   S (mp);
16576
16577   /* Use a control ping for synchronization */
16578   M (CONTROL_PING, mp_ping);
16579   S (mp_ping);
16580
16581   W (ret);
16582   return ret;
16583 }
16584
16585 static int
16586 api_ip_mfib_dump (vat_main_t * vam)
16587 {
16588   vl_api_ip_mfib_dump_t *mp;
16589   vl_api_control_ping_t *mp_ping;
16590   int ret;
16591
16592   M (IP_MFIB_DUMP, mp);
16593   S (mp);
16594
16595   /* Use a control ping for synchronization */
16596   M (CONTROL_PING, mp_ping);
16597   S (mp_ping);
16598
16599   W (ret);
16600   return ret;
16601 }
16602
16603 static void vl_api_ip_neighbor_details_t_handler
16604   (vl_api_ip_neighbor_details_t * mp)
16605 {
16606   vat_main_t *vam = &vat_main;
16607
16608   print (vam->ofp, "%c %U %U",
16609          (mp->is_static) ? 'S' : 'D',
16610          format_ethernet_address, &mp->mac_address,
16611          (mp->is_ipv6) ? format_ip6_address : format_ip4_address,
16612          &mp->ip_address);
16613 }
16614
16615 static void vl_api_ip_neighbor_details_t_handler_json
16616   (vl_api_ip_neighbor_details_t * mp)
16617 {
16618
16619   vat_main_t *vam = &vat_main;
16620   vat_json_node_t *node;
16621   struct in_addr ip4;
16622   struct in6_addr ip6;
16623
16624   if (VAT_JSON_ARRAY != vam->json_tree.type)
16625     {
16626       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16627       vat_json_init_array (&vam->json_tree);
16628     }
16629   node = vat_json_array_add (&vam->json_tree);
16630
16631   vat_json_init_object (node);
16632   vat_json_object_add_string_copy (node, "flag",
16633                                    (mp->is_static) ? (u8 *) "static" : (u8 *)
16634                                    "dynamic");
16635
16636   vat_json_object_add_string_copy (node, "link_layer",
16637                                    format (0, "%U", format_ethernet_address,
16638                                            &mp->mac_address));
16639
16640   if (mp->is_ipv6)
16641     {
16642       clib_memcpy (&ip6, &mp->ip_address, sizeof (ip6));
16643       vat_json_object_add_ip6 (node, "ip_address", ip6);
16644     }
16645   else
16646     {
16647       clib_memcpy (&ip4, &mp->ip_address, sizeof (ip4));
16648       vat_json_object_add_ip4 (node, "ip_address", ip4);
16649     }
16650 }
16651
16652 static int
16653 api_ip_neighbor_dump (vat_main_t * vam)
16654 {
16655   unformat_input_t *i = vam->input;
16656   vl_api_ip_neighbor_dump_t *mp;
16657   vl_api_control_ping_t *mp_ping;
16658   u8 is_ipv6 = 0;
16659   u32 sw_if_index = ~0;
16660   int ret;
16661
16662   /* Parse args required to build the message */
16663   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16664     {
16665       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16666         ;
16667       else if (unformat (i, "sw_if_index %d", &sw_if_index))
16668         ;
16669       else if (unformat (i, "ip6"))
16670         is_ipv6 = 1;
16671       else
16672         break;
16673     }
16674
16675   if (sw_if_index == ~0)
16676     {
16677       errmsg ("missing interface name or sw_if_index");
16678       return -99;
16679     }
16680
16681   M (IP_NEIGHBOR_DUMP, mp);
16682   mp->is_ipv6 = (u8) is_ipv6;
16683   mp->sw_if_index = ntohl (sw_if_index);
16684   S (mp);
16685
16686   /* Use a control ping for synchronization */
16687   M (CONTROL_PING, mp_ping);
16688   S (mp_ping);
16689
16690   W (ret);
16691   return ret;
16692 }
16693
16694 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
16695 #define vl_api_ip6_fib_details_t_print vl_noop_handler
16696
16697 static void
16698 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
16699 {
16700   vat_main_t *vam = &vat_main;
16701   int count = ntohl (mp->count);
16702   vl_api_fib_path_t *fp;
16703   int i;
16704
16705   print (vam->ofp,
16706          "table-id %d, prefix %U/%d",
16707          ntohl (mp->table_id), format_ip6_address, mp->address,
16708          mp->address_length);
16709   fp = mp->path;
16710   for (i = 0; i < count; i++)
16711     {
16712       if (fp->afi == IP46_TYPE_IP6)
16713         print (vam->ofp,
16714                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16715                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16716                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16717                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16718                format_ip6_address, fp->next_hop);
16719       else if (fp->afi == IP46_TYPE_IP4)
16720         print (vam->ofp,
16721                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16722                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16723                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16724                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16725                format_ip4_address, fp->next_hop);
16726       fp++;
16727     }
16728 }
16729
16730 static void vl_api_ip6_fib_details_t_handler_json
16731   (vl_api_ip6_fib_details_t * mp)
16732 {
16733   vat_main_t *vam = &vat_main;
16734   int count = ntohl (mp->count);
16735   vat_json_node_t *node = NULL;
16736   struct in_addr ip4;
16737   struct in6_addr ip6;
16738   vl_api_fib_path_t *fp;
16739   int i;
16740
16741   if (VAT_JSON_ARRAY != vam->json_tree.type)
16742     {
16743       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16744       vat_json_init_array (&vam->json_tree);
16745     }
16746   node = vat_json_array_add (&vam->json_tree);
16747
16748   vat_json_init_object (node);
16749   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
16750   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
16751   vat_json_object_add_ip6 (node, "prefix", ip6);
16752   vat_json_object_add_uint (node, "mask_length", mp->address_length);
16753   vat_json_object_add_uint (node, "path_count", count);
16754   fp = mp->path;
16755   for (i = 0; i < count; i++)
16756     {
16757       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
16758       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
16759       vat_json_object_add_uint (node, "is_local", fp->is_local);
16760       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
16761       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
16762       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
16763       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
16764       if (fp->afi == IP46_TYPE_IP4)
16765         {
16766           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
16767           vat_json_object_add_ip4 (node, "next_hop", ip4);
16768         }
16769       else if (fp->afi == IP46_TYPE_IP6)
16770         {
16771           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
16772           vat_json_object_add_ip6 (node, "next_hop", ip6);
16773         }
16774     }
16775 }
16776
16777 static int
16778 api_ip6_fib_dump (vat_main_t * vam)
16779 {
16780   vl_api_ip6_fib_dump_t *mp;
16781   vl_api_control_ping_t *mp_ping;
16782   int ret;
16783
16784   M (IP6_FIB_DUMP, mp);
16785   S (mp);
16786
16787   /* Use a control ping for synchronization */
16788   M (CONTROL_PING, mp_ping);
16789   S (mp_ping);
16790
16791   W (ret);
16792   return ret;
16793 }
16794
16795 static int
16796 api_ip6_mfib_dump (vat_main_t * vam)
16797 {
16798   vl_api_ip6_mfib_dump_t *mp;
16799   vl_api_control_ping_t *mp_ping;
16800   int ret;
16801
16802   M (IP6_MFIB_DUMP, mp);
16803   S (mp);
16804
16805   /* Use a control ping for synchronization */
16806   M (CONTROL_PING, mp_ping);
16807   S (mp_ping);
16808
16809   W (ret);
16810   return ret;
16811 }
16812
16813 int
16814 api_classify_table_ids (vat_main_t * vam)
16815 {
16816   vl_api_classify_table_ids_t *mp;
16817   int ret;
16818
16819   /* Construct the API message */
16820   M (CLASSIFY_TABLE_IDS, mp);
16821   mp->context = 0;
16822
16823   S (mp);
16824   W (ret);
16825   return ret;
16826 }
16827
16828 int
16829 api_classify_table_by_interface (vat_main_t * vam)
16830 {
16831   unformat_input_t *input = vam->input;
16832   vl_api_classify_table_by_interface_t *mp;
16833
16834   u32 sw_if_index = ~0;
16835   int ret;
16836   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16837     {
16838       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16839         ;
16840       else if (unformat (input, "sw_if_index %d", &sw_if_index))
16841         ;
16842       else
16843         break;
16844     }
16845   if (sw_if_index == ~0)
16846     {
16847       errmsg ("missing interface name or sw_if_index");
16848       return -99;
16849     }
16850
16851   /* Construct the API message */
16852   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
16853   mp->context = 0;
16854   mp->sw_if_index = ntohl (sw_if_index);
16855
16856   S (mp);
16857   W (ret);
16858   return ret;
16859 }
16860
16861 int
16862 api_classify_table_info (vat_main_t * vam)
16863 {
16864   unformat_input_t *input = vam->input;
16865   vl_api_classify_table_info_t *mp;
16866
16867   u32 table_id = ~0;
16868   int ret;
16869   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16870     {
16871       if (unformat (input, "table_id %d", &table_id))
16872         ;
16873       else
16874         break;
16875     }
16876   if (table_id == ~0)
16877     {
16878       errmsg ("missing table id");
16879       return -99;
16880     }
16881
16882   /* Construct the API message */
16883   M (CLASSIFY_TABLE_INFO, mp);
16884   mp->context = 0;
16885   mp->table_id = ntohl (table_id);
16886
16887   S (mp);
16888   W (ret);
16889   return ret;
16890 }
16891
16892 int
16893 api_classify_session_dump (vat_main_t * vam)
16894 {
16895   unformat_input_t *input = vam->input;
16896   vl_api_classify_session_dump_t *mp;
16897   vl_api_control_ping_t *mp_ping;
16898
16899   u32 table_id = ~0;
16900   int ret;
16901   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16902     {
16903       if (unformat (input, "table_id %d", &table_id))
16904         ;
16905       else
16906         break;
16907     }
16908   if (table_id == ~0)
16909     {
16910       errmsg ("missing table id");
16911       return -99;
16912     }
16913
16914   /* Construct the API message */
16915   M (CLASSIFY_SESSION_DUMP, mp);
16916   mp->context = 0;
16917   mp->table_id = ntohl (table_id);
16918   S (mp);
16919
16920   /* Use a control ping for synchronization */
16921   M (CONTROL_PING, mp_ping);
16922   S (mp_ping);
16923
16924   W (ret);
16925   return ret;
16926 }
16927
16928 static void
16929 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
16930 {
16931   vat_main_t *vam = &vat_main;
16932
16933   print (vam->ofp, "collector_address %U, collector_port %d, "
16934          "src_address %U, vrf_id %d, path_mtu %u, "
16935          "template_interval %u, udp_checksum %d",
16936          format_ip4_address, mp->collector_address,
16937          ntohs (mp->collector_port),
16938          format_ip4_address, mp->src_address,
16939          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
16940          ntohl (mp->template_interval), mp->udp_checksum);
16941
16942   vam->retval = 0;
16943   vam->result_ready = 1;
16944 }
16945
16946 static void
16947   vl_api_ipfix_exporter_details_t_handler_json
16948   (vl_api_ipfix_exporter_details_t * mp)
16949 {
16950   vat_main_t *vam = &vat_main;
16951   vat_json_node_t node;
16952   struct in_addr collector_address;
16953   struct in_addr src_address;
16954
16955   vat_json_init_object (&node);
16956   clib_memcpy (&collector_address, &mp->collector_address,
16957                sizeof (collector_address));
16958   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
16959   vat_json_object_add_uint (&node, "collector_port",
16960                             ntohs (mp->collector_port));
16961   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
16962   vat_json_object_add_ip4 (&node, "src_address", src_address);
16963   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
16964   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
16965   vat_json_object_add_uint (&node, "template_interval",
16966                             ntohl (mp->template_interval));
16967   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
16968
16969   vat_json_print (vam->ofp, &node);
16970   vat_json_free (&node);
16971   vam->retval = 0;
16972   vam->result_ready = 1;
16973 }
16974
16975 int
16976 api_ipfix_exporter_dump (vat_main_t * vam)
16977 {
16978   vl_api_ipfix_exporter_dump_t *mp;
16979   int ret;
16980
16981   /* Construct the API message */
16982   M (IPFIX_EXPORTER_DUMP, mp);
16983   mp->context = 0;
16984
16985   S (mp);
16986   W (ret);
16987   return ret;
16988 }
16989
16990 static int
16991 api_ipfix_classify_stream_dump (vat_main_t * vam)
16992 {
16993   vl_api_ipfix_classify_stream_dump_t *mp;
16994   int ret;
16995
16996   /* Construct the API message */
16997   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
16998   mp->context = 0;
16999
17000   S (mp);
17001   W (ret);
17002   return ret;
17003   /* NOTREACHED */
17004   return 0;
17005 }
17006
17007 static void
17008   vl_api_ipfix_classify_stream_details_t_handler
17009   (vl_api_ipfix_classify_stream_details_t * mp)
17010 {
17011   vat_main_t *vam = &vat_main;
17012   print (vam->ofp, "domain_id %d, src_port %d",
17013          ntohl (mp->domain_id), ntohs (mp->src_port));
17014   vam->retval = 0;
17015   vam->result_ready = 1;
17016 }
17017
17018 static void
17019   vl_api_ipfix_classify_stream_details_t_handler_json
17020   (vl_api_ipfix_classify_stream_details_t * mp)
17021 {
17022   vat_main_t *vam = &vat_main;
17023   vat_json_node_t node;
17024
17025   vat_json_init_object (&node);
17026   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
17027   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
17028
17029   vat_json_print (vam->ofp, &node);
17030   vat_json_free (&node);
17031   vam->retval = 0;
17032   vam->result_ready = 1;
17033 }
17034
17035 static int
17036 api_ipfix_classify_table_dump (vat_main_t * vam)
17037 {
17038   vl_api_ipfix_classify_table_dump_t *mp;
17039   vl_api_control_ping_t *mp_ping;
17040   int ret;
17041
17042   if (!vam->json_output)
17043     {
17044       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
17045              "transport_protocol");
17046     }
17047
17048   /* Construct the API message */
17049   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
17050
17051   /* send it... */
17052   S (mp);
17053
17054   /* Use a control ping for synchronization */
17055   M (CONTROL_PING, mp_ping);
17056   S (mp_ping);
17057
17058   W (ret);
17059   return ret;
17060 }
17061
17062 static void
17063   vl_api_ipfix_classify_table_details_t_handler
17064   (vl_api_ipfix_classify_table_details_t * mp)
17065 {
17066   vat_main_t *vam = &vat_main;
17067   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
17068          mp->transport_protocol);
17069 }
17070
17071 static void
17072   vl_api_ipfix_classify_table_details_t_handler_json
17073   (vl_api_ipfix_classify_table_details_t * mp)
17074 {
17075   vat_json_node_t *node = NULL;
17076   vat_main_t *vam = &vat_main;
17077
17078   if (VAT_JSON_ARRAY != vam->json_tree.type)
17079     {
17080       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17081       vat_json_init_array (&vam->json_tree);
17082     }
17083
17084   node = vat_json_array_add (&vam->json_tree);
17085   vat_json_init_object (node);
17086
17087   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
17088   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
17089   vat_json_object_add_uint (node, "transport_protocol",
17090                             mp->transport_protocol);
17091 }
17092
17093 static int
17094 api_sw_interface_span_enable_disable (vat_main_t * vam)
17095 {
17096   unformat_input_t *i = vam->input;
17097   vl_api_sw_interface_span_enable_disable_t *mp;
17098   u32 src_sw_if_index = ~0;
17099   u32 dst_sw_if_index = ~0;
17100   u8 state = 3;
17101   int ret;
17102
17103   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17104     {
17105       if (unformat
17106           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
17107         ;
17108       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
17109         ;
17110       else
17111         if (unformat
17112             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
17113         ;
17114       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
17115         ;
17116       else if (unformat (i, "disable"))
17117         state = 0;
17118       else if (unformat (i, "rx"))
17119         state = 1;
17120       else if (unformat (i, "tx"))
17121         state = 2;
17122       else if (unformat (i, "both"))
17123         state = 3;
17124       else
17125         break;
17126     }
17127
17128   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
17129
17130   mp->sw_if_index_from = htonl (src_sw_if_index);
17131   mp->sw_if_index_to = htonl (dst_sw_if_index);
17132   mp->state = state;
17133
17134   S (mp);
17135   W (ret);
17136   return ret;
17137 }
17138
17139 static void
17140 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
17141                                             * mp)
17142 {
17143   vat_main_t *vam = &vat_main;
17144   u8 *sw_if_from_name = 0;
17145   u8 *sw_if_to_name = 0;
17146   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
17147   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
17148   char *states[] = { "none", "rx", "tx", "both" };
17149   hash_pair_t *p;
17150
17151   /* *INDENT-OFF* */
17152   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
17153   ({
17154     if ((u32) p->value[0] == sw_if_index_from)
17155       {
17156         sw_if_from_name = (u8 *)(p->key);
17157         if (sw_if_to_name)
17158           break;
17159       }
17160     if ((u32) p->value[0] == sw_if_index_to)
17161       {
17162         sw_if_to_name = (u8 *)(p->key);
17163         if (sw_if_from_name)
17164           break;
17165       }
17166   }));
17167   /* *INDENT-ON* */
17168   print (vam->ofp, "%20s => %20s (%s)",
17169          sw_if_from_name, sw_if_to_name, states[mp->state]);
17170 }
17171
17172 static void
17173   vl_api_sw_interface_span_details_t_handler_json
17174   (vl_api_sw_interface_span_details_t * mp)
17175 {
17176   vat_main_t *vam = &vat_main;
17177   vat_json_node_t *node = NULL;
17178   u8 *sw_if_from_name = 0;
17179   u8 *sw_if_to_name = 0;
17180   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
17181   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
17182   hash_pair_t *p;
17183
17184   /* *INDENT-OFF* */
17185   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
17186   ({
17187     if ((u32) p->value[0] == sw_if_index_from)
17188       {
17189         sw_if_from_name = (u8 *)(p->key);
17190         if (sw_if_to_name)
17191           break;
17192       }
17193     if ((u32) p->value[0] == sw_if_index_to)
17194       {
17195         sw_if_to_name = (u8 *)(p->key);
17196         if (sw_if_from_name)
17197           break;
17198       }
17199   }));
17200   /* *INDENT-ON* */
17201
17202   if (VAT_JSON_ARRAY != vam->json_tree.type)
17203     {
17204       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17205       vat_json_init_array (&vam->json_tree);
17206     }
17207   node = vat_json_array_add (&vam->json_tree);
17208
17209   vat_json_init_object (node);
17210   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
17211   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
17212   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
17213   if (0 != sw_if_to_name)
17214     {
17215       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
17216     }
17217   vat_json_object_add_uint (node, "state", mp->state);
17218 }
17219
17220 static int
17221 api_sw_interface_span_dump (vat_main_t * vam)
17222 {
17223   vl_api_sw_interface_span_dump_t *mp;
17224   vl_api_control_ping_t *mp_ping;
17225   int ret;
17226
17227   M (SW_INTERFACE_SPAN_DUMP, mp);
17228   S (mp);
17229
17230   /* Use a control ping for synchronization */
17231   M (CONTROL_PING, mp_ping);
17232   S (mp_ping);
17233
17234   W (ret);
17235   return ret;
17236 }
17237
17238 int
17239 api_pg_create_interface (vat_main_t * vam)
17240 {
17241   unformat_input_t *input = vam->input;
17242   vl_api_pg_create_interface_t *mp;
17243
17244   u32 if_id = ~0;
17245   int ret;
17246   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17247     {
17248       if (unformat (input, "if_id %d", &if_id))
17249         ;
17250       else
17251         break;
17252     }
17253   if (if_id == ~0)
17254     {
17255       errmsg ("missing pg interface index");
17256       return -99;
17257     }
17258
17259   /* Construct the API message */
17260   M (PG_CREATE_INTERFACE, mp);
17261   mp->context = 0;
17262   mp->interface_id = ntohl (if_id);
17263
17264   S (mp);
17265   W (ret);
17266   return ret;
17267 }
17268
17269 int
17270 api_pg_capture (vat_main_t * vam)
17271 {
17272   unformat_input_t *input = vam->input;
17273   vl_api_pg_capture_t *mp;
17274
17275   u32 if_id = ~0;
17276   u8 enable = 1;
17277   u32 count = 1;
17278   u8 pcap_file_set = 0;
17279   u8 *pcap_file = 0;
17280   int ret;
17281   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17282     {
17283       if (unformat (input, "if_id %d", &if_id))
17284         ;
17285       else if (unformat (input, "pcap %s", &pcap_file))
17286         pcap_file_set = 1;
17287       else if (unformat (input, "count %d", &count))
17288         ;
17289       else if (unformat (input, "disable"))
17290         enable = 0;
17291       else
17292         break;
17293     }
17294   if (if_id == ~0)
17295     {
17296       errmsg ("missing pg interface index");
17297       return -99;
17298     }
17299   if (pcap_file_set > 0)
17300     {
17301       if (vec_len (pcap_file) > 255)
17302         {
17303           errmsg ("pcap file name is too long");
17304           return -99;
17305         }
17306     }
17307
17308   u32 name_len = vec_len (pcap_file);
17309   /* Construct the API message */
17310   M (PG_CAPTURE, mp);
17311   mp->context = 0;
17312   mp->interface_id = ntohl (if_id);
17313   mp->is_enabled = enable;
17314   mp->count = ntohl (count);
17315   mp->pcap_name_length = ntohl (name_len);
17316   if (pcap_file_set != 0)
17317     {
17318       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
17319     }
17320   vec_free (pcap_file);
17321
17322   S (mp);
17323   W (ret);
17324   return ret;
17325 }
17326
17327 int
17328 api_pg_enable_disable (vat_main_t * vam)
17329 {
17330   unformat_input_t *input = vam->input;
17331   vl_api_pg_enable_disable_t *mp;
17332
17333   u8 enable = 1;
17334   u8 stream_name_set = 0;
17335   u8 *stream_name = 0;
17336   int ret;
17337   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17338     {
17339       if (unformat (input, "stream %s", &stream_name))
17340         stream_name_set = 1;
17341       else if (unformat (input, "disable"))
17342         enable = 0;
17343       else
17344         break;
17345     }
17346
17347   if (stream_name_set > 0)
17348     {
17349       if (vec_len (stream_name) > 255)
17350         {
17351           errmsg ("stream name too long");
17352           return -99;
17353         }
17354     }
17355
17356   u32 name_len = vec_len (stream_name);
17357   /* Construct the API message */
17358   M (PG_ENABLE_DISABLE, mp);
17359   mp->context = 0;
17360   mp->is_enabled = enable;
17361   if (stream_name_set != 0)
17362     {
17363       mp->stream_name_length = ntohl (name_len);
17364       clib_memcpy (mp->stream_name, stream_name, name_len);
17365     }
17366   vec_free (stream_name);
17367
17368   S (mp);
17369   W (ret);
17370   return ret;
17371 }
17372
17373 int
17374 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
17375 {
17376   unformat_input_t *input = vam->input;
17377   vl_api_ip_source_and_port_range_check_add_del_t *mp;
17378
17379   u16 *low_ports = 0;
17380   u16 *high_ports = 0;
17381   u16 this_low;
17382   u16 this_hi;
17383   ip4_address_t ip4_addr;
17384   ip6_address_t ip6_addr;
17385   u32 length;
17386   u32 tmp, tmp2;
17387   u8 prefix_set = 0;
17388   u32 vrf_id = ~0;
17389   u8 is_add = 1;
17390   u8 is_ipv6 = 0;
17391   int ret;
17392
17393   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17394     {
17395       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
17396         {
17397           prefix_set = 1;
17398         }
17399       else
17400         if (unformat
17401             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
17402         {
17403           prefix_set = 1;
17404           is_ipv6 = 1;
17405         }
17406       else if (unformat (input, "vrf %d", &vrf_id))
17407         ;
17408       else if (unformat (input, "del"))
17409         is_add = 0;
17410       else if (unformat (input, "port %d", &tmp))
17411         {
17412           if (tmp == 0 || tmp > 65535)
17413             {
17414               errmsg ("port %d out of range", tmp);
17415               return -99;
17416             }
17417           this_low = tmp;
17418           this_hi = this_low + 1;
17419           vec_add1 (low_ports, this_low);
17420           vec_add1 (high_ports, this_hi);
17421         }
17422       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
17423         {
17424           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
17425             {
17426               errmsg ("incorrect range parameters");
17427               return -99;
17428             }
17429           this_low = tmp;
17430           /* Note: in debug CLI +1 is added to high before
17431              passing to real fn that does "the work"
17432              (ip_source_and_port_range_check_add_del).
17433              This fn is a wrapper around the binary API fn a
17434              control plane will call, which expects this increment
17435              to have occurred. Hence letting the binary API control
17436              plane fn do the increment for consistency between VAT
17437              and other control planes.
17438            */
17439           this_hi = tmp2;
17440           vec_add1 (low_ports, this_low);
17441           vec_add1 (high_ports, this_hi);
17442         }
17443       else
17444         break;
17445     }
17446
17447   if (prefix_set == 0)
17448     {
17449       errmsg ("<address>/<mask> not specified");
17450       return -99;
17451     }
17452
17453   if (vrf_id == ~0)
17454     {
17455       errmsg ("VRF ID required, not specified");
17456       return -99;
17457     }
17458
17459   if (vrf_id == 0)
17460     {
17461       errmsg
17462         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
17463       return -99;
17464     }
17465
17466   if (vec_len (low_ports) == 0)
17467     {
17468       errmsg ("At least one port or port range required");
17469       return -99;
17470     }
17471
17472   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
17473
17474   mp->is_add = is_add;
17475
17476   if (is_ipv6)
17477     {
17478       mp->is_ipv6 = 1;
17479       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
17480     }
17481   else
17482     {
17483       mp->is_ipv6 = 0;
17484       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
17485     }
17486
17487   mp->mask_length = length;
17488   mp->number_of_ranges = vec_len (low_ports);
17489
17490   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
17491   vec_free (low_ports);
17492
17493   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
17494   vec_free (high_ports);
17495
17496   mp->vrf_id = ntohl (vrf_id);
17497
17498   S (mp);
17499   W (ret);
17500   return ret;
17501 }
17502
17503 int
17504 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
17505 {
17506   unformat_input_t *input = vam->input;
17507   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
17508   u32 sw_if_index = ~0;
17509   int vrf_set = 0;
17510   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
17511   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
17512   u8 is_add = 1;
17513   int ret;
17514
17515   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17516     {
17517       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17518         ;
17519       else if (unformat (input, "sw_if_index %d", &sw_if_index))
17520         ;
17521       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
17522         vrf_set = 1;
17523       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
17524         vrf_set = 1;
17525       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
17526         vrf_set = 1;
17527       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
17528         vrf_set = 1;
17529       else if (unformat (input, "del"))
17530         is_add = 0;
17531       else
17532         break;
17533     }
17534
17535   if (sw_if_index == ~0)
17536     {
17537       errmsg ("Interface required but not specified");
17538       return -99;
17539     }
17540
17541   if (vrf_set == 0)
17542     {
17543       errmsg ("VRF ID required but not specified");
17544       return -99;
17545     }
17546
17547   if (tcp_out_vrf_id == 0
17548       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
17549     {
17550       errmsg
17551         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
17552       return -99;
17553     }
17554
17555   /* Construct the API message */
17556   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
17557
17558   mp->sw_if_index = ntohl (sw_if_index);
17559   mp->is_add = is_add;
17560   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
17561   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
17562   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
17563   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
17564
17565   /* send it... */
17566   S (mp);
17567
17568   /* Wait for a reply... */
17569   W (ret);
17570   return ret;
17571 }
17572
17573 static int
17574 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
17575 {
17576   unformat_input_t *i = vam->input;
17577   vl_api_ipsec_gre_add_del_tunnel_t *mp;
17578   u32 local_sa_id = 0;
17579   u32 remote_sa_id = 0;
17580   ip4_address_t src_address;
17581   ip4_address_t dst_address;
17582   u8 is_add = 1;
17583   int ret;
17584
17585   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17586     {
17587       if (unformat (i, "local_sa %d", &local_sa_id))
17588         ;
17589       else if (unformat (i, "remote_sa %d", &remote_sa_id))
17590         ;
17591       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
17592         ;
17593       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
17594         ;
17595       else if (unformat (i, "del"))
17596         is_add = 0;
17597       else
17598         {
17599           clib_warning ("parse error '%U'", format_unformat_error, i);
17600           return -99;
17601         }
17602     }
17603
17604   M (IPSEC_GRE_ADD_DEL_TUNNEL, mp);
17605
17606   mp->local_sa_id = ntohl (local_sa_id);
17607   mp->remote_sa_id = ntohl (remote_sa_id);
17608   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
17609   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
17610   mp->is_add = is_add;
17611
17612   S (mp);
17613   W (ret);
17614   return ret;
17615 }
17616
17617 static int
17618 api_punt (vat_main_t * vam)
17619 {
17620   unformat_input_t *i = vam->input;
17621   vl_api_punt_t *mp;
17622   u32 ipv = ~0;
17623   u32 protocol = ~0;
17624   u32 port = ~0;
17625   int is_add = 1;
17626   int ret;
17627
17628   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17629     {
17630       if (unformat (i, "ip %d", &ipv))
17631         ;
17632       else if (unformat (i, "protocol %d", &protocol))
17633         ;
17634       else if (unformat (i, "port %d", &port))
17635         ;
17636       else if (unformat (i, "del"))
17637         is_add = 0;
17638       else
17639         {
17640           clib_warning ("parse error '%U'", format_unformat_error, i);
17641           return -99;
17642         }
17643     }
17644
17645   M (PUNT, mp);
17646
17647   mp->is_add = (u8) is_add;
17648   mp->ipv = (u8) ipv;
17649   mp->l4_protocol = (u8) protocol;
17650   mp->l4_port = htons ((u16) port);
17651
17652   S (mp);
17653   W (ret);
17654   return ret;
17655 }
17656
17657 static void vl_api_ipsec_gre_tunnel_details_t_handler
17658   (vl_api_ipsec_gre_tunnel_details_t * mp)
17659 {
17660   vat_main_t *vam = &vat_main;
17661
17662   print (vam->ofp, "%11d%15U%15U%14d%14d",
17663          ntohl (mp->sw_if_index),
17664          format_ip4_address, &mp->src_address,
17665          format_ip4_address, &mp->dst_address,
17666          ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
17667 }
17668
17669 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
17670   (vl_api_ipsec_gre_tunnel_details_t * mp)
17671 {
17672   vat_main_t *vam = &vat_main;
17673   vat_json_node_t *node = NULL;
17674   struct in_addr ip4;
17675
17676   if (VAT_JSON_ARRAY != vam->json_tree.type)
17677     {
17678       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17679       vat_json_init_array (&vam->json_tree);
17680     }
17681   node = vat_json_array_add (&vam->json_tree);
17682
17683   vat_json_init_object (node);
17684   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
17685   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
17686   vat_json_object_add_ip4 (node, "src_address", ip4);
17687   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
17688   vat_json_object_add_ip4 (node, "dst_address", ip4);
17689   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
17690   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
17691 }
17692
17693 static int
17694 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
17695 {
17696   unformat_input_t *i = vam->input;
17697   vl_api_ipsec_gre_tunnel_dump_t *mp;
17698   vl_api_control_ping_t *mp_ping;
17699   u32 sw_if_index;
17700   u8 sw_if_index_set = 0;
17701   int ret;
17702
17703   /* Parse args required to build the message */
17704   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17705     {
17706       if (unformat (i, "sw_if_index %d", &sw_if_index))
17707         sw_if_index_set = 1;
17708       else
17709         break;
17710     }
17711
17712   if (sw_if_index_set == 0)
17713     {
17714       sw_if_index = ~0;
17715     }
17716
17717   if (!vam->json_output)
17718     {
17719       print (vam->ofp, "%11s%15s%15s%14s%14s",
17720              "sw_if_index", "src_address", "dst_address",
17721              "local_sa_id", "remote_sa_id");
17722     }
17723
17724   /* Get list of gre-tunnel interfaces */
17725   M (IPSEC_GRE_TUNNEL_DUMP, mp);
17726
17727   mp->sw_if_index = htonl (sw_if_index);
17728
17729   S (mp);
17730
17731   /* Use a control ping for synchronization */
17732   M (CONTROL_PING, mp_ping);
17733   S (mp_ping);
17734
17735   W (ret);
17736   return ret;
17737 }
17738
17739 static int
17740 api_delete_subif (vat_main_t * vam)
17741 {
17742   unformat_input_t *i = vam->input;
17743   vl_api_delete_subif_t *mp;
17744   u32 sw_if_index = ~0;
17745   int ret;
17746
17747   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17748     {
17749       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17750         ;
17751       if (unformat (i, "sw_if_index %d", &sw_if_index))
17752         ;
17753       else
17754         break;
17755     }
17756
17757   if (sw_if_index == ~0)
17758     {
17759       errmsg ("missing sw_if_index");
17760       return -99;
17761     }
17762
17763   /* Construct the API message */
17764   M (DELETE_SUBIF, mp);
17765   mp->sw_if_index = ntohl (sw_if_index);
17766
17767   S (mp);
17768   W (ret);
17769   return ret;
17770 }
17771
17772 #define foreach_pbb_vtr_op      \
17773 _("disable",  L2_VTR_DISABLED)  \
17774 _("pop",  L2_VTR_POP_2)         \
17775 _("push",  L2_VTR_PUSH_2)
17776
17777 static int
17778 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
17779 {
17780   unformat_input_t *i = vam->input;
17781   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
17782   u32 sw_if_index = ~0, vtr_op = ~0;
17783   u16 outer_tag = ~0;
17784   u8 dmac[6], smac[6];
17785   u8 dmac_set = 0, smac_set = 0;
17786   u16 vlanid = 0;
17787   u32 sid = ~0;
17788   u32 tmp;
17789   int ret;
17790
17791   /* Shut up coverity */
17792   memset (dmac, 0, sizeof (dmac));
17793   memset (smac, 0, sizeof (smac));
17794
17795   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17796     {
17797       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17798         ;
17799       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17800         ;
17801       else if (unformat (i, "vtr_op %d", &vtr_op))
17802         ;
17803 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
17804       foreach_pbb_vtr_op
17805 #undef _
17806         else if (unformat (i, "translate_pbb_stag"))
17807         {
17808           if (unformat (i, "%d", &tmp))
17809             {
17810               vtr_op = L2_VTR_TRANSLATE_2_1;
17811               outer_tag = tmp;
17812             }
17813           else
17814             {
17815               errmsg
17816                 ("translate_pbb_stag operation requires outer tag definition");
17817               return -99;
17818             }
17819         }
17820       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
17821         dmac_set++;
17822       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
17823         smac_set++;
17824       else if (unformat (i, "sid %d", &sid))
17825         ;
17826       else if (unformat (i, "vlanid %d", &tmp))
17827         vlanid = tmp;
17828       else
17829         {
17830           clib_warning ("parse error '%U'", format_unformat_error, i);
17831           return -99;
17832         }
17833     }
17834
17835   if ((sw_if_index == ~0) || (vtr_op == ~0))
17836     {
17837       errmsg ("missing sw_if_index or vtr operation");
17838       return -99;
17839     }
17840   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
17841       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
17842     {
17843       errmsg
17844         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
17845       return -99;
17846     }
17847
17848   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
17849   mp->sw_if_index = ntohl (sw_if_index);
17850   mp->vtr_op = ntohl (vtr_op);
17851   mp->outer_tag = ntohs (outer_tag);
17852   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
17853   clib_memcpy (mp->b_smac, smac, sizeof (smac));
17854   mp->b_vlanid = ntohs (vlanid);
17855   mp->i_sid = ntohl (sid);
17856
17857   S (mp);
17858   W (ret);
17859   return ret;
17860 }
17861
17862 static int
17863 api_flow_classify_set_interface (vat_main_t * vam)
17864 {
17865   unformat_input_t *i = vam->input;
17866   vl_api_flow_classify_set_interface_t *mp;
17867   u32 sw_if_index;
17868   int sw_if_index_set;
17869   u32 ip4_table_index = ~0;
17870   u32 ip6_table_index = ~0;
17871   u8 is_add = 1;
17872   int ret;
17873
17874   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17875     {
17876       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17877         sw_if_index_set = 1;
17878       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17879         sw_if_index_set = 1;
17880       else if (unformat (i, "del"))
17881         is_add = 0;
17882       else if (unformat (i, "ip4-table %d", &ip4_table_index))
17883         ;
17884       else if (unformat (i, "ip6-table %d", &ip6_table_index))
17885         ;
17886       else
17887         {
17888           clib_warning ("parse error '%U'", format_unformat_error, i);
17889           return -99;
17890         }
17891     }
17892
17893   if (sw_if_index_set == 0)
17894     {
17895       errmsg ("missing interface name or sw_if_index");
17896       return -99;
17897     }
17898
17899   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
17900
17901   mp->sw_if_index = ntohl (sw_if_index);
17902   mp->ip4_table_index = ntohl (ip4_table_index);
17903   mp->ip6_table_index = ntohl (ip6_table_index);
17904   mp->is_add = is_add;
17905
17906   S (mp);
17907   W (ret);
17908   return ret;
17909 }
17910
17911 static int
17912 api_flow_classify_dump (vat_main_t * vam)
17913 {
17914   unformat_input_t *i = vam->input;
17915   vl_api_flow_classify_dump_t *mp;
17916   vl_api_control_ping_t *mp_ping;
17917   u8 type = FLOW_CLASSIFY_N_TABLES;
17918   int ret;
17919
17920   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
17921     ;
17922   else
17923     {
17924       errmsg ("classify table type must be specified");
17925       return -99;
17926     }
17927
17928   if (!vam->json_output)
17929     {
17930       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
17931     }
17932
17933   M (FLOW_CLASSIFY_DUMP, mp);
17934   mp->type = type;
17935   /* send it... */
17936   S (mp);
17937
17938   /* Use a control ping for synchronization */
17939   M (CONTROL_PING, mp_ping);
17940   S (mp_ping);
17941
17942   /* Wait for a reply... */
17943   W (ret);
17944   return ret;
17945 }
17946
17947 static int
17948 api_feature_enable_disable (vat_main_t * vam)
17949 {
17950   unformat_input_t *i = vam->input;
17951   vl_api_feature_enable_disable_t *mp;
17952   u8 *arc_name = 0;
17953   u8 *feature_name = 0;
17954   u32 sw_if_index = ~0;
17955   u8 enable = 1;
17956   int ret;
17957
17958   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17959     {
17960       if (unformat (i, "arc_name %s", &arc_name))
17961         ;
17962       else if (unformat (i, "feature_name %s", &feature_name))
17963         ;
17964       else
17965         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17966         ;
17967       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17968         ;
17969       else if (unformat (i, "disable"))
17970         enable = 0;
17971       else
17972         break;
17973     }
17974
17975   if (arc_name == 0)
17976     {
17977       errmsg ("missing arc name");
17978       return -99;
17979     }
17980   if (vec_len (arc_name) > 63)
17981     {
17982       errmsg ("arc name too long");
17983     }
17984
17985   if (feature_name == 0)
17986     {
17987       errmsg ("missing feature name");
17988       return -99;
17989     }
17990   if (vec_len (feature_name) > 63)
17991     {
17992       errmsg ("feature name too long");
17993     }
17994
17995   if (sw_if_index == ~0)
17996     {
17997       errmsg ("missing interface name or sw_if_index");
17998       return -99;
17999     }
18000
18001   /* Construct the API message */
18002   M (FEATURE_ENABLE_DISABLE, mp);
18003   mp->sw_if_index = ntohl (sw_if_index);
18004   mp->enable = enable;
18005   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
18006   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
18007   vec_free (arc_name);
18008   vec_free (feature_name);
18009
18010   S (mp);
18011   W (ret);
18012   return ret;
18013 }
18014
18015 static int
18016 api_sw_interface_tag_add_del (vat_main_t * vam)
18017 {
18018   unformat_input_t *i = vam->input;
18019   vl_api_sw_interface_tag_add_del_t *mp;
18020   u32 sw_if_index = ~0;
18021   u8 *tag = 0;
18022   u8 enable = 1;
18023   int ret;
18024
18025   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18026     {
18027       if (unformat (i, "tag %s", &tag))
18028         ;
18029       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18030         ;
18031       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18032         ;
18033       else if (unformat (i, "del"))
18034         enable = 0;
18035       else
18036         break;
18037     }
18038
18039   if (sw_if_index == ~0)
18040     {
18041       errmsg ("missing interface name or sw_if_index");
18042       return -99;
18043     }
18044
18045   if (enable && (tag == 0))
18046     {
18047       errmsg ("no tag specified");
18048       return -99;
18049     }
18050
18051   /* Construct the API message */
18052   M (SW_INTERFACE_TAG_ADD_DEL, mp);
18053   mp->sw_if_index = ntohl (sw_if_index);
18054   mp->is_add = enable;
18055   if (enable)
18056     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
18057   vec_free (tag);
18058
18059   S (mp);
18060   W (ret);
18061   return ret;
18062 }
18063
18064 static void vl_api_l2_xconnect_details_t_handler
18065   (vl_api_l2_xconnect_details_t * mp)
18066 {
18067   vat_main_t *vam = &vat_main;
18068
18069   print (vam->ofp, "%15d%15d",
18070          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
18071 }
18072
18073 static void vl_api_l2_xconnect_details_t_handler_json
18074   (vl_api_l2_xconnect_details_t * mp)
18075 {
18076   vat_main_t *vam = &vat_main;
18077   vat_json_node_t *node = NULL;
18078
18079   if (VAT_JSON_ARRAY != vam->json_tree.type)
18080     {
18081       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18082       vat_json_init_array (&vam->json_tree);
18083     }
18084   node = vat_json_array_add (&vam->json_tree);
18085
18086   vat_json_init_object (node);
18087   vat_json_object_add_uint (node, "rx_sw_if_index",
18088                             ntohl (mp->rx_sw_if_index));
18089   vat_json_object_add_uint (node, "tx_sw_if_index",
18090                             ntohl (mp->tx_sw_if_index));
18091 }
18092
18093 static int
18094 api_l2_xconnect_dump (vat_main_t * vam)
18095 {
18096   vl_api_l2_xconnect_dump_t *mp;
18097   vl_api_control_ping_t *mp_ping;
18098   int ret;
18099
18100   if (!vam->json_output)
18101     {
18102       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
18103     }
18104
18105   M (L2_XCONNECT_DUMP, mp);
18106
18107   S (mp);
18108
18109   /* Use a control ping for synchronization */
18110   M (CONTROL_PING, mp_ping);
18111   S (mp_ping);
18112
18113   W (ret);
18114   return ret;
18115 }
18116
18117 static int
18118 api_sw_interface_set_mtu (vat_main_t * vam)
18119 {
18120   unformat_input_t *i = vam->input;
18121   vl_api_sw_interface_set_mtu_t *mp;
18122   u32 sw_if_index = ~0;
18123   u32 mtu = 0;
18124   int ret;
18125
18126   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18127     {
18128       if (unformat (i, "mtu %d", &mtu))
18129         ;
18130       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18131         ;
18132       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18133         ;
18134       else
18135         break;
18136     }
18137
18138   if (sw_if_index == ~0)
18139     {
18140       errmsg ("missing interface name or sw_if_index");
18141       return -99;
18142     }
18143
18144   if (mtu == 0)
18145     {
18146       errmsg ("no mtu specified");
18147       return -99;
18148     }
18149
18150   /* Construct the API message */
18151   M (SW_INTERFACE_SET_MTU, mp);
18152   mp->sw_if_index = ntohl (sw_if_index);
18153   mp->mtu = ntohs ((u16) mtu);
18154
18155   S (mp);
18156   W (ret);
18157   return ret;
18158 }
18159
18160
18161 static int
18162 q_or_quit (vat_main_t * vam)
18163 {
18164 #if VPP_API_TEST_BUILTIN == 0
18165   longjmp (vam->jump_buf, 1);
18166 #endif
18167   return 0;                     /* not so much */
18168 }
18169
18170 static int
18171 q (vat_main_t * vam)
18172 {
18173   return q_or_quit (vam);
18174 }
18175
18176 static int
18177 quit (vat_main_t * vam)
18178 {
18179   return q_or_quit (vam);
18180 }
18181
18182 static int
18183 comment (vat_main_t * vam)
18184 {
18185   return 0;
18186 }
18187
18188 static int
18189 cmd_cmp (void *a1, void *a2)
18190 {
18191   u8 **c1 = a1;
18192   u8 **c2 = a2;
18193
18194   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
18195 }
18196
18197 static int
18198 help (vat_main_t * vam)
18199 {
18200   u8 **cmds = 0;
18201   u8 *name = 0;
18202   hash_pair_t *p;
18203   unformat_input_t *i = vam->input;
18204   int j;
18205
18206   if (unformat (i, "%s", &name))
18207     {
18208       uword *hs;
18209
18210       vec_add1 (name, 0);
18211
18212       hs = hash_get_mem (vam->help_by_name, name);
18213       if (hs)
18214         print (vam->ofp, "usage: %s %s", name, hs[0]);
18215       else
18216         print (vam->ofp, "No such msg / command '%s'", name);
18217       vec_free (name);
18218       return 0;
18219     }
18220
18221   print (vam->ofp, "Help is available for the following:");
18222
18223     /* *INDENT-OFF* */
18224     hash_foreach_pair (p, vam->function_by_name,
18225     ({
18226       vec_add1 (cmds, (u8 *)(p->key));
18227     }));
18228     /* *INDENT-ON* */
18229
18230   vec_sort_with_function (cmds, cmd_cmp);
18231
18232   for (j = 0; j < vec_len (cmds); j++)
18233     print (vam->ofp, "%s", cmds[j]);
18234
18235   vec_free (cmds);
18236   return 0;
18237 }
18238
18239 static int
18240 set (vat_main_t * vam)
18241 {
18242   u8 *name = 0, *value = 0;
18243   unformat_input_t *i = vam->input;
18244
18245   if (unformat (i, "%s", &name))
18246     {
18247       /* The input buffer is a vector, not a string. */
18248       value = vec_dup (i->buffer);
18249       vec_delete (value, i->index, 0);
18250       /* Almost certainly has a trailing newline */
18251       if (value[vec_len (value) - 1] == '\n')
18252         value[vec_len (value) - 1] = 0;
18253       /* Make sure it's a proper string, one way or the other */
18254       vec_add1 (value, 0);
18255       (void) clib_macro_set_value (&vam->macro_main,
18256                                    (char *) name, (char *) value);
18257     }
18258   else
18259     errmsg ("usage: set <name> <value>");
18260
18261   vec_free (name);
18262   vec_free (value);
18263   return 0;
18264 }
18265
18266 static int
18267 unset (vat_main_t * vam)
18268 {
18269   u8 *name = 0;
18270
18271   if (unformat (vam->input, "%s", &name))
18272     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
18273       errmsg ("unset: %s wasn't set", name);
18274   vec_free (name);
18275   return 0;
18276 }
18277
18278 typedef struct
18279 {
18280   u8 *name;
18281   u8 *value;
18282 } macro_sort_t;
18283
18284
18285 static int
18286 macro_sort_cmp (void *a1, void *a2)
18287 {
18288   macro_sort_t *s1 = a1;
18289   macro_sort_t *s2 = a2;
18290
18291   return strcmp ((char *) (s1->name), (char *) (s2->name));
18292 }
18293
18294 static int
18295 dump_macro_table (vat_main_t * vam)
18296 {
18297   macro_sort_t *sort_me = 0, *sm;
18298   int i;
18299   hash_pair_t *p;
18300
18301     /* *INDENT-OFF* */
18302     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
18303     ({
18304       vec_add2 (sort_me, sm, 1);
18305       sm->name = (u8 *)(p->key);
18306       sm->value = (u8 *) (p->value[0]);
18307     }));
18308     /* *INDENT-ON* */
18309
18310   vec_sort_with_function (sort_me, macro_sort_cmp);
18311
18312   if (vec_len (sort_me))
18313     print (vam->ofp, "%-15s%s", "Name", "Value");
18314   else
18315     print (vam->ofp, "The macro table is empty...");
18316
18317   for (i = 0; i < vec_len (sort_me); i++)
18318     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
18319   return 0;
18320 }
18321
18322 static int
18323 dump_node_table (vat_main_t * vam)
18324 {
18325   int i, j;
18326   vlib_node_t *node, *next_node;
18327
18328   if (vec_len (vam->graph_nodes) == 0)
18329     {
18330       print (vam->ofp, "Node table empty, issue get_node_graph...");
18331       return 0;
18332     }
18333
18334   for (i = 0; i < vec_len (vam->graph_nodes); i++)
18335     {
18336       node = vam->graph_nodes[i];
18337       print (vam->ofp, "[%d] %s", i, node->name);
18338       for (j = 0; j < vec_len (node->next_nodes); j++)
18339         {
18340           if (node->next_nodes[j] != ~0)
18341             {
18342               next_node = vam->graph_nodes[node->next_nodes[j]];
18343               print (vam->ofp, "  [%d] %s", j, next_node->name);
18344             }
18345         }
18346     }
18347   return 0;
18348 }
18349
18350 static int
18351 value_sort_cmp (void *a1, void *a2)
18352 {
18353   name_sort_t *n1 = a1;
18354   name_sort_t *n2 = a2;
18355
18356   if (n1->value < n2->value)
18357     return -1;
18358   if (n1->value > n2->value)
18359     return 1;
18360   return 0;
18361 }
18362
18363
18364 static int
18365 dump_msg_api_table (vat_main_t * vam)
18366 {
18367   api_main_t *am = &api_main;
18368   name_sort_t *nses = 0, *ns;
18369   hash_pair_t *hp;
18370   int i;
18371
18372   /* *INDENT-OFF* */
18373   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
18374   ({
18375     vec_add2 (nses, ns, 1);
18376     ns->name = (u8 *)(hp->key);
18377     ns->value = (u32) hp->value[0];
18378   }));
18379   /* *INDENT-ON* */
18380
18381   vec_sort_with_function (nses, value_sort_cmp);
18382
18383   for (i = 0; i < vec_len (nses); i++)
18384     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
18385   vec_free (nses);
18386   return 0;
18387 }
18388
18389 static int
18390 get_msg_id (vat_main_t * vam)
18391 {
18392   u8 *name_and_crc;
18393   u32 message_index;
18394
18395   if (unformat (vam->input, "%s", &name_and_crc))
18396     {
18397       message_index = vl_api_get_msg_index (name_and_crc);
18398       if (message_index == ~0)
18399         {
18400           print (vam->ofp, " '%s' not found", name_and_crc);
18401           return 0;
18402         }
18403       print (vam->ofp, " '%s' has message index %d",
18404              name_and_crc, message_index);
18405       return 0;
18406     }
18407   errmsg ("name_and_crc required...");
18408   return 0;
18409 }
18410
18411 static int
18412 search_node_table (vat_main_t * vam)
18413 {
18414   unformat_input_t *line_input = vam->input;
18415   u8 *node_to_find;
18416   int j;
18417   vlib_node_t *node, *next_node;
18418   uword *p;
18419
18420   if (vam->graph_node_index_by_name == 0)
18421     {
18422       print (vam->ofp, "Node table empty, issue get_node_graph...");
18423       return 0;
18424     }
18425
18426   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
18427     {
18428       if (unformat (line_input, "%s", &node_to_find))
18429         {
18430           vec_add1 (node_to_find, 0);
18431           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
18432           if (p == 0)
18433             {
18434               print (vam->ofp, "%s not found...", node_to_find);
18435               goto out;
18436             }
18437           node = vam->graph_nodes[p[0]];
18438           print (vam->ofp, "[%d] %s", p[0], node->name);
18439           for (j = 0; j < vec_len (node->next_nodes); j++)
18440             {
18441               if (node->next_nodes[j] != ~0)
18442                 {
18443                   next_node = vam->graph_nodes[node->next_nodes[j]];
18444                   print (vam->ofp, "  [%d] %s", j, next_node->name);
18445                 }
18446             }
18447         }
18448
18449       else
18450         {
18451           clib_warning ("parse error '%U'", format_unformat_error,
18452                         line_input);
18453           return -99;
18454         }
18455
18456     out:
18457       vec_free (node_to_find);
18458
18459     }
18460
18461   return 0;
18462 }
18463
18464
18465 static int
18466 script (vat_main_t * vam)
18467 {
18468 #if (VPP_API_TEST_BUILTIN==0)
18469   u8 *s = 0;
18470   char *save_current_file;
18471   unformat_input_t save_input;
18472   jmp_buf save_jump_buf;
18473   u32 save_line_number;
18474
18475   FILE *new_fp, *save_ifp;
18476
18477   if (unformat (vam->input, "%s", &s))
18478     {
18479       new_fp = fopen ((char *) s, "r");
18480       if (new_fp == 0)
18481         {
18482           errmsg ("Couldn't open script file %s", s);
18483           vec_free (s);
18484           return -99;
18485         }
18486     }
18487   else
18488     {
18489       errmsg ("Missing script name");
18490       return -99;
18491     }
18492
18493   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
18494   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
18495   save_ifp = vam->ifp;
18496   save_line_number = vam->input_line_number;
18497   save_current_file = (char *) vam->current_file;
18498
18499   vam->input_line_number = 0;
18500   vam->ifp = new_fp;
18501   vam->current_file = s;
18502   do_one_file (vam);
18503
18504   clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
18505   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
18506   vam->ifp = save_ifp;
18507   vam->input_line_number = save_line_number;
18508   vam->current_file = (u8 *) save_current_file;
18509   vec_free (s);
18510
18511   return 0;
18512 #else
18513   clib_warning ("use the exec command...");
18514   return -99;
18515 #endif
18516 }
18517
18518 static int
18519 echo (vat_main_t * vam)
18520 {
18521   print (vam->ofp, "%v", vam->input->buffer);
18522   return 0;
18523 }
18524
18525 /* List of API message constructors, CLI names map to api_xxx */
18526 #define foreach_vpe_api_msg                                             \
18527 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
18528 _(sw_interface_dump,"")                                                 \
18529 _(sw_interface_set_flags,                                               \
18530   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
18531 _(sw_interface_add_del_address,                                         \
18532   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
18533 _(sw_interface_set_table,                                               \
18534   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
18535 _(sw_interface_set_mpls_enable,                                         \
18536   "<intfc> | sw_if_index [disable | dis]")                              \
18537 _(sw_interface_set_vpath,                                               \
18538   "<intfc> | sw_if_index <id> enable | disable")                        \
18539 _(sw_interface_set_vxlan_bypass,                                        \
18540   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
18541 _(sw_interface_set_l2_xconnect,                                         \
18542   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
18543   "enable | disable")                                                   \
18544 _(sw_interface_set_l2_bridge,                                           \
18545   "<intfc> | sw_if_index <id> bd_id <bridge-domain-id>\n"               \
18546   "[shg <split-horizon-group>] [bvi]\n"                                 \
18547   "enable | disable")                                                   \
18548 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255\n")\
18549 _(bridge_domain_add_del,                                                \
18550   "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") \
18551 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
18552 _(l2fib_add_del,                                                        \
18553   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
18554 _(l2_flags,                                                             \
18555   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood]\n") \
18556 _(bridge_flags,                                                         \
18557   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
18558 _(tap_connect,                                                          \
18559   "tapname <name> mac <mac-addr> | random-mac [tag <string>]")          \
18560 _(tap_modify,                                                           \
18561   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
18562 _(tap_delete,                                                           \
18563   "<vpp-if-name> | sw_if_index <id>")                                   \
18564 _(sw_interface_tap_dump, "")                                            \
18565 _(ip_add_del_route,                                                     \
18566   "<addr>/<mask> via <addr> [table-id <n>]\n"                           \
18567   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
18568   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
18569   "[multipath] [count <n>]")                                            \
18570 _(ip_mroute_add_del,                                                    \
18571   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
18572   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
18573 _(mpls_route_add_del,                                                   \
18574   "<label> <eos> via <addr> [table-id <n>]\n"                           \
18575   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
18576   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
18577   "[multipath] [count <n>]")                                            \
18578 _(mpls_ip_bind_unbind,                                                  \
18579   "<label> <addr/len>")                                                 \
18580 _(mpls_tunnel_add_del,                                                  \
18581   " via <addr> [table-id <n>]\n"                                        \
18582   "sw_if_index <id>] [l2]  [del]")                                      \
18583 _(proxy_arp_add_del,                                                    \
18584   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
18585 _(proxy_arp_intfc_enable_disable,                                       \
18586   "<intfc> | sw_if_index <id> enable | disable")                        \
18587 _(sw_interface_set_unnumbered,                                          \
18588   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
18589 _(ip_neighbor_add_del,                                                  \
18590   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
18591   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
18592 _(reset_vrf, "vrf <id> [ipv6]")                                         \
18593 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
18594 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
18595   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
18596   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
18597   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
18598 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
18599 _(reset_fib, "vrf <n> [ipv6]")                                          \
18600 _(dhcp_proxy_config,                                                    \
18601   "svr <v46-address> src <v46-address>\n"                               \
18602    "rx_vrf_id <nn> server_vrf_id <nn>  [del]")                          \
18603 _(dhcp_proxy_set_vss,                                                   \
18604   "tbl_id <n> fib_id <n> oui <n> [ipv6] [del]")                         \
18605 _(dhcp_proxy_dump, "ip6")                                               \
18606 _(dhcp_client_config,                                                   \
18607   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
18608 _(set_ip_flow_hash,                                                     \
18609   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
18610 _(sw_interface_ip6_enable_disable,                                      \
18611   "<intfc> | sw_if_index <id> enable | disable")                        \
18612 _(sw_interface_ip6_set_link_local_address,                              \
18613   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
18614 _(ip6nd_proxy_add_del,                                                  \
18615   "<intfc> | sw_if_index <id> <ip6-address>")                           \
18616 _(ip6nd_proxy_dump, "")                                                 \
18617 _(sw_interface_ip6nd_ra_prefix,                                         \
18618   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
18619   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
18620   "[nolink] [isno]")                                                    \
18621 _(sw_interface_ip6nd_ra_config,                                         \
18622   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
18623   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
18624   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
18625 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
18626 _(l2_patch_add_del,                                                     \
18627   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
18628   "enable | disable")                                                   \
18629 _(sr_localsid_add_del,                                                  \
18630   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
18631   "fib-table <num> (end.psp) sw_if_index <num>")                        \
18632 _(classify_add_del_table,                                               \
18633   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
18634   " [del] [del-chain] mask <mask-value>\n"                              \
18635   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
18636   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
18637 _(classify_add_del_session,                                             \
18638   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
18639   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
18640   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
18641   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
18642 _(classify_set_interface_ip_table,                                      \
18643   "<intfc> | sw_if_index <nn> table <nn>")                              \
18644 _(classify_set_interface_l2_tables,                                     \
18645   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
18646   "  [other-table <nn>]")                                               \
18647 _(get_node_index, "node <node-name")                                    \
18648 _(add_node_next, "node <node-name> next <next-node-name>")              \
18649 _(l2tpv3_create_tunnel,                                                 \
18650   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
18651   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
18652   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
18653 _(l2tpv3_set_tunnel_cookies,                                            \
18654   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
18655   "[new_remote_cookie <nn>]\n")                                         \
18656 _(l2tpv3_interface_enable_disable,                                      \
18657   "<intfc> | sw_if_index <nn> enable | disable")                        \
18658 _(l2tpv3_set_lookup_key,                                                \
18659   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
18660 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
18661 _(vxlan_add_del_tunnel,                                                 \
18662   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
18663   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
18664   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
18665 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
18666 _(gre_add_del_tunnel,                                                   \
18667   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [teb] [del]\n")    \
18668 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
18669 _(l2_fib_clear_table, "")                                               \
18670 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
18671 _(l2_interface_vlan_tag_rewrite,                                        \
18672   "<intfc> | sw_if_index <nn> \n"                                       \
18673   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
18674   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
18675 _(create_vhost_user_if,                                                 \
18676         "socket <filename> [server] [renumber <dev_instance>] "         \
18677         "[mac <mac_address>] "                                          \
18678         "[mode <interrupt | polling>]")                                 \
18679 _(modify_vhost_user_if,                                                 \
18680         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
18681         "[server] [renumber <dev_instance>] "                           \
18682         "[mode <interrupt | polling>]")                                 \
18683 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
18684 _(sw_interface_vhost_user_dump, "")                                     \
18685 _(show_version, "")                                                     \
18686 _(vxlan_gpe_add_del_tunnel,                                             \
18687   "local <addr> remote <addr> vni <nn>\n"                               \
18688     "[encap-vrf-id <nn>] [decap-vrf-id <nn>] [next-ip4][next-ip6]"      \
18689   "[next-ethernet] [next-nsh]\n")                                       \
18690 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
18691 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
18692 _(interface_name_renumber,                                              \
18693   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
18694 _(input_acl_set_interface,                                              \
18695   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
18696   "  [l2-table <nn>] [del]")                                            \
18697 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
18698 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
18699 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
18700 _(ip_dump, "ipv4 | ipv6")                                               \
18701 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
18702 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
18703   "  spid_id <n> ")                                                     \
18704 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
18705   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
18706   "  integ_alg <alg> integ_key <hex>")                                  \
18707 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
18708   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
18709   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
18710   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
18711 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
18712 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
18713 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
18714   "(auth_data 0x<data> | auth_data <data>)")                            \
18715 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
18716   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
18717 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
18718   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
18719   "(local|remote)")                                                     \
18720 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
18721 _(ikev2_set_responder, "<profile_name> interface <interface> address <addr>") \
18722 _(ikev2_set_ike_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
18723 _(ikev2_set_esp_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
18724 _(ikev2_set_sa_lifetime, "<profile_name> <seconds> <jitter> <handover> <max bytes>") \
18725 _(ikev2_initiate_sa_init, "<profile_name>")                             \
18726 _(ikev2_initiate_del_ike_sa, "<ispi>")                                  \
18727 _(ikev2_initiate_del_child_sa, "<ispi>")                                \
18728 _(ikev2_initiate_rekey_child_sa, "<ispi>")                              \
18729 _(delete_loopback,"sw_if_index <nn>")                                   \
18730 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
18731 _(map_add_domain,                                                       \
18732   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
18733   "ip6-src <ip6addr> "                                                  \
18734   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
18735 _(map_del_domain, "index <n>")                                          \
18736 _(map_add_del_rule,                                                     \
18737   "index <n> psid <n> dst <ip6addr> [del]")                             \
18738 _(map_domain_dump, "")                                                  \
18739 _(map_rule_dump, "index <map-domain>")                                  \
18740 _(want_interface_events,  "enable|disable")                             \
18741 _(want_stats,"enable|disable")                                          \
18742 _(get_first_msg_id, "client <name>")                                    \
18743 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
18744 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
18745   "fib-id <nn> [ip4][ip6][default]")                                    \
18746 _(get_node_graph, " ")                                                  \
18747 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
18748 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
18749 _(ioam_disable, "")                                                     \
18750 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
18751                             " sw_if_index <sw_if_index> p <priority> "  \
18752                             "w <weight>] [del]")                        \
18753 _(one_add_del_locator, "locator-set <locator_name> "                    \
18754                         "iface <intf> | sw_if_index <sw_if_index> "     \
18755                         "p <priority> w <weight> [del]")                \
18756 _(one_add_del_local_eid,"vni <vni> eid "                                \
18757                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
18758                          "locator-set <locator_name> [del]"             \
18759                          "[key-id sha1|sha256 secret-key <secret-key>]")\
18760 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
18761 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
18762 _(one_enable_disable, "enable|disable")                                 \
18763 _(one_map_register_enable_disable, "enable|disable")                    \
18764 _(one_rloc_probe_enable_disable, "enable|disable")                      \
18765 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
18766                                "[seid <seid>] "                         \
18767                                "rloc <locator> p <prio> "               \
18768                                "w <weight> [rloc <loc> ... ] "          \
18769                                "action <action> [del-all]")             \
18770 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
18771                           "<local-eid>")                                \
18772 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
18773 _(one_use_petr, "ip-address> | disable")                                \
18774 _(one_map_request_mode, "src-dst|dst-only")                             \
18775 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
18776 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
18777 _(one_locator_set_dump, "[local | remote]")                             \
18778 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
18779 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
18780                        "[local] | [remote]")                            \
18781 _(one_stats_enable_disable, "enable|disalbe")                           \
18782 _(show_one_stats_enable_disable, "")                                    \
18783 _(one_eid_table_vni_dump, "")                                           \
18784 _(one_eid_table_map_dump, "l2|l3")                                      \
18785 _(one_map_resolver_dump, "")                                            \
18786 _(one_map_server_dump, "")                                              \
18787 _(one_adjacencies_get, "vni <vni>")                                     \
18788 _(show_one_rloc_probe_state, "")                                        \
18789 _(show_one_map_register_state, "")                                      \
18790 _(show_one_status, "")                                                  \
18791 _(one_stats_dump, "")                                                   \
18792 _(one_get_map_request_itr_rlocs, "")                                    \
18793 _(show_one_pitr, "")                                                    \
18794 _(show_one_use_petr, "")                                                \
18795 _(show_one_map_request_mode, "")                                        \
18796 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
18797                             " sw_if_index <sw_if_index> p <priority> "  \
18798                             "w <weight>] [del]")                        \
18799 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
18800                         "iface <intf> | sw_if_index <sw_if_index> "     \
18801                         "p <priority> w <weight> [del]")                \
18802 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
18803                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
18804                          "locator-set <locator_name> [del]"             \
18805                          "[key-id sha1|sha256 secret-key <secret-key>]") \
18806 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
18807 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
18808 _(lisp_enable_disable, "enable|disable")                                \
18809 _(lisp_map_register_enable_disable, "enable|disable")                   \
18810 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
18811 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
18812                                "[seid <seid>] "                         \
18813                                "rloc <locator> p <prio> "               \
18814                                "w <weight> [rloc <loc> ... ] "          \
18815                                "action <action> [del-all]")             \
18816 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
18817                           "<local-eid>")                                \
18818 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
18819 _(lisp_use_petr, "<ip-address> | disable")                              \
18820 _(lisp_map_request_mode, "src-dst|dst-only")                            \
18821 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
18822 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
18823 _(lisp_locator_set_dump, "[local | remote]")                            \
18824 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
18825 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
18826                        "[local] | [remote]")                            \
18827 _(lisp_eid_table_vni_dump, "")                                          \
18828 _(lisp_eid_table_map_dump, "l2|l3")                                     \
18829 _(lisp_map_resolver_dump, "")                                           \
18830 _(lisp_map_server_dump, "")                                             \
18831 _(lisp_adjacencies_get, "vni <vni>")                                    \
18832 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
18833 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
18834 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
18835 _(gpe_get_encap_mode, "")                                               \
18836 _(lisp_gpe_add_del_iface, "up|down")                                    \
18837 _(lisp_gpe_enable_disable, "enable|disable")                            \
18838 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
18839   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
18840 _(show_lisp_rloc_probe_state, "")                                       \
18841 _(show_lisp_map_register_state, "")                                     \
18842 _(show_lisp_status, "")                                                 \
18843 _(lisp_get_map_request_itr_rlocs, "")                                   \
18844 _(show_lisp_pitr, "")                                                   \
18845 _(show_lisp_use_petr, "")                                               \
18846 _(show_lisp_map_request_mode, "")                                       \
18847 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
18848 _(af_packet_delete, "name <host interface name>")                       \
18849 _(policer_add_del, "name <policer name> <params> [del]")                \
18850 _(policer_dump, "[name <policer name>]")                                \
18851 _(policer_classify_set_interface,                                       \
18852   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
18853   "  [l2-table <nn>] [del]")                                            \
18854 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
18855 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
18856     "[master|slave]")                                                   \
18857 _(netmap_delete, "name <interface name>")                               \
18858 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
18859 _(mpls_fib_dump, "")                                                    \
18860 _(classify_table_ids, "")                                               \
18861 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
18862 _(classify_table_info, "table_id <nn>")                                 \
18863 _(classify_session_dump, "table_id <nn>")                               \
18864 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
18865     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
18866     "[template_interval <nn>] [udp_checksum]")                          \
18867 _(ipfix_exporter_dump, "")                                              \
18868 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
18869 _(ipfix_classify_stream_dump, "")                                       \
18870 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
18871 _(ipfix_classify_table_dump, "")                                        \
18872 _(sw_interface_span_enable_disable, "[src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
18873 _(sw_interface_span_dump, "")                                           \
18874 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
18875 _(pg_create_interface, "if_id <nn>")                                    \
18876 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
18877 _(pg_enable_disable, "[stream <id>] disable")                           \
18878 _(ip_source_and_port_range_check_add_del,                               \
18879   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
18880 _(ip_source_and_port_range_check_interface_add_del,                     \
18881   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
18882   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
18883 _(ipsec_gre_add_del_tunnel,                                             \
18884   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
18885 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
18886 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
18887 _(l2_interface_pbb_tag_rewrite,                                         \
18888   "<intfc> | sw_if_index <nn> \n"                                       \
18889   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
18890   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
18891 _(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
18892 _(flow_classify_set_interface,                                          \
18893   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
18894 _(flow_classify_dump, "type [ip4|ip6]")                                 \
18895 _(ip_fib_dump, "")                                                      \
18896 _(ip_mfib_dump, "")                                                     \
18897 _(ip6_fib_dump, "")                                                     \
18898 _(ip6_mfib_dump, "")                                                    \
18899 _(feature_enable_disable, "arc_name <arc_name> "                        \
18900   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
18901 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
18902 "[disable]")                                                            \
18903 _(l2_xconnect_dump, "")                                                 \
18904 _(sw_interface_set_mtu, "<intfc> | sw_if_index <nn> mtu <nn>")        \
18905 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
18906 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")
18907
18908 /* List of command functions, CLI names map directly to functions */
18909 #define foreach_cli_function                                    \
18910 _(comment, "usage: comment <ignore-rest-of-line>")              \
18911 _(dump_interface_table, "usage: dump_interface_table")          \
18912 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
18913 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
18914 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
18915 _(dump_stats_table, "usage: dump_stats_table")                  \
18916 _(dump_macro_table, "usage: dump_macro_table ")                 \
18917 _(dump_node_table, "usage: dump_node_table")                    \
18918 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
18919 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
18920 _(echo, "usage: echo <message>")                                \
18921 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
18922 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
18923 _(help, "usage: help")                                          \
18924 _(q, "usage: quit")                                             \
18925 _(quit, "usage: quit")                                          \
18926 _(search_node_table, "usage: search_node_table <name>...")      \
18927 _(set, "usage: set <variable-name> <value>")                    \
18928 _(script, "usage: script <file-name>")                          \
18929 _(unset, "usage: unset <variable-name>")
18930
18931 #define _(N,n)                                  \
18932     static void vl_api_##n##_t_handler_uni      \
18933     (vl_api_##n##_t * mp)                       \
18934     {                                           \
18935         vat_main_t * vam = &vat_main;           \
18936         if (vam->json_output) {                 \
18937             vl_api_##n##_t_handler_json(mp);    \
18938         } else {                                \
18939             vl_api_##n##_t_handler(mp);         \
18940         }                                       \
18941     }
18942 foreach_vpe_api_reply_msg;
18943 #if VPP_API_TEST_BUILTIN == 0
18944 foreach_standalone_reply_msg;
18945 #endif
18946 #undef _
18947
18948 void
18949 vat_api_hookup (vat_main_t * vam)
18950 {
18951 #define _(N,n)                                                  \
18952     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
18953                            vl_api_##n##_t_handler_uni,          \
18954                            vl_noop_handler,                     \
18955                            vl_api_##n##_t_endian,               \
18956                            vl_api_##n##_t_print,                \
18957                            sizeof(vl_api_##n##_t), 1);
18958   foreach_vpe_api_reply_msg;
18959 #if VPP_API_TEST_BUILTIN == 0
18960   foreach_standalone_reply_msg;
18961 #endif
18962 #undef _
18963
18964 #if (VPP_API_TEST_BUILTIN==0)
18965   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
18966
18967   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
18968
18969   vam->function_by_name = hash_create_string (0, sizeof (uword));
18970
18971   vam->help_by_name = hash_create_string (0, sizeof (uword));
18972 #endif
18973
18974   /* API messages we can send */
18975 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
18976   foreach_vpe_api_msg;
18977 #undef _
18978
18979   /* Help strings */
18980 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
18981   foreach_vpe_api_msg;
18982 #undef _
18983
18984   /* CLI functions */
18985 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
18986   foreach_cli_function;
18987 #undef _
18988
18989   /* Help strings */
18990 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
18991   foreach_cli_function;
18992 #undef _
18993 }
18994
18995 #if VPP_API_TEST_BUILTIN
18996 static clib_error_t *
18997 vat_api_hookup_shim (vlib_main_t * vm)
18998 {
18999   vat_api_hookup (&vat_main);
19000   return 0;
19001 }
19002
19003 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
19004 #endif
19005
19006 /*
19007  * fd.io coding-style-patch-verification: ON
19008  *
19009  * Local Variables:
19010  * eval: (c-set-style "gnu")
19011  * End:
19012  */