Add VAT handlers for LISP-GPE API
[vpp.git] / src / vat / api_format.c
1 /*
2  *------------------------------------------------------------------
3  * api_format.c
4  *
5  * Copyright (c) 2014-2016 Cisco and/or its affiliates.
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at:
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *------------------------------------------------------------------
18  */
19
20 #include <vat/vat.h>
21 #include <vlibapi/api.h>
22 #include <vlibmemory/api.h>
23 #include <vlibsocket/api.h>
24 #include <vnet/ip/ip.h>
25 #include <vnet/l2/l2_input.h>
26 #include <vnet/l2tp/l2tp.h>
27 #include <vnet/vxlan/vxlan.h>
28 #include <vnet/gre/gre.h>
29 #include <vnet/vxlan-gpe/vxlan_gpe.h>
30 #include <vnet/lisp-gpe/lisp_gpe.h>
31
32 #include <vpp/api/vpe_msg_enum.h>
33 #include <vnet/l2/l2_classify.h>
34 #include <vnet/l2/l2_vtr.h>
35 #include <vnet/classify/input_acl.h>
36 #include <vnet/classify/policer_classify.h>
37 #include <vnet/classify/flow_classify.h>
38 #include <vnet/mpls/mpls.h>
39 #include <vnet/ipsec/ipsec.h>
40 #include <vnet/ipsec/ikev2.h>
41 #include <inttypes.h>
42 #include <vnet/map/map.h>
43 #include <vnet/cop/cop.h>
44 #include <vnet/ip/ip6_hop_by_hop.h>
45 #include <vnet/ip/ip_source_and_port_range_check.h>
46 #include <vnet/policer/xlate.h>
47 #include <vnet/span/span.h>
48 #include <vnet/policer/policer.h>
49 #include <vnet/policer/police.h>
50 #include <vnet/mfib/mfib_types.h>
51
52 #include "vat/json_format.h"
53
54 #include <inttypes.h>
55 #include <sys/stat.h>
56
57 #define vl_typedefs             /* define message structures */
58 #include <vpp/api/vpe_all_api_h.h>
59 #undef vl_typedefs
60
61 /* declare message handlers for each api */
62
63 #define vl_endianfun            /* define message structures */
64 #include <vpp/api/vpe_all_api_h.h>
65 #undef vl_endianfun
66
67 /* instantiate all the print functions we know about */
68 #define vl_print(handle, ...)
69 #define vl_printfun
70 #include <vpp/api/vpe_all_api_h.h>
71 #undef vl_printfun
72
73 #define __plugin_msg_base 0
74 #include <vlibapi/vat_helper_macros.h>
75
76 f64
77 vat_time_now (vat_main_t * vam)
78 {
79 #if VPP_API_TEST_BUILTIN
80   return vlib_time_now (vam->vlib_main);
81 #else
82   return clib_time_now (&vam->clib_time);
83 #endif
84 }
85
86 void
87 errmsg (char *fmt, ...)
88 {
89   vat_main_t *vam = &vat_main;
90   va_list va;
91   u8 *s;
92
93   va_start (va, fmt);
94   s = va_format (0, fmt, &va);
95   va_end (va);
96
97   vec_add1 (s, 0);
98
99 #if VPP_API_TEST_BUILTIN
100   vlib_cli_output (vam->vlib_main, (char *) s);
101 #else
102   {
103     if (vam->ifp != stdin)
104       fformat (vam->ofp, "%s(%d): \n", vam->current_file,
105                vam->input_line_number);
106     fformat (vam->ofp, (char *) s);
107     fflush (vam->ofp);
108   }
109 #endif
110
111   vec_free (s);
112 }
113
114 #if VPP_API_TEST_BUILTIN == 0
115 static uword
116 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
117 {
118   vat_main_t *vam = va_arg (*args, vat_main_t *);
119   u32 *result = va_arg (*args, u32 *);
120   u8 *if_name;
121   uword *p;
122
123   if (!unformat (input, "%s", &if_name))
124     return 0;
125
126   p = hash_get_mem (vam->sw_if_index_by_interface_name, if_name);
127   if (p == 0)
128     return 0;
129   *result = p[0];
130   return 1;
131 }
132
133 /* Parse an IP4 address %d.%d.%d.%d. */
134 uword
135 unformat_ip4_address (unformat_input_t * input, va_list * args)
136 {
137   u8 *result = va_arg (*args, u8 *);
138   unsigned a[4];
139
140   if (!unformat (input, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]))
141     return 0;
142
143   if (a[0] >= 256 || a[1] >= 256 || a[2] >= 256 || a[3] >= 256)
144     return 0;
145
146   result[0] = a[0];
147   result[1] = a[1];
148   result[2] = a[2];
149   result[3] = a[3];
150
151   return 1;
152 }
153
154 uword
155 unformat_ethernet_address (unformat_input_t * input, va_list * args)
156 {
157   u8 *result = va_arg (*args, u8 *);
158   u32 i, a[6];
159
160   if (!unformat (input, "%_%x:%x:%x:%x:%x:%x%_",
161                  &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]))
162     return 0;
163
164   /* Check range. */
165   for (i = 0; i < 6; i++)
166     if (a[i] >= (1 << 8))
167       return 0;
168
169   for (i = 0; i < 6; i++)
170     result[i] = a[i];
171
172   return 1;
173 }
174
175 /* Returns ethernet type as an int in host byte order. */
176 uword
177 unformat_ethernet_type_host_byte_order (unformat_input_t * input,
178                                         va_list * args)
179 {
180   u16 *result = va_arg (*args, u16 *);
181   int type;
182
183   /* Numeric type. */
184   if (unformat (input, "0x%x", &type) || unformat (input, "%d", &type))
185     {
186       if (type >= (1 << 16))
187         return 0;
188       *result = type;
189       return 1;
190     }
191   return 0;
192 }
193
194 /* Parse an IP6 address. */
195 uword
196 unformat_ip6_address (unformat_input_t * input, va_list * args)
197 {
198   ip6_address_t *result = va_arg (*args, ip6_address_t *);
199   u16 hex_quads[8];
200   uword hex_quad, n_hex_quads, hex_digit, n_hex_digits;
201   uword c, n_colon, double_colon_index;
202
203   n_hex_quads = hex_quad = n_hex_digits = n_colon = 0;
204   double_colon_index = ARRAY_LEN (hex_quads);
205   while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
206     {
207       hex_digit = 16;
208       if (c >= '0' && c <= '9')
209         hex_digit = c - '0';
210       else if (c >= 'a' && c <= 'f')
211         hex_digit = c + 10 - 'a';
212       else if (c >= 'A' && c <= 'F')
213         hex_digit = c + 10 - 'A';
214       else if (c == ':' && n_colon < 2)
215         n_colon++;
216       else
217         {
218           unformat_put_input (input);
219           break;
220         }
221
222       /* Too many hex quads. */
223       if (n_hex_quads >= ARRAY_LEN (hex_quads))
224         return 0;
225
226       if (hex_digit < 16)
227         {
228           hex_quad = (hex_quad << 4) | hex_digit;
229
230           /* Hex quad must fit in 16 bits. */
231           if (n_hex_digits >= 4)
232             return 0;
233
234           n_colon = 0;
235           n_hex_digits++;
236         }
237
238       /* Save position of :: */
239       if (n_colon == 2)
240         {
241           /* More than one :: ? */
242           if (double_colon_index < ARRAY_LEN (hex_quads))
243             return 0;
244           double_colon_index = n_hex_quads;
245         }
246
247       if (n_colon > 0 && n_hex_digits > 0)
248         {
249           hex_quads[n_hex_quads++] = hex_quad;
250           hex_quad = 0;
251           n_hex_digits = 0;
252         }
253     }
254
255   if (n_hex_digits > 0)
256     hex_quads[n_hex_quads++] = hex_quad;
257
258   {
259     word i;
260
261     /* Expand :: to appropriate number of zero hex quads. */
262     if (double_colon_index < ARRAY_LEN (hex_quads))
263       {
264         word n_zero = ARRAY_LEN (hex_quads) - n_hex_quads;
265
266         for (i = n_hex_quads - 1; i >= (signed) double_colon_index; i--)
267           hex_quads[n_zero + i] = hex_quads[i];
268
269         for (i = 0; i < n_zero; i++)
270           hex_quads[double_colon_index + i] = 0;
271
272         n_hex_quads = ARRAY_LEN (hex_quads);
273       }
274
275     /* Too few hex quads given. */
276     if (n_hex_quads < ARRAY_LEN (hex_quads))
277       return 0;
278
279     for (i = 0; i < ARRAY_LEN (hex_quads); i++)
280       result->as_u16[i] = clib_host_to_net_u16 (hex_quads[i]);
281
282     return 1;
283   }
284 }
285
286 uword
287 unformat_ipsec_policy_action (unformat_input_t * input, va_list * args)
288 {
289   u32 *r = va_arg (*args, u32 *);
290
291   if (0);
292 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f;
293   foreach_ipsec_policy_action
294 #undef _
295     else
296     return 0;
297   return 1;
298 }
299
300 uword
301 unformat_ipsec_crypto_alg (unformat_input_t * input, va_list * args)
302 {
303   u32 *r = va_arg (*args, u32 *);
304
305   if (0);
306 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_CRYPTO_ALG_##f;
307   foreach_ipsec_crypto_alg
308 #undef _
309     else
310     return 0;
311   return 1;
312 }
313
314 u8 *
315 format_ipsec_crypto_alg (u8 * s, va_list * args)
316 {
317   u32 i = va_arg (*args, u32);
318   u8 *t = 0;
319
320   switch (i)
321     {
322 #define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break;
323       foreach_ipsec_crypto_alg
324 #undef _
325     default:
326       return format (s, "unknown");
327     }
328   return format (s, "%s", t);
329 }
330
331 uword
332 unformat_ipsec_integ_alg (unformat_input_t * input, va_list * args)
333 {
334   u32 *r = va_arg (*args, u32 *);
335
336   if (0);
337 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_INTEG_ALG_##f;
338   foreach_ipsec_integ_alg
339 #undef _
340     else
341     return 0;
342   return 1;
343 }
344
345 u8 *
346 format_ipsec_integ_alg (u8 * s, va_list * args)
347 {
348   u32 i = va_arg (*args, u32);
349   u8 *t = 0;
350
351   switch (i)
352     {
353 #define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
354       foreach_ipsec_integ_alg
355 #undef _
356     default:
357       return format (s, "unknown");
358     }
359   return format (s, "%s", t);
360 }
361
362 uword
363 unformat_ikev2_auth_method (unformat_input_t * input, va_list * args)
364 {
365   u32 *r = va_arg (*args, u32 *);
366
367   if (0);
368 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_AUTH_METHOD_##f;
369   foreach_ikev2_auth_method
370 #undef _
371     else
372     return 0;
373   return 1;
374 }
375
376 uword
377 unformat_ikev2_id_type (unformat_input_t * input, va_list * args)
378 {
379   u32 *r = va_arg (*args, u32 *);
380
381   if (0);
382 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_ID_TYPE_##f;
383   foreach_ikev2_id_type
384 #undef _
385     else
386     return 0;
387   return 1;
388 }
389 #else /* VPP_API_TEST_BUILTIN == 1 */
390 static uword
391 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
392 {
393   vat_main_t *vam __attribute__ ((unused)) = va_arg (*args, vat_main_t *);
394   vnet_main_t *vnm = vnet_get_main ();
395   u32 *result = va_arg (*args, u32 *);
396   u32 sw_if_index;
397
398   if (!unformat (input, "%U", unformat_vnet_sw_interface, vnm, &sw_if_index))
399     return 0;
400
401   *result = sw_if_index;
402   return 1;
403 }
404 #endif /* VPP_API_TEST_BUILTIN */
405
406 static uword
407 unformat_policer_rate_type (unformat_input_t * input, va_list * args)
408 {
409   u8 *r = va_arg (*args, u8 *);
410
411   if (unformat (input, "kbps"))
412     *r = SSE2_QOS_RATE_KBPS;
413   else if (unformat (input, "pps"))
414     *r = SSE2_QOS_RATE_PPS;
415   else
416     return 0;
417   return 1;
418 }
419
420 static uword
421 unformat_policer_round_type (unformat_input_t * input, va_list * args)
422 {
423   u8 *r = va_arg (*args, u8 *);
424
425   if (unformat (input, "closest"))
426     *r = SSE2_QOS_ROUND_TO_CLOSEST;
427   else if (unformat (input, "up"))
428     *r = SSE2_QOS_ROUND_TO_UP;
429   else if (unformat (input, "down"))
430     *r = SSE2_QOS_ROUND_TO_DOWN;
431   else
432     return 0;
433   return 1;
434 }
435
436 static uword
437 unformat_policer_type (unformat_input_t * input, va_list * args)
438 {
439   u8 *r = va_arg (*args, u8 *);
440
441   if (unformat (input, "1r2c"))
442     *r = SSE2_QOS_POLICER_TYPE_1R2C;
443   else if (unformat (input, "1r3c"))
444     *r = SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697;
445   else if (unformat (input, "2r3c-2698"))
446     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698;
447   else if (unformat (input, "2r3c-4115"))
448     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115;
449   else if (unformat (input, "2r3c-mef5cf1"))
450     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
451   else
452     return 0;
453   return 1;
454 }
455
456 static uword
457 unformat_dscp (unformat_input_t * input, va_list * va)
458 {
459   u8 *r = va_arg (*va, u8 *);
460
461   if (0);
462 #define _(v,f,str) else if (unformat (input, str)) *r = VNET_DSCP_##f;
463   foreach_vnet_dscp
464 #undef _
465     else
466     return 0;
467   return 1;
468 }
469
470 static uword
471 unformat_policer_action_type (unformat_input_t * input, va_list * va)
472 {
473   sse2_qos_pol_action_params_st *a
474     = va_arg (*va, sse2_qos_pol_action_params_st *);
475
476   if (unformat (input, "drop"))
477     a->action_type = SSE2_QOS_ACTION_DROP;
478   else if (unformat (input, "transmit"))
479     a->action_type = SSE2_QOS_ACTION_TRANSMIT;
480   else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp))
481     a->action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
482   else
483     return 0;
484   return 1;
485 }
486
487 static uword
488 unformat_policer_classify_table_type (unformat_input_t * input, va_list * va)
489 {
490   u32 *r = va_arg (*va, u32 *);
491   u32 tid;
492
493   if (unformat (input, "ip4"))
494     tid = POLICER_CLASSIFY_TABLE_IP4;
495   else if (unformat (input, "ip6"))
496     tid = POLICER_CLASSIFY_TABLE_IP6;
497   else if (unformat (input, "l2"))
498     tid = POLICER_CLASSIFY_TABLE_L2;
499   else
500     return 0;
501
502   *r = tid;
503   return 1;
504 }
505
506 static uword
507 unformat_flow_classify_table_type (unformat_input_t * input, va_list * va)
508 {
509   u32 *r = va_arg (*va, u32 *);
510   u32 tid;
511
512   if (unformat (input, "ip4"))
513     tid = FLOW_CLASSIFY_TABLE_IP4;
514   else if (unformat (input, "ip6"))
515     tid = FLOW_CLASSIFY_TABLE_IP6;
516   else
517     return 0;
518
519   *r = tid;
520   return 1;
521 }
522
523 static const char *mfib_flag_names[] = MFIB_ENTRY_NAMES_SHORT;
524 static const char *mfib_flag_long_names[] = MFIB_ENTRY_NAMES_LONG;
525 static const char *mfib_itf_flag_long_names[] = MFIB_ITF_NAMES_LONG;
526 static const char *mfib_itf_flag_names[] = MFIB_ITF_NAMES_SHORT;
527
528 #if (VPP_API_TEST_BUILTIN==0)
529 uword
530 unformat_mfib_itf_flags (unformat_input_t * input, va_list * args)
531 {
532   mfib_itf_flags_t old, *iflags = va_arg (*args, mfib_itf_flags_t *);
533   mfib_itf_attribute_t attr;
534
535   old = *iflags;
536   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
537   {
538     if (unformat (input, mfib_itf_flag_long_names[attr]))
539       *iflags |= (1 << attr);
540   }
541   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
542   {
543     if (unformat (input, mfib_itf_flag_names[attr]))
544       *iflags |= (1 << attr);
545   }
546
547   return (old == *iflags ? 0 : 1);
548 }
549
550 uword
551 unformat_mfib_entry_flags (unformat_input_t * input, va_list * args)
552 {
553   mfib_entry_flags_t old, *eflags = va_arg (*args, mfib_entry_flags_t *);
554   mfib_entry_attribute_t attr;
555
556   old = *eflags;
557   FOR_EACH_MFIB_ATTRIBUTE (attr)
558   {
559     if (unformat (input, mfib_flag_long_names[attr]))
560       *eflags |= (1 << attr);
561   }
562   FOR_EACH_MFIB_ATTRIBUTE (attr)
563   {
564     if (unformat (input, mfib_flag_names[attr]))
565       *eflags |= (1 << attr);
566   }
567
568   return (old == *eflags ? 0 : 1);
569 }
570
571 u8 *
572 format_ip4_address (u8 * s, va_list * args)
573 {
574   u8 *a = va_arg (*args, u8 *);
575   return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
576 }
577
578 u8 *
579 format_ip6_address (u8 * s, va_list * args)
580 {
581   ip6_address_t *a = va_arg (*args, ip6_address_t *);
582   u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
583
584   i_max_n_zero = ARRAY_LEN (a->as_u16);
585   max_n_zeros = 0;
586   i_first_zero = i_max_n_zero;
587   n_zeros = 0;
588   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
589     {
590       u32 is_zero = a->as_u16[i] == 0;
591       if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
592         {
593           i_first_zero = i;
594           n_zeros = 0;
595         }
596       n_zeros += is_zero;
597       if ((!is_zero && n_zeros > max_n_zeros)
598           || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
599         {
600           i_max_n_zero = i_first_zero;
601           max_n_zeros = n_zeros;
602           i_first_zero = ARRAY_LEN (a->as_u16);
603           n_zeros = 0;
604         }
605     }
606
607   last_double_colon = 0;
608   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
609     {
610       if (i == i_max_n_zero && max_n_zeros > 1)
611         {
612           s = format (s, "::");
613           i += max_n_zeros - 1;
614           last_double_colon = 1;
615         }
616       else
617         {
618           s = format (s, "%s%x",
619                       (last_double_colon || i == 0) ? "" : ":",
620                       clib_net_to_host_u16 (a->as_u16[i]));
621           last_double_colon = 0;
622         }
623     }
624
625   return s;
626 }
627
628 /* Format an IP46 address. */
629 u8 *
630 format_ip46_address (u8 * s, va_list * args)
631 {
632   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
633   ip46_type_t type = va_arg (*args, ip46_type_t);
634   int is_ip4 = 1;
635
636   switch (type)
637     {
638     case IP46_TYPE_ANY:
639       is_ip4 = ip46_address_is_ip4 (ip46);
640       break;
641     case IP46_TYPE_IP4:
642       is_ip4 = 1;
643       break;
644     case IP46_TYPE_IP6:
645       is_ip4 = 0;
646       break;
647     }
648
649   return is_ip4 ?
650     format (s, "%U", format_ip4_address, &ip46->ip4) :
651     format (s, "%U", format_ip6_address, &ip46->ip6);
652 }
653
654 u8 *
655 format_ethernet_address (u8 * s, va_list * args)
656 {
657   u8 *a = va_arg (*args, u8 *);
658
659   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
660                  a[0], a[1], a[2], a[3], a[4], a[5]);
661 }
662 #endif
663
664 static void
665 increment_v4_address (ip4_address_t * a)
666 {
667   u32 v;
668
669   v = ntohl (a->as_u32) + 1;
670   a->as_u32 = ntohl (v);
671 }
672
673 static void
674 increment_v6_address (ip6_address_t * a)
675 {
676   u64 v0, v1;
677
678   v0 = clib_net_to_host_u64 (a->as_u64[0]);
679   v1 = clib_net_to_host_u64 (a->as_u64[1]);
680
681   v1 += 1;
682   if (v1 == 0)
683     v0 += 1;
684   a->as_u64[0] = clib_net_to_host_u64 (v0);
685   a->as_u64[1] = clib_net_to_host_u64 (v1);
686 }
687
688 static void
689 increment_mac_address (u64 * mac)
690 {
691   u64 tmp = *mac;
692
693   tmp = clib_net_to_host_u64 (tmp);
694   tmp += 1 << 16;               /* skip unused (least significant) octets */
695   tmp = clib_host_to_net_u64 (tmp);
696   *mac = tmp;
697 }
698
699 static void vl_api_create_loopback_reply_t_handler
700   (vl_api_create_loopback_reply_t * mp)
701 {
702   vat_main_t *vam = &vat_main;
703   i32 retval = ntohl (mp->retval);
704
705   vam->retval = retval;
706   vam->regenerate_interface_table = 1;
707   vam->sw_if_index = ntohl (mp->sw_if_index);
708   vam->result_ready = 1;
709 }
710
711 static void vl_api_create_loopback_reply_t_handler_json
712   (vl_api_create_loopback_reply_t * mp)
713 {
714   vat_main_t *vam = &vat_main;
715   vat_json_node_t node;
716
717   vat_json_init_object (&node);
718   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
719   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
720
721   vat_json_print (vam->ofp, &node);
722   vat_json_free (&node);
723   vam->retval = ntohl (mp->retval);
724   vam->result_ready = 1;
725 }
726
727 static void vl_api_create_loopback_instance_reply_t_handler
728   (vl_api_create_loopback_instance_reply_t * mp)
729 {
730   vat_main_t *vam = &vat_main;
731   i32 retval = ntohl (mp->retval);
732
733   vam->retval = retval;
734   vam->regenerate_interface_table = 1;
735   vam->sw_if_index = ntohl (mp->sw_if_index);
736   vam->result_ready = 1;
737 }
738
739 static void vl_api_create_loopback_instance_reply_t_handler_json
740   (vl_api_create_loopback_instance_reply_t * mp)
741 {
742   vat_main_t *vam = &vat_main;
743   vat_json_node_t node;
744
745   vat_json_init_object (&node);
746   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
747   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
748
749   vat_json_print (vam->ofp, &node);
750   vat_json_free (&node);
751   vam->retval = ntohl (mp->retval);
752   vam->result_ready = 1;
753 }
754
755 static void vl_api_af_packet_create_reply_t_handler
756   (vl_api_af_packet_create_reply_t * mp)
757 {
758   vat_main_t *vam = &vat_main;
759   i32 retval = ntohl (mp->retval);
760
761   vam->retval = retval;
762   vam->regenerate_interface_table = 1;
763   vam->sw_if_index = ntohl (mp->sw_if_index);
764   vam->result_ready = 1;
765 }
766
767 static void vl_api_af_packet_create_reply_t_handler_json
768   (vl_api_af_packet_create_reply_t * mp)
769 {
770   vat_main_t *vam = &vat_main;
771   vat_json_node_t node;
772
773   vat_json_init_object (&node);
774   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
775   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
776
777   vat_json_print (vam->ofp, &node);
778   vat_json_free (&node);
779
780   vam->retval = ntohl (mp->retval);
781   vam->result_ready = 1;
782 }
783
784 static void vl_api_create_vlan_subif_reply_t_handler
785   (vl_api_create_vlan_subif_reply_t * mp)
786 {
787   vat_main_t *vam = &vat_main;
788   i32 retval = ntohl (mp->retval);
789
790   vam->retval = retval;
791   vam->regenerate_interface_table = 1;
792   vam->sw_if_index = ntohl (mp->sw_if_index);
793   vam->result_ready = 1;
794 }
795
796 static void vl_api_create_vlan_subif_reply_t_handler_json
797   (vl_api_create_vlan_subif_reply_t * mp)
798 {
799   vat_main_t *vam = &vat_main;
800   vat_json_node_t node;
801
802   vat_json_init_object (&node);
803   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
804   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
805
806   vat_json_print (vam->ofp, &node);
807   vat_json_free (&node);
808
809   vam->retval = ntohl (mp->retval);
810   vam->result_ready = 1;
811 }
812
813 static void vl_api_create_subif_reply_t_handler
814   (vl_api_create_subif_reply_t * mp)
815 {
816   vat_main_t *vam = &vat_main;
817   i32 retval = ntohl (mp->retval);
818
819   vam->retval = retval;
820   vam->regenerate_interface_table = 1;
821   vam->sw_if_index = ntohl (mp->sw_if_index);
822   vam->result_ready = 1;
823 }
824
825 static void vl_api_create_subif_reply_t_handler_json
826   (vl_api_create_subif_reply_t * mp)
827 {
828   vat_main_t *vam = &vat_main;
829   vat_json_node_t node;
830
831   vat_json_init_object (&node);
832   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
833   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
834
835   vat_json_print (vam->ofp, &node);
836   vat_json_free (&node);
837
838   vam->retval = ntohl (mp->retval);
839   vam->result_ready = 1;
840 }
841
842 static void vl_api_interface_name_renumber_reply_t_handler
843   (vl_api_interface_name_renumber_reply_t * mp)
844 {
845   vat_main_t *vam = &vat_main;
846   i32 retval = ntohl (mp->retval);
847
848   vam->retval = retval;
849   vam->regenerate_interface_table = 1;
850   vam->result_ready = 1;
851 }
852
853 static void vl_api_interface_name_renumber_reply_t_handler_json
854   (vl_api_interface_name_renumber_reply_t * mp)
855 {
856   vat_main_t *vam = &vat_main;
857   vat_json_node_t node;
858
859   vat_json_init_object (&node);
860   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
861
862   vat_json_print (vam->ofp, &node);
863   vat_json_free (&node);
864
865   vam->retval = ntohl (mp->retval);
866   vam->result_ready = 1;
867 }
868
869 /*
870  * Special-case: build the interface table, maintain
871  * the next loopback sw_if_index vbl.
872  */
873 static void vl_api_sw_interface_details_t_handler
874   (vl_api_sw_interface_details_t * mp)
875 {
876   vat_main_t *vam = &vat_main;
877   u8 *s = format (0, "%s%c", mp->interface_name, 0);
878
879   hash_set_mem (vam->sw_if_index_by_interface_name, s,
880                 ntohl (mp->sw_if_index));
881
882   /* In sub interface case, fill the sub interface table entry */
883   if (mp->sw_if_index != mp->sup_sw_if_index)
884     {
885       sw_interface_subif_t *sub = NULL;
886
887       vec_add2 (vam->sw_if_subif_table, sub, 1);
888
889       vec_validate (sub->interface_name, strlen ((char *) s) + 1);
890       strncpy ((char *) sub->interface_name, (char *) s,
891                vec_len (sub->interface_name));
892       sub->sw_if_index = ntohl (mp->sw_if_index);
893       sub->sub_id = ntohl (mp->sub_id);
894
895       sub->sub_dot1ad = mp->sub_dot1ad;
896       sub->sub_number_of_tags = mp->sub_number_of_tags;
897       sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
898       sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
899       sub->sub_exact_match = mp->sub_exact_match;
900       sub->sub_default = mp->sub_default;
901       sub->sub_outer_vlan_id_any = mp->sub_outer_vlan_id_any;
902       sub->sub_inner_vlan_id_any = mp->sub_inner_vlan_id_any;
903
904       /* vlan tag rewrite */
905       sub->vtr_op = ntohl (mp->vtr_op);
906       sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
907       sub->vtr_tag1 = ntohl (mp->vtr_tag1);
908       sub->vtr_tag2 = ntohl (mp->vtr_tag2);
909     }
910 }
911
912 static void vl_api_sw_interface_details_t_handler_json
913   (vl_api_sw_interface_details_t * mp)
914 {
915   vat_main_t *vam = &vat_main;
916   vat_json_node_t *node = NULL;
917
918   if (VAT_JSON_ARRAY != vam->json_tree.type)
919     {
920       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
921       vat_json_init_array (&vam->json_tree);
922     }
923   node = vat_json_array_add (&vam->json_tree);
924
925   vat_json_init_object (node);
926   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
927   vat_json_object_add_uint (node, "sup_sw_if_index",
928                             ntohl (mp->sup_sw_if_index));
929   vat_json_object_add_uint (node, "l2_address_length",
930                             ntohl (mp->l2_address_length));
931   vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
932                              sizeof (mp->l2_address));
933   vat_json_object_add_string_copy (node, "interface_name",
934                                    mp->interface_name);
935   vat_json_object_add_uint (node, "admin_up_down", mp->admin_up_down);
936   vat_json_object_add_uint (node, "link_up_down", mp->link_up_down);
937   vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
938   vat_json_object_add_uint (node, "link_speed", mp->link_speed);
939   vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
940   vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
941   vat_json_object_add_uint (node, "sub_dot1ad", mp->sub_dot1ad);
942   vat_json_object_add_uint (node, "sub_number_of_tags",
943                             mp->sub_number_of_tags);
944   vat_json_object_add_uint (node, "sub_outer_vlan_id",
945                             ntohs (mp->sub_outer_vlan_id));
946   vat_json_object_add_uint (node, "sub_inner_vlan_id",
947                             ntohs (mp->sub_inner_vlan_id));
948   vat_json_object_add_uint (node, "sub_exact_match", mp->sub_exact_match);
949   vat_json_object_add_uint (node, "sub_default", mp->sub_default);
950   vat_json_object_add_uint (node, "sub_outer_vlan_id_any",
951                             mp->sub_outer_vlan_id_any);
952   vat_json_object_add_uint (node, "sub_inner_vlan_id_any",
953                             mp->sub_inner_vlan_id_any);
954   vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
955   vat_json_object_add_uint (node, "vtr_push_dot1q",
956                             ntohl (mp->vtr_push_dot1q));
957   vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
958   vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
959   if (mp->sub_dot1ah)
960     {
961       vat_json_object_add_string_copy (node, "pbb_vtr_dmac",
962                                        format (0, "%U",
963                                                format_ethernet_address,
964                                                &mp->b_dmac));
965       vat_json_object_add_string_copy (node, "pbb_vtr_smac",
966                                        format (0, "%U",
967                                                format_ethernet_address,
968                                                &mp->b_smac));
969       vat_json_object_add_uint (node, "pbb_vtr_b_vlanid", mp->b_vlanid);
970       vat_json_object_add_uint (node, "pbb_vtr_i_sid", mp->i_sid);
971     }
972 }
973
974 #if VPP_API_TEST_BUILTIN == 0
975 static void vl_api_sw_interface_set_flags_t_handler
976   (vl_api_sw_interface_set_flags_t * mp)
977 {
978   vat_main_t *vam = &vat_main;
979   if (vam->interface_event_display)
980     errmsg ("interface flags: sw_if_index %d %s %s",
981             ntohl (mp->sw_if_index),
982             mp->admin_up_down ? "admin-up" : "admin-down",
983             mp->link_up_down ? "link-up" : "link-down");
984 }
985 #endif
986
987 static void vl_api_sw_interface_set_flags_t_handler_json
988   (vl_api_sw_interface_set_flags_t * mp)
989 {
990   /* JSON output not supported */
991 }
992
993 static void
994 vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
995 {
996   vat_main_t *vam = &vat_main;
997   i32 retval = ntohl (mp->retval);
998
999   vam->retval = retval;
1000   vam->shmem_result = uword_to_pointer (mp->reply_in_shmem, u8 *);
1001   vam->result_ready = 1;
1002 }
1003
1004 static void
1005 vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
1006 {
1007   vat_main_t *vam = &vat_main;
1008   vat_json_node_t node;
1009   api_main_t *am = &api_main;
1010   void *oldheap;
1011   u8 *reply;
1012
1013   vat_json_init_object (&node);
1014   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1015   vat_json_object_add_uint (&node, "reply_in_shmem",
1016                             ntohl (mp->reply_in_shmem));
1017   /* Toss the shared-memory original... */
1018   pthread_mutex_lock (&am->vlib_rp->mutex);
1019   oldheap = svm_push_data_heap (am->vlib_rp);
1020
1021   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
1022   vec_free (reply);
1023
1024   svm_pop_heap (oldheap);
1025   pthread_mutex_unlock (&am->vlib_rp->mutex);
1026
1027   vat_json_print (vam->ofp, &node);
1028   vat_json_free (&node);
1029
1030   vam->retval = ntohl (mp->retval);
1031   vam->result_ready = 1;
1032 }
1033
1034 static void
1035 vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
1036 {
1037   vat_main_t *vam = &vat_main;
1038   i32 retval = ntohl (mp->retval);
1039
1040   vam->retval = retval;
1041   vam->cmd_reply = mp->reply;
1042   vam->result_ready = 1;
1043 }
1044
1045 static void
1046 vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
1047 {
1048   vat_main_t *vam = &vat_main;
1049   vat_json_node_t node;
1050
1051   vat_json_init_object (&node);
1052   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1053   vat_json_object_add_string_copy (&node, "reply", mp->reply);
1054
1055   vat_json_print (vam->ofp, &node);
1056   vat_json_free (&node);
1057
1058   vam->retval = ntohl (mp->retval);
1059   vam->result_ready = 1;
1060 }
1061
1062 static void vl_api_classify_add_del_table_reply_t_handler
1063   (vl_api_classify_add_del_table_reply_t * mp)
1064 {
1065   vat_main_t *vam = &vat_main;
1066   i32 retval = ntohl (mp->retval);
1067   if (vam->async_mode)
1068     {
1069       vam->async_errors += (retval < 0);
1070     }
1071   else
1072     {
1073       vam->retval = retval;
1074       if (retval == 0 &&
1075           ((mp->new_table_index != 0xFFFFFFFF) ||
1076            (mp->skip_n_vectors != 0xFFFFFFFF) ||
1077            (mp->match_n_vectors != 0xFFFFFFFF)))
1078         /*
1079          * Note: this is just barely thread-safe, depends on
1080          * the main thread spinning waiting for an answer...
1081          */
1082         errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d",
1083                 ntohl (mp->new_table_index),
1084                 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
1085       vam->result_ready = 1;
1086     }
1087 }
1088
1089 static void vl_api_classify_add_del_table_reply_t_handler_json
1090   (vl_api_classify_add_del_table_reply_t * mp)
1091 {
1092   vat_main_t *vam = &vat_main;
1093   vat_json_node_t node;
1094
1095   vat_json_init_object (&node);
1096   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1097   vat_json_object_add_uint (&node, "new_table_index",
1098                             ntohl (mp->new_table_index));
1099   vat_json_object_add_uint (&node, "skip_n_vectors",
1100                             ntohl (mp->skip_n_vectors));
1101   vat_json_object_add_uint (&node, "match_n_vectors",
1102                             ntohl (mp->match_n_vectors));
1103
1104   vat_json_print (vam->ofp, &node);
1105   vat_json_free (&node);
1106
1107   vam->retval = ntohl (mp->retval);
1108   vam->result_ready = 1;
1109 }
1110
1111 static void vl_api_get_node_index_reply_t_handler
1112   (vl_api_get_node_index_reply_t * mp)
1113 {
1114   vat_main_t *vam = &vat_main;
1115   i32 retval = ntohl (mp->retval);
1116   if (vam->async_mode)
1117     {
1118       vam->async_errors += (retval < 0);
1119     }
1120   else
1121     {
1122       vam->retval = retval;
1123       if (retval == 0)
1124         errmsg ("node index %d", ntohl (mp->node_index));
1125       vam->result_ready = 1;
1126     }
1127 }
1128
1129 static void vl_api_get_node_index_reply_t_handler_json
1130   (vl_api_get_node_index_reply_t * mp)
1131 {
1132   vat_main_t *vam = &vat_main;
1133   vat_json_node_t node;
1134
1135   vat_json_init_object (&node);
1136   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1137   vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
1138
1139   vat_json_print (vam->ofp, &node);
1140   vat_json_free (&node);
1141
1142   vam->retval = ntohl (mp->retval);
1143   vam->result_ready = 1;
1144 }
1145
1146 static void vl_api_get_next_index_reply_t_handler
1147   (vl_api_get_next_index_reply_t * mp)
1148 {
1149   vat_main_t *vam = &vat_main;
1150   i32 retval = ntohl (mp->retval);
1151   if (vam->async_mode)
1152     {
1153       vam->async_errors += (retval < 0);
1154     }
1155   else
1156     {
1157       vam->retval = retval;
1158       if (retval == 0)
1159         errmsg ("next node index %d", ntohl (mp->next_index));
1160       vam->result_ready = 1;
1161     }
1162 }
1163
1164 static void vl_api_get_next_index_reply_t_handler_json
1165   (vl_api_get_next_index_reply_t * mp)
1166 {
1167   vat_main_t *vam = &vat_main;
1168   vat_json_node_t node;
1169
1170   vat_json_init_object (&node);
1171   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1172   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1173
1174   vat_json_print (vam->ofp, &node);
1175   vat_json_free (&node);
1176
1177   vam->retval = ntohl (mp->retval);
1178   vam->result_ready = 1;
1179 }
1180
1181 static void vl_api_add_node_next_reply_t_handler
1182   (vl_api_add_node_next_reply_t * mp)
1183 {
1184   vat_main_t *vam = &vat_main;
1185   i32 retval = ntohl (mp->retval);
1186   if (vam->async_mode)
1187     {
1188       vam->async_errors += (retval < 0);
1189     }
1190   else
1191     {
1192       vam->retval = retval;
1193       if (retval == 0)
1194         errmsg ("next index %d", ntohl (mp->next_index));
1195       vam->result_ready = 1;
1196     }
1197 }
1198
1199 static void vl_api_add_node_next_reply_t_handler_json
1200   (vl_api_add_node_next_reply_t * mp)
1201 {
1202   vat_main_t *vam = &vat_main;
1203   vat_json_node_t node;
1204
1205   vat_json_init_object (&node);
1206   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1207   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1208
1209   vat_json_print (vam->ofp, &node);
1210   vat_json_free (&node);
1211
1212   vam->retval = ntohl (mp->retval);
1213   vam->result_ready = 1;
1214 }
1215
1216 static void vl_api_show_version_reply_t_handler
1217   (vl_api_show_version_reply_t * mp)
1218 {
1219   vat_main_t *vam = &vat_main;
1220   i32 retval = ntohl (mp->retval);
1221
1222   if (retval >= 0)
1223     {
1224       errmsg ("        program: %s", mp->program);
1225       errmsg ("        version: %s", mp->version);
1226       errmsg ("     build date: %s", mp->build_date);
1227       errmsg ("build directory: %s", mp->build_directory);
1228     }
1229   vam->retval = retval;
1230   vam->result_ready = 1;
1231 }
1232
1233 static void vl_api_show_version_reply_t_handler_json
1234   (vl_api_show_version_reply_t * mp)
1235 {
1236   vat_main_t *vam = &vat_main;
1237   vat_json_node_t node;
1238
1239   vat_json_init_object (&node);
1240   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1241   vat_json_object_add_string_copy (&node, "program", mp->program);
1242   vat_json_object_add_string_copy (&node, "version", mp->version);
1243   vat_json_object_add_string_copy (&node, "build_date", mp->build_date);
1244   vat_json_object_add_string_copy (&node, "build_directory",
1245                                    mp->build_directory);
1246
1247   vat_json_print (vam->ofp, &node);
1248   vat_json_free (&node);
1249
1250   vam->retval = ntohl (mp->retval);
1251   vam->result_ready = 1;
1252 }
1253
1254 static void
1255 vl_api_ip4_arp_event_t_handler (vl_api_ip4_arp_event_t * mp)
1256 {
1257   u32 sw_if_index = ntohl (mp->sw_if_index);
1258   errmsg ("arp %s event: pid %d address %U new mac %U sw_if_index %d\n",
1259           mp->mac_ip ? "mac/ip binding" : "address resolution",
1260           ntohl (mp->pid), format_ip4_address, &mp->address,
1261           format_ethernet_address, mp->new_mac, sw_if_index);
1262 }
1263
1264 static void
1265 vl_api_ip4_arp_event_t_handler_json (vl_api_ip4_arp_event_t * mp)
1266 {
1267   /* JSON output not supported */
1268 }
1269
1270 static void
1271 vl_api_ip6_nd_event_t_handler (vl_api_ip6_nd_event_t * mp)
1272 {
1273   u32 sw_if_index = ntohl (mp->sw_if_index);
1274   errmsg ("ip6 nd %s event: pid %d address %U new mac %U sw_if_index %d\n",
1275           mp->mac_ip ? "mac/ip binding" : "address resolution",
1276           ntohl (mp->pid), format_ip6_address, mp->address,
1277           format_ethernet_address, mp->new_mac, sw_if_index);
1278 }
1279
1280 static void
1281 vl_api_ip6_nd_event_t_handler_json (vl_api_ip6_nd_event_t * mp)
1282 {
1283   /* JSON output not supported */
1284 }
1285
1286 #define vl_api_bridge_domain_details_t_endian vl_noop_handler
1287 #define vl_api_bridge_domain_details_t_print vl_noop_handler
1288
1289 /*
1290  * Special-case: build the bridge domain table, maintain
1291  * the next bd id vbl.
1292  */
1293 static void vl_api_bridge_domain_details_t_handler
1294   (vl_api_bridge_domain_details_t * mp)
1295 {
1296   vat_main_t *vam = &vat_main;
1297   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1298   int i;
1299
1300   print (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-3s",
1301          " ID", "LRN", "FWD", "FLD", "BVI", "#IF");
1302
1303   print (vam->ofp, "%3d %3d %3d %3d %3d %3d",
1304          ntohl (mp->bd_id), mp->learn, mp->forward,
1305          mp->flood, ntohl (mp->bvi_sw_if_index), n_sw_ifs);
1306
1307   if (n_sw_ifs)
1308     {
1309       vl_api_bridge_domain_sw_if_t *sw_ifs;
1310       print (vam->ofp, "\n\n%s %s  %s", "sw_if_index", "SHG",
1311              "Interface Name");
1312
1313       sw_ifs = mp->sw_if_details;
1314       for (i = 0; i < n_sw_ifs; i++)
1315         {
1316           u8 *sw_if_name = 0;
1317           u32 sw_if_index;
1318           hash_pair_t *p;
1319
1320           sw_if_index = ntohl (sw_ifs->sw_if_index);
1321
1322           /* *INDENT-OFF* */
1323           hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1324                              ({
1325                                if ((u32) p->value[0] == sw_if_index)
1326                                  {
1327                                    sw_if_name = (u8 *)(p->key);
1328                                    break;
1329                                  }
1330                              }));
1331           /* *INDENT-ON* */
1332           print (vam->ofp, "%7d     %3d  %s", sw_if_index,
1333                  sw_ifs->shg, sw_if_name ? (char *) sw_if_name :
1334                  "sw_if_index not found!");
1335
1336           sw_ifs++;
1337         }
1338     }
1339 }
1340
1341 static void vl_api_bridge_domain_details_t_handler_json
1342   (vl_api_bridge_domain_details_t * mp)
1343 {
1344   vat_main_t *vam = &vat_main;
1345   vat_json_node_t *node, *array = NULL;
1346   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1347
1348   if (VAT_JSON_ARRAY != vam->json_tree.type)
1349     {
1350       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1351       vat_json_init_array (&vam->json_tree);
1352     }
1353   node = vat_json_array_add (&vam->json_tree);
1354
1355   vat_json_init_object (node);
1356   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1357   vat_json_object_add_uint (node, "flood", mp->flood);
1358   vat_json_object_add_uint (node, "forward", mp->forward);
1359   vat_json_object_add_uint (node, "learn", mp->learn);
1360   vat_json_object_add_uint (node, "bvi_sw_if_index",
1361                             ntohl (mp->bvi_sw_if_index));
1362   vat_json_object_add_uint (node, "n_sw_ifs", n_sw_ifs);
1363   array = vat_json_object_add (node, "sw_if");
1364   vat_json_init_array (array);
1365
1366
1367
1368   if (n_sw_ifs)
1369     {
1370       vl_api_bridge_domain_sw_if_t *sw_ifs;
1371       int i;
1372
1373       sw_ifs = mp->sw_if_details;
1374       for (i = 0; i < n_sw_ifs; i++)
1375         {
1376           node = vat_json_array_add (array);
1377           vat_json_init_object (node);
1378           vat_json_object_add_uint (node, "sw_if_index",
1379                                     ntohl (sw_ifs->sw_if_index));
1380           vat_json_object_add_uint (node, "shg", sw_ifs->shg);
1381           sw_ifs++;
1382         }
1383     }
1384 }
1385
1386 static void vl_api_control_ping_reply_t_handler
1387   (vl_api_control_ping_reply_t * mp)
1388 {
1389   vat_main_t *vam = &vat_main;
1390   i32 retval = ntohl (mp->retval);
1391   if (vam->async_mode)
1392     {
1393       vam->async_errors += (retval < 0);
1394     }
1395   else
1396     {
1397       vam->retval = retval;
1398       vam->result_ready = 1;
1399     }
1400 }
1401
1402 static void vl_api_control_ping_reply_t_handler_json
1403   (vl_api_control_ping_reply_t * mp)
1404 {
1405   vat_main_t *vam = &vat_main;
1406   i32 retval = ntohl (mp->retval);
1407
1408   if (VAT_JSON_NONE != vam->json_tree.type)
1409     {
1410       vat_json_print (vam->ofp, &vam->json_tree);
1411       vat_json_free (&vam->json_tree);
1412       vam->json_tree.type = VAT_JSON_NONE;
1413     }
1414   else
1415     {
1416       /* just print [] */
1417       vat_json_init_array (&vam->json_tree);
1418       vat_json_print (vam->ofp, &vam->json_tree);
1419       vam->json_tree.type = VAT_JSON_NONE;
1420     }
1421
1422   vam->retval = retval;
1423   vam->result_ready = 1;
1424 }
1425
1426 static void
1427   vl_api_bridge_domain_set_mac_age_reply_t_handler
1428   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1429 {
1430   vat_main_t *vam = &vat_main;
1431   i32 retval = ntohl (mp->retval);
1432   if (vam->async_mode)
1433     {
1434       vam->async_errors += (retval < 0);
1435     }
1436   else
1437     {
1438       vam->retval = retval;
1439       vam->result_ready = 1;
1440     }
1441 }
1442
1443 static void vl_api_bridge_domain_set_mac_age_reply_t_handler_json
1444   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1445 {
1446   vat_main_t *vam = &vat_main;
1447   vat_json_node_t node;
1448
1449   vat_json_init_object (&node);
1450   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1451
1452   vat_json_print (vam->ofp, &node);
1453   vat_json_free (&node);
1454
1455   vam->retval = ntohl (mp->retval);
1456   vam->result_ready = 1;
1457 }
1458
1459 static void
1460 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1461 {
1462   vat_main_t *vam = &vat_main;
1463   i32 retval = ntohl (mp->retval);
1464   if (vam->async_mode)
1465     {
1466       vam->async_errors += (retval < 0);
1467     }
1468   else
1469     {
1470       vam->retval = retval;
1471       vam->result_ready = 1;
1472     }
1473 }
1474
1475 static void vl_api_l2_flags_reply_t_handler_json
1476   (vl_api_l2_flags_reply_t * mp)
1477 {
1478   vat_main_t *vam = &vat_main;
1479   vat_json_node_t node;
1480
1481   vat_json_init_object (&node);
1482   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1483   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1484                             ntohl (mp->resulting_feature_bitmap));
1485
1486   vat_json_print (vam->ofp, &node);
1487   vat_json_free (&node);
1488
1489   vam->retval = ntohl (mp->retval);
1490   vam->result_ready = 1;
1491 }
1492
1493 static void vl_api_bridge_flags_reply_t_handler
1494   (vl_api_bridge_flags_reply_t * mp)
1495 {
1496   vat_main_t *vam = &vat_main;
1497   i32 retval = ntohl (mp->retval);
1498   if (vam->async_mode)
1499     {
1500       vam->async_errors += (retval < 0);
1501     }
1502   else
1503     {
1504       vam->retval = retval;
1505       vam->result_ready = 1;
1506     }
1507 }
1508
1509 static void vl_api_bridge_flags_reply_t_handler_json
1510   (vl_api_bridge_flags_reply_t * mp)
1511 {
1512   vat_main_t *vam = &vat_main;
1513   vat_json_node_t node;
1514
1515   vat_json_init_object (&node);
1516   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1517   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1518                             ntohl (mp->resulting_feature_bitmap));
1519
1520   vat_json_print (vam->ofp, &node);
1521   vat_json_free (&node);
1522
1523   vam->retval = ntohl (mp->retval);
1524   vam->result_ready = 1;
1525 }
1526
1527 static void vl_api_tap_connect_reply_t_handler
1528   (vl_api_tap_connect_reply_t * mp)
1529 {
1530   vat_main_t *vam = &vat_main;
1531   i32 retval = ntohl (mp->retval);
1532   if (vam->async_mode)
1533     {
1534       vam->async_errors += (retval < 0);
1535     }
1536   else
1537     {
1538       vam->retval = retval;
1539       vam->sw_if_index = ntohl (mp->sw_if_index);
1540       vam->result_ready = 1;
1541     }
1542
1543 }
1544
1545 static void vl_api_tap_connect_reply_t_handler_json
1546   (vl_api_tap_connect_reply_t * mp)
1547 {
1548   vat_main_t *vam = &vat_main;
1549   vat_json_node_t node;
1550
1551   vat_json_init_object (&node);
1552   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1553   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1554
1555   vat_json_print (vam->ofp, &node);
1556   vat_json_free (&node);
1557
1558   vam->retval = ntohl (mp->retval);
1559   vam->result_ready = 1;
1560
1561 }
1562
1563 static void
1564 vl_api_tap_modify_reply_t_handler (vl_api_tap_modify_reply_t * mp)
1565 {
1566   vat_main_t *vam = &vat_main;
1567   i32 retval = ntohl (mp->retval);
1568   if (vam->async_mode)
1569     {
1570       vam->async_errors += (retval < 0);
1571     }
1572   else
1573     {
1574       vam->retval = retval;
1575       vam->sw_if_index = ntohl (mp->sw_if_index);
1576       vam->result_ready = 1;
1577     }
1578 }
1579
1580 static void vl_api_tap_modify_reply_t_handler_json
1581   (vl_api_tap_modify_reply_t * mp)
1582 {
1583   vat_main_t *vam = &vat_main;
1584   vat_json_node_t node;
1585
1586   vat_json_init_object (&node);
1587   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1588   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1589
1590   vat_json_print (vam->ofp, &node);
1591   vat_json_free (&node);
1592
1593   vam->retval = ntohl (mp->retval);
1594   vam->result_ready = 1;
1595 }
1596
1597 static void
1598 vl_api_tap_delete_reply_t_handler (vl_api_tap_delete_reply_t * mp)
1599 {
1600   vat_main_t *vam = &vat_main;
1601   i32 retval = ntohl (mp->retval);
1602   if (vam->async_mode)
1603     {
1604       vam->async_errors += (retval < 0);
1605     }
1606   else
1607     {
1608       vam->retval = retval;
1609       vam->result_ready = 1;
1610     }
1611 }
1612
1613 static void vl_api_tap_delete_reply_t_handler_json
1614   (vl_api_tap_delete_reply_t * mp)
1615 {
1616   vat_main_t *vam = &vat_main;
1617   vat_json_node_t node;
1618
1619   vat_json_init_object (&node);
1620   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1621
1622   vat_json_print (vam->ofp, &node);
1623   vat_json_free (&node);
1624
1625   vam->retval = ntohl (mp->retval);
1626   vam->result_ready = 1;
1627 }
1628
1629 static void vl_api_mpls_tunnel_add_del_reply_t_handler
1630   (vl_api_mpls_tunnel_add_del_reply_t * mp)
1631 {
1632   vat_main_t *vam = &vat_main;
1633   i32 retval = ntohl (mp->retval);
1634   if (vam->async_mode)
1635     {
1636       vam->async_errors += (retval < 0);
1637     }
1638   else
1639     {
1640       vam->retval = retval;
1641       vam->result_ready = 1;
1642     }
1643 }
1644
1645 static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
1646   (vl_api_mpls_tunnel_add_del_reply_t * mp)
1647 {
1648   vat_main_t *vam = &vat_main;
1649   vat_json_node_t node;
1650
1651   vat_json_init_object (&node);
1652   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1653   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
1654                             ntohl (mp->sw_if_index));
1655
1656   vat_json_print (vam->ofp, &node);
1657   vat_json_free (&node);
1658
1659   vam->retval = ntohl (mp->retval);
1660   vam->result_ready = 1;
1661 }
1662
1663 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
1664   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1665 {
1666   vat_main_t *vam = &vat_main;
1667   i32 retval = ntohl (mp->retval);
1668   if (vam->async_mode)
1669     {
1670       vam->async_errors += (retval < 0);
1671     }
1672   else
1673     {
1674       vam->retval = retval;
1675       vam->sw_if_index = ntohl (mp->sw_if_index);
1676       vam->result_ready = 1;
1677     }
1678 }
1679
1680 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
1681   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1682 {
1683   vat_main_t *vam = &vat_main;
1684   vat_json_node_t node;
1685
1686   vat_json_init_object (&node);
1687   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1688   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1689
1690   vat_json_print (vam->ofp, &node);
1691   vat_json_free (&node);
1692
1693   vam->retval = ntohl (mp->retval);
1694   vam->result_ready = 1;
1695 }
1696
1697 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler
1698   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
1699 {
1700   vat_main_t *vam = &vat_main;
1701   i32 retval = ntohl (mp->retval);
1702   if (vam->async_mode)
1703     {
1704       vam->async_errors += (retval < 0);
1705     }
1706   else
1707     {
1708       vam->retval = retval;
1709       vam->result_ready = 1;
1710     }
1711 }
1712
1713 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler_json
1714   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
1715 {
1716   vat_main_t *vam = &vat_main;
1717   vat_json_node_t node;
1718
1719   vat_json_init_object (&node);
1720   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1721   vat_json_object_add_uint (&node, "fwd_entry_index",
1722                             clib_net_to_host_u32 (mp->fwd_entry_index));
1723
1724   vat_json_print (vam->ofp, &node);
1725   vat_json_free (&node);
1726
1727   vam->retval = ntohl (mp->retval);
1728   vam->result_ready = 1;
1729 }
1730
1731 static void vl_api_one_add_del_locator_set_reply_t_handler
1732   (vl_api_one_add_del_locator_set_reply_t * mp)
1733 {
1734   vat_main_t *vam = &vat_main;
1735   i32 retval = ntohl (mp->retval);
1736   if (vam->async_mode)
1737     {
1738       vam->async_errors += (retval < 0);
1739     }
1740   else
1741     {
1742       vam->retval = retval;
1743       vam->result_ready = 1;
1744     }
1745 }
1746
1747 static void vl_api_one_add_del_locator_set_reply_t_handler_json
1748   (vl_api_one_add_del_locator_set_reply_t * mp)
1749 {
1750   vat_main_t *vam = &vat_main;
1751   vat_json_node_t node;
1752
1753   vat_json_init_object (&node);
1754   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1755   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
1756
1757   vat_json_print (vam->ofp, &node);
1758   vat_json_free (&node);
1759
1760   vam->retval = ntohl (mp->retval);
1761   vam->result_ready = 1;
1762 }
1763
1764 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
1765   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1766 {
1767   vat_main_t *vam = &vat_main;
1768   i32 retval = ntohl (mp->retval);
1769   if (vam->async_mode)
1770     {
1771       vam->async_errors += (retval < 0);
1772     }
1773   else
1774     {
1775       vam->retval = retval;
1776       vam->sw_if_index = ntohl (mp->sw_if_index);
1777       vam->result_ready = 1;
1778     }
1779 }
1780
1781 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
1782   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1783 {
1784   vat_main_t *vam = &vat_main;
1785   vat_json_node_t node;
1786
1787   vat_json_init_object (&node);
1788   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1789   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1790
1791   vat_json_print (vam->ofp, &node);
1792   vat_json_free (&node);
1793
1794   vam->retval = ntohl (mp->retval);
1795   vam->result_ready = 1;
1796 }
1797
1798 static void vl_api_gre_add_del_tunnel_reply_t_handler
1799   (vl_api_gre_add_del_tunnel_reply_t * mp)
1800 {
1801   vat_main_t *vam = &vat_main;
1802   i32 retval = ntohl (mp->retval);
1803   if (vam->async_mode)
1804     {
1805       vam->async_errors += (retval < 0);
1806     }
1807   else
1808     {
1809       vam->retval = retval;
1810       vam->sw_if_index = ntohl (mp->sw_if_index);
1811       vam->result_ready = 1;
1812     }
1813 }
1814
1815 static void vl_api_gre_add_del_tunnel_reply_t_handler_json
1816   (vl_api_gre_add_del_tunnel_reply_t * mp)
1817 {
1818   vat_main_t *vam = &vat_main;
1819   vat_json_node_t node;
1820
1821   vat_json_init_object (&node);
1822   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1823   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1824
1825   vat_json_print (vam->ofp, &node);
1826   vat_json_free (&node);
1827
1828   vam->retval = ntohl (mp->retval);
1829   vam->result_ready = 1;
1830 }
1831
1832 static void vl_api_create_vhost_user_if_reply_t_handler
1833   (vl_api_create_vhost_user_if_reply_t * mp)
1834 {
1835   vat_main_t *vam = &vat_main;
1836   i32 retval = ntohl (mp->retval);
1837   if (vam->async_mode)
1838     {
1839       vam->async_errors += (retval < 0);
1840     }
1841   else
1842     {
1843       vam->retval = retval;
1844       vam->sw_if_index = ntohl (mp->sw_if_index);
1845       vam->result_ready = 1;
1846     }
1847 }
1848
1849 static void vl_api_create_vhost_user_if_reply_t_handler_json
1850   (vl_api_create_vhost_user_if_reply_t * mp)
1851 {
1852   vat_main_t *vam = &vat_main;
1853   vat_json_node_t node;
1854
1855   vat_json_init_object (&node);
1856   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1857   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1858
1859   vat_json_print (vam->ofp, &node);
1860   vat_json_free (&node);
1861
1862   vam->retval = ntohl (mp->retval);
1863   vam->result_ready = 1;
1864 }
1865
1866 static void vl_api_ip_address_details_t_handler
1867   (vl_api_ip_address_details_t * mp)
1868 {
1869   vat_main_t *vam = &vat_main;
1870   static ip_address_details_t empty_ip_address_details = { {0} };
1871   ip_address_details_t *address = NULL;
1872   ip_details_t *current_ip_details = NULL;
1873   ip_details_t *details = NULL;
1874
1875   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
1876
1877   if (!details || vam->current_sw_if_index >= vec_len (details)
1878       || !details[vam->current_sw_if_index].present)
1879     {
1880       errmsg ("ip address details arrived but not stored");
1881       errmsg ("ip_dump should be called first");
1882       return;
1883     }
1884
1885   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
1886
1887 #define addresses (current_ip_details->addr)
1888
1889   vec_validate_init_empty (addresses, vec_len (addresses),
1890                            empty_ip_address_details);
1891
1892   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
1893
1894   clib_memcpy (&address->ip, &mp->ip, sizeof (address->ip));
1895   address->prefix_length = mp->prefix_length;
1896 #undef addresses
1897 }
1898
1899 static void vl_api_ip_address_details_t_handler_json
1900   (vl_api_ip_address_details_t * mp)
1901 {
1902   vat_main_t *vam = &vat_main;
1903   vat_json_node_t *node = NULL;
1904   struct in6_addr ip6;
1905   struct in_addr ip4;
1906
1907   if (VAT_JSON_ARRAY != vam->json_tree.type)
1908     {
1909       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1910       vat_json_init_array (&vam->json_tree);
1911     }
1912   node = vat_json_array_add (&vam->json_tree);
1913
1914   vat_json_init_object (node);
1915   if (vam->is_ipv6)
1916     {
1917       clib_memcpy (&ip6, mp->ip, sizeof (ip6));
1918       vat_json_object_add_ip6 (node, "ip", ip6);
1919     }
1920   else
1921     {
1922       clib_memcpy (&ip4, mp->ip, sizeof (ip4));
1923       vat_json_object_add_ip4 (node, "ip", ip4);
1924     }
1925   vat_json_object_add_uint (node, "prefix_length", mp->prefix_length);
1926 }
1927
1928 static void
1929 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
1930 {
1931   vat_main_t *vam = &vat_main;
1932   static ip_details_t empty_ip_details = { 0 };
1933   ip_details_t *ip = NULL;
1934   u32 sw_if_index = ~0;
1935
1936   sw_if_index = ntohl (mp->sw_if_index);
1937
1938   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1939                            sw_if_index, empty_ip_details);
1940
1941   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1942                          sw_if_index);
1943
1944   ip->present = 1;
1945 }
1946
1947 static void
1948 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
1949 {
1950   vat_main_t *vam = &vat_main;
1951
1952   if (VAT_JSON_ARRAY != vam->json_tree.type)
1953     {
1954       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1955       vat_json_init_array (&vam->json_tree);
1956     }
1957   vat_json_array_add_uint (&vam->json_tree,
1958                            clib_net_to_host_u32 (mp->sw_if_index));
1959 }
1960
1961 static void vl_api_map_domain_details_t_handler_json
1962   (vl_api_map_domain_details_t * mp)
1963 {
1964   vat_json_node_t *node = NULL;
1965   vat_main_t *vam = &vat_main;
1966   struct in6_addr ip6;
1967   struct in_addr ip4;
1968
1969   if (VAT_JSON_ARRAY != vam->json_tree.type)
1970     {
1971       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1972       vat_json_init_array (&vam->json_tree);
1973     }
1974
1975   node = vat_json_array_add (&vam->json_tree);
1976   vat_json_init_object (node);
1977
1978   vat_json_object_add_uint (node, "domain_index",
1979                             clib_net_to_host_u32 (mp->domain_index));
1980   clib_memcpy (&ip6, mp->ip6_prefix, sizeof (ip6));
1981   vat_json_object_add_ip6 (node, "ip6_prefix", ip6);
1982   clib_memcpy (&ip4, mp->ip4_prefix, sizeof (ip4));
1983   vat_json_object_add_ip4 (node, "ip4_prefix", ip4);
1984   clib_memcpy (&ip6, mp->ip6_src, sizeof (ip6));
1985   vat_json_object_add_ip6 (node, "ip6_src", ip6);
1986   vat_json_object_add_int (node, "ip6_prefix_len", mp->ip6_prefix_len);
1987   vat_json_object_add_int (node, "ip4_prefix_len", mp->ip4_prefix_len);
1988   vat_json_object_add_int (node, "ip6_src_len", mp->ip6_src_len);
1989   vat_json_object_add_int (node, "ea_bits_len", mp->ea_bits_len);
1990   vat_json_object_add_int (node, "psid_offset", mp->psid_offset);
1991   vat_json_object_add_int (node, "psid_length", mp->psid_length);
1992   vat_json_object_add_uint (node, "flags", mp->flags);
1993   vat_json_object_add_uint (node, "mtu", clib_net_to_host_u16 (mp->mtu));
1994   vat_json_object_add_int (node, "is_translation", mp->is_translation);
1995 }
1996
1997 static void vl_api_map_domain_details_t_handler
1998   (vl_api_map_domain_details_t * mp)
1999 {
2000   vat_main_t *vam = &vat_main;
2001
2002   if (mp->is_translation)
2003     {
2004       print (vam->ofp,
2005              "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U/%d (ip6-src) index: %u",
2006              format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
2007              format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
2008              format_ip6_address, mp->ip6_src, mp->ip6_src_len,
2009              clib_net_to_host_u32 (mp->domain_index));
2010     }
2011   else
2012     {
2013       print (vam->ofp,
2014              "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U (ip6-src) index: %u",
2015              format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
2016              format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
2017              format_ip6_address, mp->ip6_src,
2018              clib_net_to_host_u32 (mp->domain_index));
2019     }
2020   print (vam->ofp, "  ea-len %d psid-offset %d psid-len %d mtu %d %s",
2021          mp->ea_bits_len, mp->psid_offset, mp->psid_length, mp->mtu,
2022          mp->is_translation ? "map-t" : "");
2023 }
2024
2025 static void vl_api_map_rule_details_t_handler_json
2026   (vl_api_map_rule_details_t * mp)
2027 {
2028   struct in6_addr ip6;
2029   vat_json_node_t *node = NULL;
2030   vat_main_t *vam = &vat_main;
2031
2032   if (VAT_JSON_ARRAY != vam->json_tree.type)
2033     {
2034       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2035       vat_json_init_array (&vam->json_tree);
2036     }
2037
2038   node = vat_json_array_add (&vam->json_tree);
2039   vat_json_init_object (node);
2040
2041   vat_json_object_add_uint (node, "psid", clib_net_to_host_u16 (mp->psid));
2042   clib_memcpy (&ip6, mp->ip6_dst, sizeof (ip6));
2043   vat_json_object_add_ip6 (node, "ip6_dst", ip6);
2044 }
2045
2046 static void
2047 vl_api_map_rule_details_t_handler (vl_api_map_rule_details_t * mp)
2048 {
2049   vat_main_t *vam = &vat_main;
2050   print (vam->ofp, " %d (psid) %U (ip6-dst)",
2051          clib_net_to_host_u16 (mp->psid), format_ip6_address, mp->ip6_dst);
2052 }
2053
2054 static void
2055 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
2056 {
2057   errmsg ("DHCP compl event: pid %d %s hostname %s host_addr %U "
2058           "router_addr %U host_mac %U",
2059           ntohl (mp->pid), mp->is_ipv6 ? "ipv6" : "ipv4", mp->hostname,
2060           format_ip4_address, &mp->host_address,
2061           format_ip4_address, &mp->router_address,
2062           format_ethernet_address, mp->host_mac);
2063 }
2064
2065 static void vl_api_dhcp_compl_event_t_handler_json
2066   (vl_api_dhcp_compl_event_t * mp)
2067 {
2068   /* JSON output not supported */
2069 }
2070
2071 static void
2072 set_simple_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
2073                               u32 counter)
2074 {
2075   vat_main_t *vam = &vat_main;
2076   static u64 default_counter = 0;
2077
2078   vec_validate_init_empty (vam->simple_interface_counters, vnet_counter_type,
2079                            NULL);
2080   vec_validate_init_empty (vam->simple_interface_counters[vnet_counter_type],
2081                            sw_if_index, default_counter);
2082   vam->simple_interface_counters[vnet_counter_type][sw_if_index] = counter;
2083 }
2084
2085 static void
2086 set_combined_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
2087                                 interface_counter_t counter)
2088 {
2089   vat_main_t *vam = &vat_main;
2090   static interface_counter_t default_counter = { 0, };
2091
2092   vec_validate_init_empty (vam->combined_interface_counters,
2093                            vnet_counter_type, NULL);
2094   vec_validate_init_empty (vam->combined_interface_counters
2095                            [vnet_counter_type], sw_if_index, default_counter);
2096   vam->combined_interface_counters[vnet_counter_type][sw_if_index] = counter;
2097 }
2098
2099 static void vl_api_vnet_interface_simple_counters_t_handler
2100   (vl_api_vnet_interface_simple_counters_t * mp)
2101 {
2102   /* not supported */
2103 }
2104
2105 static void vl_api_vnet_interface_combined_counters_t_handler
2106   (vl_api_vnet_interface_combined_counters_t * mp)
2107 {
2108   /* not supported */
2109 }
2110
2111 static void vl_api_vnet_interface_simple_counters_t_handler_json
2112   (vl_api_vnet_interface_simple_counters_t * mp)
2113 {
2114   u64 *v_packets;
2115   u64 packets;
2116   u32 count;
2117   u32 first_sw_if_index;
2118   int i;
2119
2120   count = ntohl (mp->count);
2121   first_sw_if_index = ntohl (mp->first_sw_if_index);
2122
2123   v_packets = (u64 *) & mp->data;
2124   for (i = 0; i < count; i++)
2125     {
2126       packets = clib_net_to_host_u64 (clib_mem_unaligned (v_packets, u64));
2127       set_simple_interface_counter (mp->vnet_counter_type,
2128                                     first_sw_if_index + i, packets);
2129       v_packets++;
2130     }
2131 }
2132
2133 static void vl_api_vnet_interface_combined_counters_t_handler_json
2134   (vl_api_vnet_interface_combined_counters_t * mp)
2135 {
2136   interface_counter_t counter;
2137   vlib_counter_t *v;
2138   u32 first_sw_if_index;
2139   int i;
2140   u32 count;
2141
2142   count = ntohl (mp->count);
2143   first_sw_if_index = ntohl (mp->first_sw_if_index);
2144
2145   v = (vlib_counter_t *) & mp->data;
2146   for (i = 0; i < count; i++)
2147     {
2148       counter.packets =
2149         clib_net_to_host_u64 (clib_mem_unaligned (&v->packets, u64));
2150       counter.bytes =
2151         clib_net_to_host_u64 (clib_mem_unaligned (&v->bytes, u64));
2152       set_combined_interface_counter (mp->vnet_counter_type,
2153                                       first_sw_if_index + i, counter);
2154       v++;
2155     }
2156 }
2157
2158 static u32
2159 ip4_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2160 {
2161   vat_main_t *vam = &vat_main;
2162   u32 i;
2163
2164   for (i = 0; i < vec_len (vam->ip4_fib_counters_vrf_id_by_index); i++)
2165     {
2166       if (vam->ip4_fib_counters_vrf_id_by_index[i] == vrf_id)
2167         {
2168           return i;
2169         }
2170     }
2171   return ~0;
2172 }
2173
2174 static u32
2175 ip6_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2176 {
2177   vat_main_t *vam = &vat_main;
2178   u32 i;
2179
2180   for (i = 0; i < vec_len (vam->ip6_fib_counters_vrf_id_by_index); i++)
2181     {
2182       if (vam->ip6_fib_counters_vrf_id_by_index[i] == vrf_id)
2183         {
2184           return i;
2185         }
2186     }
2187   return ~0;
2188 }
2189
2190 static void vl_api_vnet_ip4_fib_counters_t_handler
2191   (vl_api_vnet_ip4_fib_counters_t * mp)
2192 {
2193   /* not supported */
2194 }
2195
2196 static void vl_api_vnet_ip4_fib_counters_t_handler_json
2197   (vl_api_vnet_ip4_fib_counters_t * mp)
2198 {
2199   vat_main_t *vam = &vat_main;
2200   vl_api_ip4_fib_counter_t *v;
2201   ip4_fib_counter_t *counter;
2202   struct in_addr ip4;
2203   u32 vrf_id;
2204   u32 vrf_index;
2205   u32 count;
2206   int i;
2207
2208   vrf_id = ntohl (mp->vrf_id);
2209   vrf_index = ip4_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2210   if (~0 == vrf_index)
2211     {
2212       vrf_index = vec_len (vam->ip4_fib_counters_vrf_id_by_index);
2213       vec_validate (vam->ip4_fib_counters_vrf_id_by_index, vrf_index);
2214       vam->ip4_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2215       vec_validate (vam->ip4_fib_counters, vrf_index);
2216       vam->ip4_fib_counters[vrf_index] = NULL;
2217     }
2218
2219   vec_free (vam->ip4_fib_counters[vrf_index]);
2220   v = (vl_api_ip4_fib_counter_t *) & mp->c;
2221   count = ntohl (mp->count);
2222   for (i = 0; i < count; i++)
2223     {
2224       vec_validate (vam->ip4_fib_counters[vrf_index], i);
2225       counter = &vam->ip4_fib_counters[vrf_index][i];
2226       clib_memcpy (&ip4, &v->address, sizeof (ip4));
2227       counter->address = ip4;
2228       counter->address_length = v->address_length;
2229       counter->packets = clib_net_to_host_u64 (v->packets);
2230       counter->bytes = clib_net_to_host_u64 (v->bytes);
2231       v++;
2232     }
2233 }
2234
2235 static void vl_api_vnet_ip4_nbr_counters_t_handler
2236   (vl_api_vnet_ip4_nbr_counters_t * mp)
2237 {
2238   /* not supported */
2239 }
2240
2241 static void vl_api_vnet_ip4_nbr_counters_t_handler_json
2242   (vl_api_vnet_ip4_nbr_counters_t * mp)
2243 {
2244   vat_main_t *vam = &vat_main;
2245   vl_api_ip4_nbr_counter_t *v;
2246   ip4_nbr_counter_t *counter;
2247   u32 sw_if_index;
2248   u32 count;
2249   int i;
2250
2251   sw_if_index = ntohl (mp->sw_if_index);
2252   count = ntohl (mp->count);
2253   vec_validate (vam->ip4_nbr_counters, sw_if_index);
2254
2255   if (mp->begin)
2256     vec_free (vam->ip4_nbr_counters[sw_if_index]);
2257
2258   v = (vl_api_ip4_nbr_counter_t *) & mp->c;
2259   for (i = 0; i < count; i++)
2260     {
2261       vec_validate (vam->ip4_nbr_counters[sw_if_index], i);
2262       counter = &vam->ip4_nbr_counters[sw_if_index][i];
2263       counter->address.s_addr = v->address;
2264       counter->packets = clib_net_to_host_u64 (v->packets);
2265       counter->bytes = clib_net_to_host_u64 (v->bytes);
2266       counter->linkt = v->link_type;
2267       v++;
2268     }
2269 }
2270
2271 static void vl_api_vnet_ip6_fib_counters_t_handler
2272   (vl_api_vnet_ip6_fib_counters_t * mp)
2273 {
2274   /* not supported */
2275 }
2276
2277 static void vl_api_vnet_ip6_fib_counters_t_handler_json
2278   (vl_api_vnet_ip6_fib_counters_t * mp)
2279 {
2280   vat_main_t *vam = &vat_main;
2281   vl_api_ip6_fib_counter_t *v;
2282   ip6_fib_counter_t *counter;
2283   struct in6_addr ip6;
2284   u32 vrf_id;
2285   u32 vrf_index;
2286   u32 count;
2287   int i;
2288
2289   vrf_id = ntohl (mp->vrf_id);
2290   vrf_index = ip6_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2291   if (~0 == vrf_index)
2292     {
2293       vrf_index = vec_len (vam->ip6_fib_counters_vrf_id_by_index);
2294       vec_validate (vam->ip6_fib_counters_vrf_id_by_index, vrf_index);
2295       vam->ip6_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2296       vec_validate (vam->ip6_fib_counters, vrf_index);
2297       vam->ip6_fib_counters[vrf_index] = NULL;
2298     }
2299
2300   vec_free (vam->ip6_fib_counters[vrf_index]);
2301   v = (vl_api_ip6_fib_counter_t *) & mp->c;
2302   count = ntohl (mp->count);
2303   for (i = 0; i < count; i++)
2304     {
2305       vec_validate (vam->ip6_fib_counters[vrf_index], i);
2306       counter = &vam->ip6_fib_counters[vrf_index][i];
2307       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2308       counter->address = ip6;
2309       counter->address_length = v->address_length;
2310       counter->packets = clib_net_to_host_u64 (v->packets);
2311       counter->bytes = clib_net_to_host_u64 (v->bytes);
2312       v++;
2313     }
2314 }
2315
2316 static void vl_api_vnet_ip6_nbr_counters_t_handler
2317   (vl_api_vnet_ip6_nbr_counters_t * mp)
2318 {
2319   /* not supported */
2320 }
2321
2322 static void vl_api_vnet_ip6_nbr_counters_t_handler_json
2323   (vl_api_vnet_ip6_nbr_counters_t * mp)
2324 {
2325   vat_main_t *vam = &vat_main;
2326   vl_api_ip6_nbr_counter_t *v;
2327   ip6_nbr_counter_t *counter;
2328   struct in6_addr ip6;
2329   u32 sw_if_index;
2330   u32 count;
2331   int i;
2332
2333   sw_if_index = ntohl (mp->sw_if_index);
2334   count = ntohl (mp->count);
2335   vec_validate (vam->ip6_nbr_counters, sw_if_index);
2336
2337   if (mp->begin)
2338     vec_free (vam->ip6_nbr_counters[sw_if_index]);
2339
2340   v = (vl_api_ip6_nbr_counter_t *) & mp->c;
2341   for (i = 0; i < count; i++)
2342     {
2343       vec_validate (vam->ip6_nbr_counters[sw_if_index], i);
2344       counter = &vam->ip6_nbr_counters[sw_if_index][i];
2345       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2346       counter->address = ip6;
2347       counter->packets = clib_net_to_host_u64 (v->packets);
2348       counter->bytes = clib_net_to_host_u64 (v->bytes);
2349       v++;
2350     }
2351 }
2352
2353 static void vl_api_get_first_msg_id_reply_t_handler
2354   (vl_api_get_first_msg_id_reply_t * mp)
2355 {
2356   vat_main_t *vam = &vat_main;
2357   i32 retval = ntohl (mp->retval);
2358
2359   if (vam->async_mode)
2360     {
2361       vam->async_errors += (retval < 0);
2362     }
2363   else
2364     {
2365       vam->retval = retval;
2366       vam->result_ready = 1;
2367     }
2368   if (retval >= 0)
2369     {
2370       errmsg ("first message id %d", ntohs (mp->first_msg_id));
2371     }
2372 }
2373
2374 static void vl_api_get_first_msg_id_reply_t_handler_json
2375   (vl_api_get_first_msg_id_reply_t * mp)
2376 {
2377   vat_main_t *vam = &vat_main;
2378   vat_json_node_t node;
2379
2380   vat_json_init_object (&node);
2381   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2382   vat_json_object_add_uint (&node, "first_msg_id",
2383                             (uint) ntohs (mp->first_msg_id));
2384
2385   vat_json_print (vam->ofp, &node);
2386   vat_json_free (&node);
2387
2388   vam->retval = ntohl (mp->retval);
2389   vam->result_ready = 1;
2390 }
2391
2392 static void vl_api_get_node_graph_reply_t_handler
2393   (vl_api_get_node_graph_reply_t * mp)
2394 {
2395   vat_main_t *vam = &vat_main;
2396   api_main_t *am = &api_main;
2397   i32 retval = ntohl (mp->retval);
2398   u8 *pvt_copy, *reply;
2399   void *oldheap;
2400   vlib_node_t *node;
2401   int i;
2402
2403   if (vam->async_mode)
2404     {
2405       vam->async_errors += (retval < 0);
2406     }
2407   else
2408     {
2409       vam->retval = retval;
2410       vam->result_ready = 1;
2411     }
2412
2413   /* "Should never happen..." */
2414   if (retval != 0)
2415     return;
2416
2417   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2418   pvt_copy = vec_dup (reply);
2419
2420   /* Toss the shared-memory original... */
2421   pthread_mutex_lock (&am->vlib_rp->mutex);
2422   oldheap = svm_push_data_heap (am->vlib_rp);
2423
2424   vec_free (reply);
2425
2426   svm_pop_heap (oldheap);
2427   pthread_mutex_unlock (&am->vlib_rp->mutex);
2428
2429   if (vam->graph_nodes)
2430     {
2431       hash_free (vam->graph_node_index_by_name);
2432
2433       for (i = 0; i < vec_len (vam->graph_nodes); i++)
2434         {
2435           node = vam->graph_nodes[i];
2436           vec_free (node->name);
2437           vec_free (node->next_nodes);
2438           vec_free (node);
2439         }
2440       vec_free (vam->graph_nodes);
2441     }
2442
2443   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2444   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2445   vec_free (pvt_copy);
2446
2447   for (i = 0; i < vec_len (vam->graph_nodes); i++)
2448     {
2449       node = vam->graph_nodes[i];
2450       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2451     }
2452 }
2453
2454 static void vl_api_get_node_graph_reply_t_handler_json
2455   (vl_api_get_node_graph_reply_t * mp)
2456 {
2457   vat_main_t *vam = &vat_main;
2458   api_main_t *am = &api_main;
2459   void *oldheap;
2460   vat_json_node_t node;
2461   u8 *reply;
2462
2463   /* $$$$ make this real? */
2464   vat_json_init_object (&node);
2465   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2466   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2467
2468   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2469
2470   /* Toss the shared-memory original... */
2471   pthread_mutex_lock (&am->vlib_rp->mutex);
2472   oldheap = svm_push_data_heap (am->vlib_rp);
2473
2474   vec_free (reply);
2475
2476   svm_pop_heap (oldheap);
2477   pthread_mutex_unlock (&am->vlib_rp->mutex);
2478
2479   vat_json_print (vam->ofp, &node);
2480   vat_json_free (&node);
2481
2482   vam->retval = ntohl (mp->retval);
2483   vam->result_ready = 1;
2484 }
2485
2486 static void
2487 vl_api_one_locator_details_t_handler (vl_api_one_locator_details_t * mp)
2488 {
2489   vat_main_t *vam = &vat_main;
2490   u8 *s = 0;
2491
2492   if (mp->local)
2493     {
2494       s = format (s, "%=16d%=16d%=16d",
2495                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
2496     }
2497   else
2498     {
2499       s = format (s, "%=16U%=16d%=16d",
2500                   mp->is_ipv6 ? format_ip6_address :
2501                   format_ip4_address,
2502                   mp->ip_address, mp->priority, mp->weight);
2503     }
2504
2505   print (vam->ofp, "%v", s);
2506   vec_free (s);
2507 }
2508
2509 static void
2510 vl_api_one_locator_details_t_handler_json (vl_api_one_locator_details_t * mp)
2511 {
2512   vat_main_t *vam = &vat_main;
2513   vat_json_node_t *node = NULL;
2514   struct in6_addr ip6;
2515   struct in_addr ip4;
2516
2517   if (VAT_JSON_ARRAY != vam->json_tree.type)
2518     {
2519       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2520       vat_json_init_array (&vam->json_tree);
2521     }
2522   node = vat_json_array_add (&vam->json_tree);
2523   vat_json_init_object (node);
2524
2525   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2526   vat_json_object_add_uint (node, "priority", mp->priority);
2527   vat_json_object_add_uint (node, "weight", mp->weight);
2528
2529   if (mp->local)
2530     vat_json_object_add_uint (node, "sw_if_index",
2531                               clib_net_to_host_u32 (mp->sw_if_index));
2532   else
2533     {
2534       if (mp->is_ipv6)
2535         {
2536           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2537           vat_json_object_add_ip6 (node, "address", ip6);
2538         }
2539       else
2540         {
2541           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2542           vat_json_object_add_ip4 (node, "address", ip4);
2543         }
2544     }
2545 }
2546
2547 static void
2548 vl_api_one_locator_set_details_t_handler (vl_api_one_locator_set_details_t *
2549                                           mp)
2550 {
2551   vat_main_t *vam = &vat_main;
2552   u8 *ls_name = 0;
2553
2554   ls_name = format (0, "%s", mp->ls_name);
2555
2556   print (vam->ofp, "%=10d%=15v", clib_net_to_host_u32 (mp->ls_index),
2557          ls_name);
2558   vec_free (ls_name);
2559 }
2560
2561 static void
2562   vl_api_one_locator_set_details_t_handler_json
2563   (vl_api_one_locator_set_details_t * mp)
2564 {
2565   vat_main_t *vam = &vat_main;
2566   vat_json_node_t *node = 0;
2567   u8 *ls_name = 0;
2568
2569   ls_name = format (0, "%s", mp->ls_name);
2570   vec_add1 (ls_name, 0);
2571
2572   if (VAT_JSON_ARRAY != vam->json_tree.type)
2573     {
2574       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2575       vat_json_init_array (&vam->json_tree);
2576     }
2577   node = vat_json_array_add (&vam->json_tree);
2578
2579   vat_json_init_object (node);
2580   vat_json_object_add_string_copy (node, "ls_name", ls_name);
2581   vat_json_object_add_uint (node, "ls_index",
2582                             clib_net_to_host_u32 (mp->ls_index));
2583   vec_free (ls_name);
2584 }
2585
2586 typedef struct
2587 {
2588   u32 spi;
2589   u8 si;
2590 } __attribute__ ((__packed__)) lisp_nsh_api_t;
2591
2592 uword
2593 unformat_nsh_address (unformat_input_t * input, va_list * args)
2594 {
2595   lisp_nsh_api_t *nsh = va_arg (*args, lisp_nsh_api_t *);
2596   return unformat (input, "SPI:%d SI:%d", &nsh->spi, &nsh->si);
2597 }
2598
2599 u8 *
2600 format_nsh_address_vat (u8 * s, va_list * args)
2601 {
2602   nsh_t *a = va_arg (*args, nsh_t *);
2603   return format (s, "SPI:%d SI:%d", clib_net_to_host_u32 (a->spi), a->si);
2604 }
2605
2606 static u8 *
2607 format_lisp_flat_eid (u8 * s, va_list * args)
2608 {
2609   u32 type = va_arg (*args, u32);
2610   u8 *eid = va_arg (*args, u8 *);
2611   u32 eid_len = va_arg (*args, u32);
2612
2613   switch (type)
2614     {
2615     case 0:
2616       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
2617     case 1:
2618       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
2619     case 2:
2620       return format (s, "%U", format_ethernet_address, eid);
2621     case 3:
2622       return format (s, "%U", format_nsh_address_vat, eid);
2623     }
2624   return 0;
2625 }
2626
2627 static u8 *
2628 format_lisp_eid_vat (u8 * s, va_list * args)
2629 {
2630   u32 type = va_arg (*args, u32);
2631   u8 *eid = va_arg (*args, u8 *);
2632   u32 eid_len = va_arg (*args, u32);
2633   u8 *seid = va_arg (*args, u8 *);
2634   u32 seid_len = va_arg (*args, u32);
2635   u32 is_src_dst = va_arg (*args, u32);
2636
2637   if (is_src_dst)
2638     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
2639
2640   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
2641
2642   return s;
2643 }
2644
2645 static void
2646 vl_api_one_eid_table_details_t_handler (vl_api_one_eid_table_details_t * mp)
2647 {
2648   vat_main_t *vam = &vat_main;
2649   u8 *s = 0, *eid = 0;
2650
2651   if (~0 == mp->locator_set_index)
2652     s = format (0, "action: %d", mp->action);
2653   else
2654     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
2655
2656   eid = format (0, "%U", format_lisp_eid_vat,
2657                 mp->eid_type,
2658                 mp->eid,
2659                 mp->eid_prefix_len,
2660                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2661   vec_add1 (eid, 0);
2662
2663   print (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s",
2664          clib_net_to_host_u32 (mp->vni),
2665          eid,
2666          mp->is_local ? "local" : "remote",
2667          s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
2668          clib_net_to_host_u16 (mp->key_id), mp->key);
2669
2670   vec_free (s);
2671   vec_free (eid);
2672 }
2673
2674 static void
2675 vl_api_one_eid_table_details_t_handler_json (vl_api_one_eid_table_details_t
2676                                              * mp)
2677 {
2678   vat_main_t *vam = &vat_main;
2679   vat_json_node_t *node = 0;
2680   u8 *eid = 0;
2681
2682   if (VAT_JSON_ARRAY != vam->json_tree.type)
2683     {
2684       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2685       vat_json_init_array (&vam->json_tree);
2686     }
2687   node = vat_json_array_add (&vam->json_tree);
2688
2689   vat_json_init_object (node);
2690   if (~0 == mp->locator_set_index)
2691     vat_json_object_add_uint (node, "action", mp->action);
2692   else
2693     vat_json_object_add_uint (node, "locator_set_index",
2694                               clib_net_to_host_u32 (mp->locator_set_index));
2695
2696   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
2697   if (mp->eid_type == 3)
2698     {
2699       vat_json_node_t *nsh_json = vat_json_object_add (node, "eid");
2700       vat_json_init_object (nsh_json);
2701       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) mp->eid;
2702       vat_json_object_add_uint (nsh_json, "spi",
2703                                 clib_net_to_host_u32 (nsh->spi));
2704       vat_json_object_add_uint (nsh_json, "si", nsh->si);
2705     }
2706   else
2707     {
2708       eid = format (0, "%U", format_lisp_eid_vat,
2709                     mp->eid_type,
2710                     mp->eid,
2711                     mp->eid_prefix_len,
2712                     mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2713       vec_add1 (eid, 0);
2714       vat_json_object_add_string_copy (node, "eid", eid);
2715       vec_free (eid);
2716     }
2717   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2718   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
2719   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
2720
2721   if (mp->key_id)
2722     {
2723       vat_json_object_add_uint (node, "key_id",
2724                                 clib_net_to_host_u16 (mp->key_id));
2725       vat_json_object_add_string_copy (node, "key", mp->key);
2726     }
2727 }
2728
2729 static void
2730 vl_api_one_stats_details_t_handler (vl_api_one_stats_details_t * mp)
2731 {
2732   vat_main_t *vam = &vat_main;
2733   u8 *seid = 0, *deid = 0;
2734   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
2735
2736   deid = format (0, "%U", format_lisp_eid_vat,
2737                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
2738
2739   seid = format (0, "%U", format_lisp_eid_vat,
2740                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
2741
2742   vec_add1 (deid, 0);
2743   vec_add1 (seid, 0);
2744
2745   if (mp->is_ip4)
2746     format_ip_address_fcn = format_ip4_address;
2747   else
2748     format_ip_address_fcn = format_ip6_address;
2749
2750
2751   print (vam->ofp, "([%d] %s %s) (%U %U) %u %u",
2752          clib_net_to_host_u32 (mp->vni),
2753          seid, deid,
2754          format_ip_address_fcn, mp->lloc,
2755          format_ip_address_fcn, mp->rloc,
2756          clib_net_to_host_u32 (mp->pkt_count),
2757          clib_net_to_host_u32 (mp->bytes));
2758
2759   vec_free (deid);
2760   vec_free (seid);
2761 }
2762
2763 static void
2764 vl_api_one_stats_details_t_handler_json (vl_api_one_stats_details_t * mp)
2765 {
2766   struct in6_addr ip6;
2767   struct in_addr ip4;
2768   vat_main_t *vam = &vat_main;
2769   vat_json_node_t *node = 0;
2770   u8 *deid = 0, *seid = 0;
2771
2772   if (VAT_JSON_ARRAY != vam->json_tree.type)
2773     {
2774       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2775       vat_json_init_array (&vam->json_tree);
2776     }
2777   node = vat_json_array_add (&vam->json_tree);
2778
2779   vat_json_init_object (node);
2780   deid = format (0, "%U", format_lisp_eid_vat,
2781                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
2782
2783   seid = format (0, "%U", format_lisp_eid_vat,
2784                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
2785
2786   vec_add1 (deid, 0);
2787   vec_add1 (seid, 0);
2788
2789   vat_json_object_add_string_copy (node, "seid", seid);
2790   vat_json_object_add_string_copy (node, "deid", deid);
2791   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2792
2793   if (mp->is_ip4)
2794     {
2795       clib_memcpy (&ip4, mp->lloc, sizeof (ip4));
2796       vat_json_object_add_ip4 (node, "lloc", ip4);
2797       clib_memcpy (&ip4, mp->rloc, sizeof (ip4));
2798       vat_json_object_add_ip4 (node, "rloc", ip4);
2799     }
2800   else
2801     {
2802       clib_memcpy (&ip6, mp->lloc, sizeof (ip6));
2803       vat_json_object_add_ip6 (node, "lloc", ip6);
2804       clib_memcpy (&ip6, mp->rloc, sizeof (ip6));
2805       vat_json_object_add_ip6 (node, "rloc", ip6);
2806     }
2807   vat_json_object_add_uint (node, "pkt_count",
2808                             clib_net_to_host_u32 (mp->pkt_count));
2809   vat_json_object_add_uint (node, "bytes", clib_net_to_host_u32 (mp->bytes));
2810
2811   vec_free (deid);
2812   vec_free (seid);
2813 }
2814
2815 static void
2816   vl_api_one_eid_table_map_details_t_handler
2817   (vl_api_one_eid_table_map_details_t * mp)
2818 {
2819   vat_main_t *vam = &vat_main;
2820
2821   u8 *line = format (0, "%=10d%=10d",
2822                      clib_net_to_host_u32 (mp->vni),
2823                      clib_net_to_host_u32 (mp->dp_table));
2824   print (vam->ofp, "%v", line);
2825   vec_free (line);
2826 }
2827
2828 static void
2829   vl_api_one_eid_table_map_details_t_handler_json
2830   (vl_api_one_eid_table_map_details_t * mp)
2831 {
2832   vat_main_t *vam = &vat_main;
2833   vat_json_node_t *node = NULL;
2834
2835   if (VAT_JSON_ARRAY != vam->json_tree.type)
2836     {
2837       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2838       vat_json_init_array (&vam->json_tree);
2839     }
2840   node = vat_json_array_add (&vam->json_tree);
2841   vat_json_init_object (node);
2842   vat_json_object_add_uint (node, "dp_table",
2843                             clib_net_to_host_u32 (mp->dp_table));
2844   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2845 }
2846
2847 static void
2848   vl_api_one_eid_table_vni_details_t_handler
2849   (vl_api_one_eid_table_vni_details_t * mp)
2850 {
2851   vat_main_t *vam = &vat_main;
2852
2853   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
2854   print (vam->ofp, "%v", line);
2855   vec_free (line);
2856 }
2857
2858 static void
2859   vl_api_one_eid_table_vni_details_t_handler_json
2860   (vl_api_one_eid_table_vni_details_t * mp)
2861 {
2862   vat_main_t *vam = &vat_main;
2863   vat_json_node_t *node = NULL;
2864
2865   if (VAT_JSON_ARRAY != vam->json_tree.type)
2866     {
2867       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2868       vat_json_init_array (&vam->json_tree);
2869     }
2870   node = vat_json_array_add (&vam->json_tree);
2871   vat_json_init_object (node);
2872   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2873 }
2874
2875 static void
2876   vl_api_show_one_map_register_state_reply_t_handler
2877   (vl_api_show_one_map_register_state_reply_t * mp)
2878 {
2879   vat_main_t *vam = &vat_main;
2880   int retval = clib_net_to_host_u32 (mp->retval);
2881
2882   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
2883
2884   vam->retval = retval;
2885   vam->result_ready = 1;
2886 }
2887
2888 static void
2889   vl_api_show_one_map_register_state_reply_t_handler_json
2890   (vl_api_show_one_map_register_state_reply_t * mp)
2891 {
2892   vat_main_t *vam = &vat_main;
2893   vat_json_node_t _node, *node = &_node;
2894   int retval = clib_net_to_host_u32 (mp->retval);
2895
2896   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
2897
2898   vat_json_init_object (node);
2899   vat_json_object_add_string_copy (node, "state", s);
2900
2901   vat_json_print (vam->ofp, node);
2902   vat_json_free (node);
2903
2904   vam->retval = retval;
2905   vam->result_ready = 1;
2906   vec_free (s);
2907 }
2908
2909 static void
2910   vl_api_show_one_rloc_probe_state_reply_t_handler
2911   (vl_api_show_one_rloc_probe_state_reply_t * mp)
2912 {
2913   vat_main_t *vam = &vat_main;
2914   int retval = clib_net_to_host_u32 (mp->retval);
2915
2916   if (retval)
2917     goto end;
2918
2919   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
2920 end:
2921   vam->retval = retval;
2922   vam->result_ready = 1;
2923 }
2924
2925 static void
2926   vl_api_show_one_rloc_probe_state_reply_t_handler_json
2927   (vl_api_show_one_rloc_probe_state_reply_t * mp)
2928 {
2929   vat_main_t *vam = &vat_main;
2930   vat_json_node_t _node, *node = &_node;
2931   int retval = clib_net_to_host_u32 (mp->retval);
2932
2933   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
2934   vat_json_init_object (node);
2935   vat_json_object_add_string_copy (node, "state", s);
2936
2937   vat_json_print (vam->ofp, node);
2938   vat_json_free (node);
2939
2940   vam->retval = retval;
2941   vam->result_ready = 1;
2942   vec_free (s);
2943 }
2944
2945 static void
2946   vl_api_show_one_stats_enable_disable_reply_t_handler
2947   (vl_api_show_one_stats_enable_disable_reply_t * mp)
2948 {
2949   vat_main_t *vam = &vat_main;
2950   int retval = clib_net_to_host_u32 (mp->retval);
2951
2952   if (retval)
2953     goto end;
2954
2955   print (vam->ofp, "%s", mp->is_en ? "enabled" : "disabled");
2956 end:
2957   vam->retval = retval;
2958   vam->result_ready = 1;
2959 }
2960
2961 static void
2962   vl_api_show_one_stats_enable_disable_reply_t_handler_json
2963   (vl_api_show_one_stats_enable_disable_reply_t * mp)
2964 {
2965   vat_main_t *vam = &vat_main;
2966   vat_json_node_t _node, *node = &_node;
2967   int retval = clib_net_to_host_u32 (mp->retval);
2968
2969   u8 *s = format (0, "%s", mp->is_en ? "enabled" : "disabled");
2970   vat_json_init_object (node);
2971   vat_json_object_add_string_copy (node, "state", s);
2972
2973   vat_json_print (vam->ofp, node);
2974   vat_json_free (node);
2975
2976   vam->retval = retval;
2977   vam->result_ready = 1;
2978   vec_free (s);
2979 }
2980
2981 static void
2982 api_gpe_fwd_entry_net_to_host (vl_api_gpe_fwd_entry_t * e)
2983 {
2984   e->dp_table = clib_net_to_host_u32 (e->dp_table);
2985   e->fwd_entry_index = clib_net_to_host_u32 (e->fwd_entry_index);
2986   e->vni = clib_net_to_host_u32 (e->vni);
2987 }
2988
2989 static void
2990   gpe_fwd_entries_get_reply_t_net_to_host
2991   (vl_api_gpe_fwd_entries_get_reply_t * mp)
2992 {
2993   u32 i;
2994
2995   mp->count = clib_net_to_host_u32 (mp->count);
2996   for (i = 0; i < mp->count; i++)
2997     {
2998       api_gpe_fwd_entry_net_to_host (&mp->entries[i]);
2999     }
3000 }
3001
3002 static u8 *
3003 format_gpe_encap_mode (u8 * s, va_list * args)
3004 {
3005   u32 mode = va_arg (*args, u32);
3006
3007   switch (mode)
3008     {
3009     case 0:
3010       return format (s, "lisp");
3011     case 1:
3012       return format (s, "vxlan");
3013     }
3014   return 0;
3015 }
3016
3017 static void
3018   vl_api_gpe_get_encap_mode_reply_t_handler
3019   (vl_api_gpe_get_encap_mode_reply_t * mp)
3020 {
3021   vat_main_t *vam = &vat_main;
3022
3023   print (vam->ofp, "gpe mode: %U", format_gpe_encap_mode, mp->encap_mode);
3024   vam->retval = ntohl (mp->retval);
3025   vam->result_ready = 1;
3026 }
3027
3028 static void
3029   vl_api_gpe_get_encap_mode_reply_t_handler_json
3030   (vl_api_gpe_get_encap_mode_reply_t * mp)
3031 {
3032   vat_main_t *vam = &vat_main;
3033   vat_json_node_t node;
3034
3035   u8 *encap_mode = format (0, "%U", format_gpe_encap_mode, mp->encap_mode);
3036   vec_add1 (encap_mode, 0);
3037
3038   vat_json_init_object (&node);
3039   vat_json_object_add_string_copy (&node, "gpe_mode", encap_mode);
3040
3041   vec_free (encap_mode);
3042   vat_json_print (vam->ofp, &node);
3043   vat_json_free (&node);
3044
3045   vam->retval = ntohl (mp->retval);
3046   vam->result_ready = 1;
3047 }
3048
3049 static void
3050   vl_api_gpe_fwd_entry_path_details_t_handler
3051   (vl_api_gpe_fwd_entry_path_details_t * mp)
3052 {
3053   vat_main_t *vam = &vat_main;
3054   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3055
3056   if (mp->lcl_loc.is_ip4)
3057     format_ip_address_fcn = format_ip4_address;
3058   else
3059     format_ip_address_fcn = format_ip6_address;
3060
3061   print (vam->ofp, "w:%d %30U %30U", mp->rmt_loc.weight,
3062          format_ip_address_fcn, &mp->lcl_loc,
3063          format_ip_address_fcn, &mp->rmt_loc);
3064 }
3065
3066 static void
3067 lisp_fill_locator_node (vat_json_node_t * n, vl_api_gpe_locator_t * loc)
3068 {
3069   struct in6_addr ip6;
3070   struct in_addr ip4;
3071
3072   if (loc->is_ip4)
3073     {
3074       clib_memcpy (&ip4, loc->addr, sizeof (ip4));
3075       vat_json_object_add_ip4 (n, "address", ip4);
3076     }
3077   else
3078     {
3079       clib_memcpy (&ip6, loc->addr, sizeof (ip6));
3080       vat_json_object_add_ip6 (n, "address", ip6);
3081     }
3082   vat_json_object_add_uint (n, "weight", loc->weight);
3083 }
3084
3085 static void
3086   vl_api_gpe_fwd_entry_path_details_t_handler_json
3087   (vl_api_gpe_fwd_entry_path_details_t * mp)
3088 {
3089   vat_main_t *vam = &vat_main;
3090   vat_json_node_t *node = NULL;
3091   vat_json_node_t *loc_node;
3092
3093   if (VAT_JSON_ARRAY != vam->json_tree.type)
3094     {
3095       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3096       vat_json_init_array (&vam->json_tree);
3097     }
3098   node = vat_json_array_add (&vam->json_tree);
3099   vat_json_init_object (node);
3100
3101   loc_node = vat_json_object_add (node, "local_locator");
3102   vat_json_init_object (loc_node);
3103   lisp_fill_locator_node (loc_node, &mp->lcl_loc);
3104
3105   loc_node = vat_json_object_add (node, "remote_locator");
3106   vat_json_init_object (loc_node);
3107   lisp_fill_locator_node (loc_node, &mp->rmt_loc);
3108 }
3109
3110 static void
3111   vl_api_gpe_fwd_entries_get_reply_t_handler
3112   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3113 {
3114   vat_main_t *vam = &vat_main;
3115   u32 i;
3116   int retval = clib_net_to_host_u32 (mp->retval);
3117   vl_api_gpe_fwd_entry_t *e;
3118
3119   if (retval)
3120     goto end;
3121
3122   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3123
3124   for (i = 0; i < mp->count; i++)
3125     {
3126       e = &mp->entries[i];
3127       print (vam->ofp, "%10d %10d %U %40U", e->fwd_entry_index, e->dp_table,
3128              format_lisp_flat_eid, e->eid_type, e->leid, e->leid_prefix_len,
3129              format_lisp_flat_eid, e->eid_type, e->reid, e->reid_prefix_len);
3130     }
3131
3132 end:
3133   vam->retval = retval;
3134   vam->result_ready = 1;
3135 }
3136
3137 static void
3138   vl_api_gpe_fwd_entries_get_reply_t_handler_json
3139   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3140 {
3141   u8 *s = 0;
3142   vat_main_t *vam = &vat_main;
3143   vat_json_node_t *e = 0, root;
3144   u32 i;
3145   int retval = clib_net_to_host_u32 (mp->retval);
3146   vl_api_gpe_fwd_entry_t *fwd;
3147
3148   if (retval)
3149     goto end;
3150
3151   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3152   vat_json_init_array (&root);
3153
3154   for (i = 0; i < mp->count; i++)
3155     {
3156       e = vat_json_array_add (&root);
3157       fwd = &mp->entries[i];
3158
3159       vat_json_init_object (e);
3160       vat_json_object_add_int (e, "fwd_entry_index", fwd->fwd_entry_index);
3161       vat_json_object_add_int (e, "dp_table", fwd->dp_table);
3162       vat_json_object_add_int (e, "vni", fwd->vni);
3163       vat_json_object_add_int (e, "action", fwd->action);
3164
3165       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->leid,
3166                   fwd->leid_prefix_len);
3167       vec_add1 (s, 0);
3168       vat_json_object_add_string_copy (e, "leid", s);
3169       vec_free (s);
3170
3171       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->reid,
3172                   fwd->reid_prefix_len);
3173       vec_add1 (s, 0);
3174       vat_json_object_add_string_copy (e, "reid", s);
3175       vec_free (s);
3176     }
3177
3178   vat_json_print (vam->ofp, &root);
3179   vat_json_free (&root);
3180
3181 end:
3182   vam->retval = retval;
3183   vam->result_ready = 1;
3184 }
3185
3186 static void
3187   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler
3188   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3189 {
3190   vat_main_t *vam = &vat_main;
3191   u32 i, n;
3192   int retval = clib_net_to_host_u32 (mp->retval);
3193   vl_api_gpe_native_fwd_rpath_t *r;
3194
3195   if (retval)
3196     goto end;
3197
3198   n = clib_net_to_host_u32 (mp->count);
3199
3200   for (i = 0; i < n; i++)
3201     {
3202       r = &mp->entries[i];
3203       print (vam->ofp, "fib_index: %d sw_if_index %d nh %U",
3204              clib_net_to_host_u32 (r->fib_index),
3205              clib_net_to_host_u32 (r->nh_sw_if_index),
3206              r->is_ip4 ? format_ip4_address : format_ip6_address, r->nh_addr);
3207     }
3208
3209 end:
3210   vam->retval = retval;
3211   vam->result_ready = 1;
3212 }
3213
3214 static void
3215   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler_json
3216   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3217 {
3218   vat_main_t *vam = &vat_main;
3219   vat_json_node_t root, *e;
3220   u32 i, n;
3221   int retval = clib_net_to_host_u32 (mp->retval);
3222   vl_api_gpe_native_fwd_rpath_t *r;
3223   u8 *s;
3224
3225   if (retval)
3226     goto end;
3227
3228   n = clib_net_to_host_u32 (mp->count);
3229   vat_json_init_array (&root);
3230
3231   for (i = 0; i < n; i++)
3232     {
3233       e = vat_json_array_add (&root);
3234       vat_json_init_object (e);
3235       r = &mp->entries[i];
3236       s =
3237         format (0, "%U", r->is_ip4 ? format_ip4_address : format_ip6_address,
3238                 r->nh_addr);
3239       vec_add1 (s, 0);
3240       vat_json_object_add_string_copy (e, "ip4", s);
3241       vec_free (s);
3242
3243       vat_json_object_add_uint (e, "fib_index",
3244                                 clib_net_to_host_u32 (r->fib_index));
3245       vat_json_object_add_uint (e, "nh_sw_if_index",
3246                                 clib_net_to_host_u32 (r->nh_sw_if_index));
3247     }
3248
3249   vat_json_print (vam->ofp, &root);
3250   vat_json_free (&root);
3251
3252 end:
3253   vam->retval = retval;
3254   vam->result_ready = 1;
3255 }
3256
3257 static void
3258   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler
3259   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3260 {
3261   vat_main_t *vam = &vat_main;
3262   u32 i, n;
3263   int retval = clib_net_to_host_u32 (mp->retval);
3264
3265   if (retval)
3266     goto end;
3267
3268   n = clib_net_to_host_u32 (mp->count);
3269
3270   for (i = 0; i < n; i++)
3271     print (vam->ofp, "%d", clib_net_to_host_u32 (mp->vnis[i]));
3272
3273 end:
3274   vam->retval = retval;
3275   vam->result_ready = 1;
3276 }
3277
3278 static void
3279   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler_json
3280   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3281 {
3282   vat_main_t *vam = &vat_main;
3283   vat_json_node_t root;
3284   u32 i, n;
3285   int retval = clib_net_to_host_u32 (mp->retval);
3286
3287   if (retval)
3288     goto end;
3289
3290   n = clib_net_to_host_u32 (mp->count);
3291   vat_json_init_array (&root);
3292
3293   for (i = 0; i < n; i++)
3294     vat_json_array_add_uint (&root, clib_net_to_host_u32 (mp->vnis[i]));
3295
3296   vat_json_print (vam->ofp, &root);
3297   vat_json_free (&root);
3298
3299 end:
3300   vam->retval = retval;
3301   vam->result_ready = 1;
3302 }
3303
3304 static void
3305   vl_api_one_l2_arp_entries_get_reply_t_handler
3306   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3307 {
3308   vat_main_t *vam = &vat_main;
3309   u32 i, n;
3310   int retval = clib_net_to_host_u32 (mp->retval);
3311
3312   if (retval)
3313     goto end;
3314
3315   n = clib_net_to_host_u32 (mp->count);
3316
3317   for (i = 0; i < n; i++)
3318     print (vam->ofp, "%U -> %U", format_ip4_address, &mp->entries[i].ip4,
3319            format_ethernet_address, mp->entries[i].mac);
3320
3321 end:
3322   vam->retval = retval;
3323   vam->result_ready = 1;
3324 }
3325
3326 static void
3327   vl_api_one_l2_arp_entries_get_reply_t_handler_json
3328   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3329 {
3330   u8 *s = 0;
3331   vat_main_t *vam = &vat_main;
3332   vat_json_node_t *e = 0, root;
3333   u32 i, n;
3334   int retval = clib_net_to_host_u32 (mp->retval);
3335   vl_api_one_l2_arp_entry_t *arp_entry;
3336
3337   if (retval)
3338     goto end;
3339
3340   n = clib_net_to_host_u32 (mp->count);
3341   vat_json_init_array (&root);
3342
3343   for (i = 0; i < n; i++)
3344     {
3345       e = vat_json_array_add (&root);
3346       arp_entry = &mp->entries[i];
3347
3348       vat_json_init_object (e);
3349       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3350       vec_add1 (s, 0);
3351
3352       vat_json_object_add_string_copy (e, "mac", s);
3353       vec_free (s);
3354
3355       s = format (0, "%U", format_ip4_address, &arp_entry->ip4);
3356       vec_add1 (s, 0);
3357       vat_json_object_add_string_copy (e, "ip4", s);
3358       vec_free (s);
3359     }
3360
3361   vat_json_print (vam->ofp, &root);
3362   vat_json_free (&root);
3363
3364 end:
3365   vam->retval = retval;
3366   vam->result_ready = 1;
3367 }
3368
3369 static void
3370   vl_api_one_l2_arp_bd_get_reply_t_handler
3371   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3372 {
3373   vat_main_t *vam = &vat_main;
3374   u32 i, n;
3375   int retval = clib_net_to_host_u32 (mp->retval);
3376
3377   if (retval)
3378     goto end;
3379
3380   n = clib_net_to_host_u32 (mp->count);
3381
3382   for (i = 0; i < n; i++)
3383     {
3384       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3385     }
3386
3387 end:
3388   vam->retval = retval;
3389   vam->result_ready = 1;
3390 }
3391
3392 static void
3393   vl_api_one_l2_arp_bd_get_reply_t_handler_json
3394   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3395 {
3396   vat_main_t *vam = &vat_main;
3397   vat_json_node_t root;
3398   u32 i, n;
3399   int retval = clib_net_to_host_u32 (mp->retval);
3400
3401   if (retval)
3402     goto end;
3403
3404   n = clib_net_to_host_u32 (mp->count);
3405   vat_json_init_array (&root);
3406
3407   for (i = 0; i < n; i++)
3408     {
3409       vat_json_array_add_uint (&root,
3410                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3411     }
3412
3413   vat_json_print (vam->ofp, &root);
3414   vat_json_free (&root);
3415
3416 end:
3417   vam->retval = retval;
3418   vam->result_ready = 1;
3419 }
3420
3421 static void
3422   vl_api_one_adjacencies_get_reply_t_handler
3423   (vl_api_one_adjacencies_get_reply_t * mp)
3424 {
3425   vat_main_t *vam = &vat_main;
3426   u32 i, n;
3427   int retval = clib_net_to_host_u32 (mp->retval);
3428   vl_api_one_adjacency_t *a;
3429
3430   if (retval)
3431     goto end;
3432
3433   n = clib_net_to_host_u32 (mp->count);
3434
3435   for (i = 0; i < n; i++)
3436     {
3437       a = &mp->adjacencies[i];
3438       print (vam->ofp, "%U %40U",
3439              format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
3440              format_lisp_flat_eid, a->eid_type, a->reid, a->reid_prefix_len);
3441     }
3442
3443 end:
3444   vam->retval = retval;
3445   vam->result_ready = 1;
3446 }
3447
3448 static void
3449   vl_api_one_adjacencies_get_reply_t_handler_json
3450   (vl_api_one_adjacencies_get_reply_t * mp)
3451 {
3452   u8 *s = 0;
3453   vat_main_t *vam = &vat_main;
3454   vat_json_node_t *e = 0, root;
3455   u32 i, n;
3456   int retval = clib_net_to_host_u32 (mp->retval);
3457   vl_api_one_adjacency_t *a;
3458
3459   if (retval)
3460     goto end;
3461
3462   n = clib_net_to_host_u32 (mp->count);
3463   vat_json_init_array (&root);
3464
3465   for (i = 0; i < n; i++)
3466     {
3467       e = vat_json_array_add (&root);
3468       a = &mp->adjacencies[i];
3469
3470       vat_json_init_object (e);
3471       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
3472                   a->leid_prefix_len);
3473       vec_add1 (s, 0);
3474       vat_json_object_add_string_copy (e, "leid", s);
3475       vec_free (s);
3476
3477       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
3478                   a->reid_prefix_len);
3479       vec_add1 (s, 0);
3480       vat_json_object_add_string_copy (e, "reid", s);
3481       vec_free (s);
3482     }
3483
3484   vat_json_print (vam->ofp, &root);
3485   vat_json_free (&root);
3486
3487 end:
3488   vam->retval = retval;
3489   vam->result_ready = 1;
3490 }
3491
3492 static void
3493 vl_api_one_map_server_details_t_handler (vl_api_one_map_server_details_t * mp)
3494 {
3495   vat_main_t *vam = &vat_main;
3496
3497   print (vam->ofp, "%=20U",
3498          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
3499          mp->ip_address);
3500 }
3501
3502 static void
3503   vl_api_one_map_server_details_t_handler_json
3504   (vl_api_one_map_server_details_t * mp)
3505 {
3506   vat_main_t *vam = &vat_main;
3507   vat_json_node_t *node = NULL;
3508   struct in6_addr ip6;
3509   struct in_addr ip4;
3510
3511   if (VAT_JSON_ARRAY != vam->json_tree.type)
3512     {
3513       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3514       vat_json_init_array (&vam->json_tree);
3515     }
3516   node = vat_json_array_add (&vam->json_tree);
3517
3518   vat_json_init_object (node);
3519   if (mp->is_ipv6)
3520     {
3521       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
3522       vat_json_object_add_ip6 (node, "map-server", ip6);
3523     }
3524   else
3525     {
3526       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
3527       vat_json_object_add_ip4 (node, "map-server", ip4);
3528     }
3529 }
3530
3531 static void
3532 vl_api_one_map_resolver_details_t_handler (vl_api_one_map_resolver_details_t
3533                                            * mp)
3534 {
3535   vat_main_t *vam = &vat_main;
3536
3537   print (vam->ofp, "%=20U",
3538          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
3539          mp->ip_address);
3540 }
3541
3542 static void
3543   vl_api_one_map_resolver_details_t_handler_json
3544   (vl_api_one_map_resolver_details_t * mp)
3545 {
3546   vat_main_t *vam = &vat_main;
3547   vat_json_node_t *node = NULL;
3548   struct in6_addr ip6;
3549   struct in_addr ip4;
3550
3551   if (VAT_JSON_ARRAY != vam->json_tree.type)
3552     {
3553       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3554       vat_json_init_array (&vam->json_tree);
3555     }
3556   node = vat_json_array_add (&vam->json_tree);
3557
3558   vat_json_init_object (node);
3559   if (mp->is_ipv6)
3560     {
3561       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
3562       vat_json_object_add_ip6 (node, "map resolver", ip6);
3563     }
3564   else
3565     {
3566       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
3567       vat_json_object_add_ip4 (node, "map resolver", ip4);
3568     }
3569 }
3570
3571 static void
3572 vl_api_show_one_status_reply_t_handler (vl_api_show_one_status_reply_t * mp)
3573 {
3574   vat_main_t *vam = &vat_main;
3575   i32 retval = ntohl (mp->retval);
3576
3577   if (0 <= retval)
3578     {
3579       print (vam->ofp, "feature: %s\ngpe: %s",
3580              mp->feature_status ? "enabled" : "disabled",
3581              mp->gpe_status ? "enabled" : "disabled");
3582     }
3583
3584   vam->retval = retval;
3585   vam->result_ready = 1;
3586 }
3587
3588 static void
3589   vl_api_show_one_status_reply_t_handler_json
3590   (vl_api_show_one_status_reply_t * mp)
3591 {
3592   vat_main_t *vam = &vat_main;
3593   vat_json_node_t node;
3594   u8 *gpe_status = NULL;
3595   u8 *feature_status = NULL;
3596
3597   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
3598   feature_status = format (0, "%s",
3599                            mp->feature_status ? "enabled" : "disabled");
3600   vec_add1 (gpe_status, 0);
3601   vec_add1 (feature_status, 0);
3602
3603   vat_json_init_object (&node);
3604   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
3605   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
3606
3607   vec_free (gpe_status);
3608   vec_free (feature_status);
3609
3610   vat_json_print (vam->ofp, &node);
3611   vat_json_free (&node);
3612
3613   vam->retval = ntohl (mp->retval);
3614   vam->result_ready = 1;
3615 }
3616
3617 static void
3618   vl_api_one_get_map_request_itr_rlocs_reply_t_handler
3619   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
3620 {
3621   vat_main_t *vam = &vat_main;
3622   i32 retval = ntohl (mp->retval);
3623
3624   if (retval >= 0)
3625     {
3626       print (vam->ofp, "%=20s", mp->locator_set_name);
3627     }
3628
3629   vam->retval = retval;
3630   vam->result_ready = 1;
3631 }
3632
3633 static void
3634   vl_api_one_get_map_request_itr_rlocs_reply_t_handler_json
3635   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
3636 {
3637   vat_main_t *vam = &vat_main;
3638   vat_json_node_t *node = NULL;
3639
3640   if (VAT_JSON_ARRAY != vam->json_tree.type)
3641     {
3642       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3643       vat_json_init_array (&vam->json_tree);
3644     }
3645   node = vat_json_array_add (&vam->json_tree);
3646
3647   vat_json_init_object (node);
3648   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
3649
3650   vat_json_print (vam->ofp, node);
3651   vat_json_free (node);
3652
3653   vam->retval = ntohl (mp->retval);
3654   vam->result_ready = 1;
3655 }
3656
3657 static u8 *
3658 format_lisp_map_request_mode (u8 * s, va_list * args)
3659 {
3660   u32 mode = va_arg (*args, u32);
3661
3662   switch (mode)
3663     {
3664     case 0:
3665       return format (0, "dst-only");
3666     case 1:
3667       return format (0, "src-dst");
3668     }
3669   return 0;
3670 }
3671
3672 static void
3673   vl_api_show_one_map_request_mode_reply_t_handler
3674   (vl_api_show_one_map_request_mode_reply_t * mp)
3675 {
3676   vat_main_t *vam = &vat_main;
3677   i32 retval = ntohl (mp->retval);
3678
3679   if (0 <= retval)
3680     {
3681       u32 mode = mp->mode;
3682       print (vam->ofp, "map_request_mode: %U",
3683              format_lisp_map_request_mode, mode);
3684     }
3685
3686   vam->retval = retval;
3687   vam->result_ready = 1;
3688 }
3689
3690 static void
3691   vl_api_show_one_map_request_mode_reply_t_handler_json
3692   (vl_api_show_one_map_request_mode_reply_t * mp)
3693 {
3694   vat_main_t *vam = &vat_main;
3695   vat_json_node_t node;
3696   u8 *s = 0;
3697   u32 mode;
3698
3699   mode = mp->mode;
3700   s = format (0, "%U", format_lisp_map_request_mode, mode);
3701   vec_add1 (s, 0);
3702
3703   vat_json_init_object (&node);
3704   vat_json_object_add_string_copy (&node, "map_request_mode", s);
3705   vat_json_print (vam->ofp, &node);
3706   vat_json_free (&node);
3707
3708   vec_free (s);
3709   vam->retval = ntohl (mp->retval);
3710   vam->result_ready = 1;
3711 }
3712
3713 static void
3714   vl_api_show_one_use_petr_reply_t_handler
3715   (vl_api_show_one_use_petr_reply_t * mp)
3716 {
3717   vat_main_t *vam = &vat_main;
3718   i32 retval = ntohl (mp->retval);
3719
3720   if (0 <= retval)
3721     {
3722       print (vam->ofp, "%s\n", mp->status ? "enabled" : "disabled");
3723       if (mp->status)
3724         {
3725           print (vam->ofp, "Proxy-ETR address; %U",
3726                  mp->is_ip4 ? format_ip4_address : format_ip6_address,
3727                  mp->address);
3728         }
3729     }
3730
3731   vam->retval = retval;
3732   vam->result_ready = 1;
3733 }
3734
3735 static void
3736   vl_api_show_one_use_petr_reply_t_handler_json
3737   (vl_api_show_one_use_petr_reply_t * mp)
3738 {
3739   vat_main_t *vam = &vat_main;
3740   vat_json_node_t node;
3741   u8 *status = 0;
3742   struct in_addr ip4;
3743   struct in6_addr ip6;
3744
3745   status = format (0, "%s", mp->status ? "enabled" : "disabled");
3746   vec_add1 (status, 0);
3747
3748   vat_json_init_object (&node);
3749   vat_json_object_add_string_copy (&node, "status", status);
3750   if (mp->status)
3751     {
3752       if (mp->is_ip4)
3753         {
3754           clib_memcpy (&ip6, mp->address, sizeof (ip6));
3755           vat_json_object_add_ip6 (&node, "address", ip6);
3756         }
3757       else
3758         {
3759           clib_memcpy (&ip4, mp->address, sizeof (ip4));
3760           vat_json_object_add_ip4 (&node, "address", ip4);
3761         }
3762     }
3763
3764   vec_free (status);
3765
3766   vat_json_print (vam->ofp, &node);
3767   vat_json_free (&node);
3768
3769   vam->retval = ntohl (mp->retval);
3770   vam->result_ready = 1;
3771 }
3772
3773 static void
3774   vl_api_show_one_nsh_mapping_reply_t_handler
3775   (vl_api_show_one_nsh_mapping_reply_t * mp)
3776 {
3777   vat_main_t *vam = &vat_main;
3778   i32 retval = ntohl (mp->retval);
3779
3780   if (0 <= retval)
3781     {
3782       print (vam->ofp, "%-20s%-16s",
3783              mp->is_set ? "set" : "not-set",
3784              mp->is_set ? (char *) mp->locator_set_name : "");
3785     }
3786
3787   vam->retval = retval;
3788   vam->result_ready = 1;
3789 }
3790
3791 static void
3792   vl_api_show_one_nsh_mapping_reply_t_handler_json
3793   (vl_api_show_one_nsh_mapping_reply_t * mp)
3794 {
3795   vat_main_t *vam = &vat_main;
3796   vat_json_node_t node;
3797   u8 *status = 0;
3798
3799   status = format (0, "%s", mp->is_set ? "yes" : "no");
3800   vec_add1 (status, 0);
3801
3802   vat_json_init_object (&node);
3803   vat_json_object_add_string_copy (&node, "is_set", status);
3804   if (mp->is_set)
3805     {
3806       vat_json_object_add_string_copy (&node, "locator_set",
3807                                        mp->locator_set_name);
3808     }
3809
3810   vec_free (status);
3811
3812   vat_json_print (vam->ofp, &node);
3813   vat_json_free (&node);
3814
3815   vam->retval = ntohl (mp->retval);
3816   vam->result_ready = 1;
3817 }
3818
3819 static void
3820 vl_api_show_one_pitr_reply_t_handler (vl_api_show_one_pitr_reply_t * mp)
3821 {
3822   vat_main_t *vam = &vat_main;
3823   i32 retval = ntohl (mp->retval);
3824
3825   if (0 <= retval)
3826     {
3827       print (vam->ofp, "%-20s%-16s",
3828              mp->status ? "enabled" : "disabled",
3829              mp->status ? (char *) mp->locator_set_name : "");
3830     }
3831
3832   vam->retval = retval;
3833   vam->result_ready = 1;
3834 }
3835
3836 static void
3837 vl_api_show_one_pitr_reply_t_handler_json (vl_api_show_one_pitr_reply_t * mp)
3838 {
3839   vat_main_t *vam = &vat_main;
3840   vat_json_node_t node;
3841   u8 *status = 0;
3842
3843   status = format (0, "%s", mp->status ? "enabled" : "disabled");
3844   vec_add1 (status, 0);
3845
3846   vat_json_init_object (&node);
3847   vat_json_object_add_string_copy (&node, "status", status);
3848   if (mp->status)
3849     {
3850       vat_json_object_add_string_copy (&node, "locator_set",
3851                                        mp->locator_set_name);
3852     }
3853
3854   vec_free (status);
3855
3856   vat_json_print (vam->ofp, &node);
3857   vat_json_free (&node);
3858
3859   vam->retval = ntohl (mp->retval);
3860   vam->result_ready = 1;
3861 }
3862
3863 static u8 *
3864 format_policer_type (u8 * s, va_list * va)
3865 {
3866   u32 i = va_arg (*va, u32);
3867
3868   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
3869     s = format (s, "1r2c");
3870   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
3871     s = format (s, "1r3c");
3872   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
3873     s = format (s, "2r3c-2698");
3874   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
3875     s = format (s, "2r3c-4115");
3876   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
3877     s = format (s, "2r3c-mef5cf1");
3878   else
3879     s = format (s, "ILLEGAL");
3880   return s;
3881 }
3882
3883 static u8 *
3884 format_policer_rate_type (u8 * s, va_list * va)
3885 {
3886   u32 i = va_arg (*va, u32);
3887
3888   if (i == SSE2_QOS_RATE_KBPS)
3889     s = format (s, "kbps");
3890   else if (i == SSE2_QOS_RATE_PPS)
3891     s = format (s, "pps");
3892   else
3893     s = format (s, "ILLEGAL");
3894   return s;
3895 }
3896
3897 static u8 *
3898 format_policer_round_type (u8 * s, va_list * va)
3899 {
3900   u32 i = va_arg (*va, u32);
3901
3902   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
3903     s = format (s, "closest");
3904   else if (i == SSE2_QOS_ROUND_TO_UP)
3905     s = format (s, "up");
3906   else if (i == SSE2_QOS_ROUND_TO_DOWN)
3907     s = format (s, "down");
3908   else
3909     s = format (s, "ILLEGAL");
3910   return s;
3911 }
3912
3913 static u8 *
3914 format_policer_action_type (u8 * s, va_list * va)
3915 {
3916   u32 i = va_arg (*va, u32);
3917
3918   if (i == SSE2_QOS_ACTION_DROP)
3919     s = format (s, "drop");
3920   else if (i == SSE2_QOS_ACTION_TRANSMIT)
3921     s = format (s, "transmit");
3922   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3923     s = format (s, "mark-and-transmit");
3924   else
3925     s = format (s, "ILLEGAL");
3926   return s;
3927 }
3928
3929 static u8 *
3930 format_dscp (u8 * s, va_list * va)
3931 {
3932   u32 i = va_arg (*va, u32);
3933   char *t = 0;
3934
3935   switch (i)
3936     {
3937 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
3938       foreach_vnet_dscp
3939 #undef _
3940     default:
3941       return format (s, "ILLEGAL");
3942     }
3943   s = format (s, "%s", t);
3944   return s;
3945 }
3946
3947 static void
3948 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
3949 {
3950   vat_main_t *vam = &vat_main;
3951   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
3952
3953   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3954     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
3955   else
3956     conform_dscp_str = format (0, "");
3957
3958   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3959     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
3960   else
3961     exceed_dscp_str = format (0, "");
3962
3963   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3964     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
3965   else
3966     violate_dscp_str = format (0, "");
3967
3968   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
3969          "rate type %U, round type %U, %s rate, %s color-aware, "
3970          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
3971          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
3972          "conform action %U%s, exceed action %U%s, violate action %U%s",
3973          mp->name,
3974          format_policer_type, mp->type,
3975          ntohl (mp->cir),
3976          ntohl (mp->eir),
3977          clib_net_to_host_u64 (mp->cb),
3978          clib_net_to_host_u64 (mp->eb),
3979          format_policer_rate_type, mp->rate_type,
3980          format_policer_round_type, mp->round_type,
3981          mp->single_rate ? "single" : "dual",
3982          mp->color_aware ? "is" : "not",
3983          ntohl (mp->cir_tokens_per_period),
3984          ntohl (mp->pir_tokens_per_period),
3985          ntohl (mp->scale),
3986          ntohl (mp->current_limit),
3987          ntohl (mp->current_bucket),
3988          ntohl (mp->extended_limit),
3989          ntohl (mp->extended_bucket),
3990          clib_net_to_host_u64 (mp->last_update_time),
3991          format_policer_action_type, mp->conform_action_type,
3992          conform_dscp_str,
3993          format_policer_action_type, mp->exceed_action_type,
3994          exceed_dscp_str,
3995          format_policer_action_type, mp->violate_action_type,
3996          violate_dscp_str);
3997
3998   vec_free (conform_dscp_str);
3999   vec_free (exceed_dscp_str);
4000   vec_free (violate_dscp_str);
4001 }
4002
4003 static void vl_api_policer_details_t_handler_json
4004   (vl_api_policer_details_t * mp)
4005 {
4006   vat_main_t *vam = &vat_main;
4007   vat_json_node_t *node;
4008   u8 *rate_type_str, *round_type_str, *type_str;
4009   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
4010
4011   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
4012   round_type_str =
4013     format (0, "%U", format_policer_round_type, mp->round_type);
4014   type_str = format (0, "%U", format_policer_type, mp->type);
4015   conform_action_str = format (0, "%U", format_policer_action_type,
4016                                mp->conform_action_type);
4017   exceed_action_str = format (0, "%U", format_policer_action_type,
4018                               mp->exceed_action_type);
4019   violate_action_str = format (0, "%U", format_policer_action_type,
4020                                mp->violate_action_type);
4021
4022   if (VAT_JSON_ARRAY != vam->json_tree.type)
4023     {
4024       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4025       vat_json_init_array (&vam->json_tree);
4026     }
4027   node = vat_json_array_add (&vam->json_tree);
4028
4029   vat_json_init_object (node);
4030   vat_json_object_add_string_copy (node, "name", mp->name);
4031   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
4032   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
4033   vat_json_object_add_uint (node, "cb", clib_net_to_host_u64 (mp->cb));
4034   vat_json_object_add_uint (node, "eb", clib_net_to_host_u64 (mp->eb));
4035   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
4036   vat_json_object_add_string_copy (node, "round_type", round_type_str);
4037   vat_json_object_add_string_copy (node, "type", type_str);
4038   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
4039   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
4040   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
4041   vat_json_object_add_uint (node, "cir_tokens_per_period",
4042                             ntohl (mp->cir_tokens_per_period));
4043   vat_json_object_add_uint (node, "eir_tokens_per_period",
4044                             ntohl (mp->pir_tokens_per_period));
4045   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
4046   vat_json_object_add_uint (node, "current_bucket",
4047                             ntohl (mp->current_bucket));
4048   vat_json_object_add_uint (node, "extended_limit",
4049                             ntohl (mp->extended_limit));
4050   vat_json_object_add_uint (node, "extended_bucket",
4051                             ntohl (mp->extended_bucket));
4052   vat_json_object_add_uint (node, "last_update_time",
4053                             ntohl (mp->last_update_time));
4054   vat_json_object_add_string_copy (node, "conform_action",
4055                                    conform_action_str);
4056   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4057     {
4058       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4059       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
4060       vec_free (dscp_str);
4061     }
4062   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
4063   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4064     {
4065       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4066       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
4067       vec_free (dscp_str);
4068     }
4069   vat_json_object_add_string_copy (node, "violate_action",
4070                                    violate_action_str);
4071   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4072     {
4073       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4074       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
4075       vec_free (dscp_str);
4076     }
4077
4078   vec_free (rate_type_str);
4079   vec_free (round_type_str);
4080   vec_free (type_str);
4081   vec_free (conform_action_str);
4082   vec_free (exceed_action_str);
4083   vec_free (violate_action_str);
4084 }
4085
4086 static void
4087 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
4088                                            mp)
4089 {
4090   vat_main_t *vam = &vat_main;
4091   int i, count = ntohl (mp->count);
4092
4093   if (count > 0)
4094     print (vam->ofp, "classify table ids (%d) : ", count);
4095   for (i = 0; i < count; i++)
4096     {
4097       print (vam->ofp, "%d", ntohl (mp->ids[i]));
4098       print (vam->ofp, (i < count - 1) ? "," : "");
4099     }
4100   vam->retval = ntohl (mp->retval);
4101   vam->result_ready = 1;
4102 }
4103
4104 static void
4105   vl_api_classify_table_ids_reply_t_handler_json
4106   (vl_api_classify_table_ids_reply_t * mp)
4107 {
4108   vat_main_t *vam = &vat_main;
4109   int i, count = ntohl (mp->count);
4110
4111   if (count > 0)
4112     {
4113       vat_json_node_t node;
4114
4115       vat_json_init_object (&node);
4116       for (i = 0; i < count; i++)
4117         {
4118           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
4119         }
4120       vat_json_print (vam->ofp, &node);
4121       vat_json_free (&node);
4122     }
4123   vam->retval = ntohl (mp->retval);
4124   vam->result_ready = 1;
4125 }
4126
4127 static void
4128   vl_api_classify_table_by_interface_reply_t_handler
4129   (vl_api_classify_table_by_interface_reply_t * mp)
4130 {
4131   vat_main_t *vam = &vat_main;
4132   u32 table_id;
4133
4134   table_id = ntohl (mp->l2_table_id);
4135   if (table_id != ~0)
4136     print (vam->ofp, "l2 table id : %d", table_id);
4137   else
4138     print (vam->ofp, "l2 table id : No input ACL tables configured");
4139   table_id = ntohl (mp->ip4_table_id);
4140   if (table_id != ~0)
4141     print (vam->ofp, "ip4 table id : %d", table_id);
4142   else
4143     print (vam->ofp, "ip4 table id : No input ACL tables configured");
4144   table_id = ntohl (mp->ip6_table_id);
4145   if (table_id != ~0)
4146     print (vam->ofp, "ip6 table id : %d", table_id);
4147   else
4148     print (vam->ofp, "ip6 table id : No input ACL tables configured");
4149   vam->retval = ntohl (mp->retval);
4150   vam->result_ready = 1;
4151 }
4152
4153 static void
4154   vl_api_classify_table_by_interface_reply_t_handler_json
4155   (vl_api_classify_table_by_interface_reply_t * mp)
4156 {
4157   vat_main_t *vam = &vat_main;
4158   vat_json_node_t node;
4159
4160   vat_json_init_object (&node);
4161
4162   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
4163   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
4164   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
4165
4166   vat_json_print (vam->ofp, &node);
4167   vat_json_free (&node);
4168
4169   vam->retval = ntohl (mp->retval);
4170   vam->result_ready = 1;
4171 }
4172
4173 static void vl_api_policer_add_del_reply_t_handler
4174   (vl_api_policer_add_del_reply_t * mp)
4175 {
4176   vat_main_t *vam = &vat_main;
4177   i32 retval = ntohl (mp->retval);
4178   if (vam->async_mode)
4179     {
4180       vam->async_errors += (retval < 0);
4181     }
4182   else
4183     {
4184       vam->retval = retval;
4185       vam->result_ready = 1;
4186       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
4187         /*
4188          * Note: this is just barely thread-safe, depends on
4189          * the main thread spinning waiting for an answer...
4190          */
4191         errmsg ("policer index %d", ntohl (mp->policer_index));
4192     }
4193 }
4194
4195 static void vl_api_policer_add_del_reply_t_handler_json
4196   (vl_api_policer_add_del_reply_t * mp)
4197 {
4198   vat_main_t *vam = &vat_main;
4199   vat_json_node_t node;
4200
4201   vat_json_init_object (&node);
4202   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
4203   vat_json_object_add_uint (&node, "policer_index",
4204                             ntohl (mp->policer_index));
4205
4206   vat_json_print (vam->ofp, &node);
4207   vat_json_free (&node);
4208
4209   vam->retval = ntohl (mp->retval);
4210   vam->result_ready = 1;
4211 }
4212
4213 /* Format hex dump. */
4214 u8 *
4215 format_hex_bytes (u8 * s, va_list * va)
4216 {
4217   u8 *bytes = va_arg (*va, u8 *);
4218   int n_bytes = va_arg (*va, int);
4219   uword i;
4220
4221   /* Print short or long form depending on byte count. */
4222   uword short_form = n_bytes <= 32;
4223   uword indent = format_get_indent (s);
4224
4225   if (n_bytes == 0)
4226     return s;
4227
4228   for (i = 0; i < n_bytes; i++)
4229     {
4230       if (!short_form && (i % 32) == 0)
4231         s = format (s, "%08x: ", i);
4232       s = format (s, "%02x", bytes[i]);
4233       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
4234         s = format (s, "\n%U", format_white_space, indent);
4235     }
4236
4237   return s;
4238 }
4239
4240 static void
4241 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
4242                                             * mp)
4243 {
4244   vat_main_t *vam = &vat_main;
4245   i32 retval = ntohl (mp->retval);
4246   if (retval == 0)
4247     {
4248       print (vam->ofp, "classify table info :");
4249       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
4250              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
4251              ntohl (mp->miss_next_index));
4252       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
4253              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
4254              ntohl (mp->match_n_vectors));
4255       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
4256              ntohl (mp->mask_length));
4257     }
4258   vam->retval = retval;
4259   vam->result_ready = 1;
4260 }
4261
4262 static void
4263   vl_api_classify_table_info_reply_t_handler_json
4264   (vl_api_classify_table_info_reply_t * mp)
4265 {
4266   vat_main_t *vam = &vat_main;
4267   vat_json_node_t node;
4268
4269   i32 retval = ntohl (mp->retval);
4270   if (retval == 0)
4271     {
4272       vat_json_init_object (&node);
4273
4274       vat_json_object_add_int (&node, "sessions",
4275                                ntohl (mp->active_sessions));
4276       vat_json_object_add_int (&node, "nexttbl",
4277                                ntohl (mp->next_table_index));
4278       vat_json_object_add_int (&node, "nextnode",
4279                                ntohl (mp->miss_next_index));
4280       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
4281       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
4282       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
4283       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
4284                       ntohl (mp->mask_length), 0);
4285       vat_json_object_add_string_copy (&node, "mask", s);
4286
4287       vat_json_print (vam->ofp, &node);
4288       vat_json_free (&node);
4289     }
4290   vam->retval = ntohl (mp->retval);
4291   vam->result_ready = 1;
4292 }
4293
4294 static void
4295 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
4296                                            mp)
4297 {
4298   vat_main_t *vam = &vat_main;
4299
4300   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
4301          ntohl (mp->hit_next_index), ntohl (mp->advance),
4302          ntohl (mp->opaque_index));
4303   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
4304          ntohl (mp->match_length));
4305 }
4306
4307 static void
4308   vl_api_classify_session_details_t_handler_json
4309   (vl_api_classify_session_details_t * mp)
4310 {
4311   vat_main_t *vam = &vat_main;
4312   vat_json_node_t *node = NULL;
4313
4314   if (VAT_JSON_ARRAY != vam->json_tree.type)
4315     {
4316       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4317       vat_json_init_array (&vam->json_tree);
4318     }
4319   node = vat_json_array_add (&vam->json_tree);
4320
4321   vat_json_init_object (node);
4322   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
4323   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
4324   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
4325   u8 *s =
4326     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
4327             0);
4328   vat_json_object_add_string_copy (node, "match", s);
4329 }
4330
4331 static void vl_api_pg_create_interface_reply_t_handler
4332   (vl_api_pg_create_interface_reply_t * mp)
4333 {
4334   vat_main_t *vam = &vat_main;
4335
4336   vam->retval = ntohl (mp->retval);
4337   vam->result_ready = 1;
4338 }
4339
4340 static void vl_api_pg_create_interface_reply_t_handler_json
4341   (vl_api_pg_create_interface_reply_t * mp)
4342 {
4343   vat_main_t *vam = &vat_main;
4344   vat_json_node_t node;
4345
4346   i32 retval = ntohl (mp->retval);
4347   if (retval == 0)
4348     {
4349       vat_json_init_object (&node);
4350
4351       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
4352
4353       vat_json_print (vam->ofp, &node);
4354       vat_json_free (&node);
4355     }
4356   vam->retval = ntohl (mp->retval);
4357   vam->result_ready = 1;
4358 }
4359
4360 static void vl_api_policer_classify_details_t_handler
4361   (vl_api_policer_classify_details_t * mp)
4362 {
4363   vat_main_t *vam = &vat_main;
4364
4365   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
4366          ntohl (mp->table_index));
4367 }
4368
4369 static void vl_api_policer_classify_details_t_handler_json
4370   (vl_api_policer_classify_details_t * mp)
4371 {
4372   vat_main_t *vam = &vat_main;
4373   vat_json_node_t *node;
4374
4375   if (VAT_JSON_ARRAY != vam->json_tree.type)
4376     {
4377       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4378       vat_json_init_array (&vam->json_tree);
4379     }
4380   node = vat_json_array_add (&vam->json_tree);
4381
4382   vat_json_init_object (node);
4383   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
4384   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
4385 }
4386
4387 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler
4388   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
4389 {
4390   vat_main_t *vam = &vat_main;
4391   i32 retval = ntohl (mp->retval);
4392   if (vam->async_mode)
4393     {
4394       vam->async_errors += (retval < 0);
4395     }
4396   else
4397     {
4398       vam->retval = retval;
4399       vam->sw_if_index = ntohl (mp->sw_if_index);
4400       vam->result_ready = 1;
4401     }
4402 }
4403
4404 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler_json
4405   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
4406 {
4407   vat_main_t *vam = &vat_main;
4408   vat_json_node_t node;
4409
4410   vat_json_init_object (&node);
4411   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
4412   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
4413
4414   vat_json_print (vam->ofp, &node);
4415   vat_json_free (&node);
4416
4417   vam->retval = ntohl (mp->retval);
4418   vam->result_ready = 1;
4419 }
4420
4421 static void vl_api_flow_classify_details_t_handler
4422   (vl_api_flow_classify_details_t * mp)
4423 {
4424   vat_main_t *vam = &vat_main;
4425
4426   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
4427          ntohl (mp->table_index));
4428 }
4429
4430 static void vl_api_flow_classify_details_t_handler_json
4431   (vl_api_flow_classify_details_t * mp)
4432 {
4433   vat_main_t *vam = &vat_main;
4434   vat_json_node_t *node;
4435
4436   if (VAT_JSON_ARRAY != vam->json_tree.type)
4437     {
4438       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4439       vat_json_init_array (&vam->json_tree);
4440     }
4441   node = vat_json_array_add (&vam->json_tree);
4442
4443   vat_json_init_object (node);
4444   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
4445   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
4446 }
4447
4448 #define vl_api_vnet_interface_simple_counters_t_endian vl_noop_handler
4449 #define vl_api_vnet_interface_simple_counters_t_print vl_noop_handler
4450 #define vl_api_vnet_interface_combined_counters_t_endian vl_noop_handler
4451 #define vl_api_vnet_interface_combined_counters_t_print vl_noop_handler
4452 #define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
4453 #define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler
4454 #define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler
4455 #define vl_api_vnet_ip6_fib_counters_t_print vl_noop_handler
4456 #define vl_api_vnet_ip4_nbr_counters_t_endian vl_noop_handler
4457 #define vl_api_vnet_ip4_nbr_counters_t_print vl_noop_handler
4458 #define vl_api_vnet_ip6_nbr_counters_t_endian vl_noop_handler
4459 #define vl_api_vnet_ip6_nbr_counters_t_print vl_noop_handler
4460 #define vl_api_one_adjacencies_get_reply_t_endian vl_noop_handler
4461 #define vl_api_one_adjacencies_get_reply_t_print vl_noop_handler
4462 #define vl_api_one_l2_arp_bd_get_reply_t_print vl_noop_handler
4463 #define vl_api_one_l2_arp_entries_get_reply_t_endian vl_noop_handler
4464 #define vl_api_one_l2_arp_entries_get_reply_t_print vl_noop_handler
4465 #define vl_api_one_l2_arp_bd_get_reply_t_endian vl_noop_handler
4466
4467 /*
4468  * Generate boilerplate reply handlers, which
4469  * dig the return value out of the xxx_reply_t API message,
4470  * stick it into vam->retval, and set vam->result_ready
4471  *
4472  * Could also do this by pointing N message decode slots at
4473  * a single function, but that could break in subtle ways.
4474  */
4475
4476 #define foreach_standard_reply_retval_handler           \
4477 _(sw_interface_set_flags_reply)                         \
4478 _(sw_interface_add_del_address_reply)                   \
4479 _(sw_interface_set_table_reply)                         \
4480 _(sw_interface_set_mpls_enable_reply)                   \
4481 _(sw_interface_set_vpath_reply)                         \
4482 _(sw_interface_set_vxlan_bypass_reply)                  \
4483 _(sw_interface_set_l2_bridge_reply)                     \
4484 _(bridge_domain_add_del_reply)                          \
4485 _(sw_interface_set_l2_xconnect_reply)                   \
4486 _(l2fib_add_del_reply)                                  \
4487 _(l2fib_flush_int_reply)                                \
4488 _(l2fib_flush_bd_reply)                                 \
4489 _(ip_add_del_route_reply)                               \
4490 _(ip_mroute_add_del_reply)                              \
4491 _(mpls_route_add_del_reply)                             \
4492 _(mpls_ip_bind_unbind_reply)                            \
4493 _(proxy_arp_add_del_reply)                              \
4494 _(proxy_arp_intfc_enable_disable_reply)                 \
4495 _(sw_interface_set_unnumbered_reply)                    \
4496 _(ip_neighbor_add_del_reply)                            \
4497 _(reset_vrf_reply)                                      \
4498 _(oam_add_del_reply)                                    \
4499 _(reset_fib_reply)                                      \
4500 _(dhcp_proxy_config_reply)                              \
4501 _(dhcp_proxy_set_vss_reply)                             \
4502 _(dhcp_client_config_reply)                             \
4503 _(set_ip_flow_hash_reply)                               \
4504 _(sw_interface_ip6_enable_disable_reply)                \
4505 _(sw_interface_ip6_set_link_local_address_reply)        \
4506 _(ip6nd_proxy_add_del_reply)                            \
4507 _(sw_interface_ip6nd_ra_prefix_reply)                   \
4508 _(sw_interface_ip6nd_ra_config_reply)                   \
4509 _(set_arp_neighbor_limit_reply)                         \
4510 _(l2_patch_add_del_reply)                               \
4511 _(sr_policy_add_reply)                                  \
4512 _(sr_policy_mod_reply)                                  \
4513 _(sr_policy_del_reply)                                  \
4514 _(sr_localsid_add_del_reply)                            \
4515 _(sr_steering_add_del_reply)                            \
4516 _(classify_add_del_session_reply)                       \
4517 _(classify_set_interface_ip_table_reply)                \
4518 _(classify_set_interface_l2_tables_reply)               \
4519 _(l2tpv3_set_tunnel_cookies_reply)                      \
4520 _(l2tpv3_interface_enable_disable_reply)                \
4521 _(l2tpv3_set_lookup_key_reply)                          \
4522 _(l2_fib_clear_table_reply)                             \
4523 _(l2_interface_efp_filter_reply)                        \
4524 _(l2_interface_vlan_tag_rewrite_reply)                  \
4525 _(modify_vhost_user_if_reply)                           \
4526 _(delete_vhost_user_if_reply)                           \
4527 _(want_ip4_arp_events_reply)                            \
4528 _(want_ip6_nd_events_reply)                             \
4529 _(input_acl_set_interface_reply)                        \
4530 _(ipsec_spd_add_del_reply)                              \
4531 _(ipsec_interface_add_del_spd_reply)                    \
4532 _(ipsec_spd_add_del_entry_reply)                        \
4533 _(ipsec_sad_add_del_entry_reply)                        \
4534 _(ipsec_sa_set_key_reply)                               \
4535 _(ipsec_tunnel_if_add_del_reply)                        \
4536 _(ikev2_profile_add_del_reply)                          \
4537 _(ikev2_profile_set_auth_reply)                         \
4538 _(ikev2_profile_set_id_reply)                           \
4539 _(ikev2_profile_set_ts_reply)                           \
4540 _(ikev2_set_local_key_reply)                            \
4541 _(ikev2_set_responder_reply)                            \
4542 _(ikev2_set_ike_transforms_reply)                       \
4543 _(ikev2_set_esp_transforms_reply)                       \
4544 _(ikev2_set_sa_lifetime_reply)                          \
4545 _(ikev2_initiate_sa_init_reply)                         \
4546 _(ikev2_initiate_del_ike_sa_reply)                      \
4547 _(ikev2_initiate_del_child_sa_reply)                    \
4548 _(ikev2_initiate_rekey_child_sa_reply)                  \
4549 _(delete_loopback_reply)                                \
4550 _(bd_ip_mac_add_del_reply)                              \
4551 _(map_del_domain_reply)                                 \
4552 _(map_add_del_rule_reply)                               \
4553 _(want_interface_events_reply)                          \
4554 _(want_stats_reply)                                     \
4555 _(cop_interface_enable_disable_reply)                   \
4556 _(cop_whitelist_enable_disable_reply)                   \
4557 _(sw_interface_clear_stats_reply)                       \
4558 _(ioam_enable_reply)                              \
4559 _(ioam_disable_reply)                              \
4560 _(one_add_del_locator_reply)                            \
4561 _(one_add_del_local_eid_reply)                          \
4562 _(one_add_del_remote_mapping_reply)                     \
4563 _(one_add_del_adjacency_reply)                          \
4564 _(one_add_del_map_resolver_reply)                       \
4565 _(one_add_del_map_server_reply)                         \
4566 _(one_enable_disable_reply)                             \
4567 _(one_rloc_probe_enable_disable_reply)                  \
4568 _(one_map_register_enable_disable_reply)                \
4569 _(one_pitr_set_locator_set_reply)                       \
4570 _(one_map_request_mode_reply)                           \
4571 _(one_add_del_map_request_itr_rlocs_reply)              \
4572 _(one_eid_table_add_del_map_reply)                      \
4573 _(one_use_petr_reply)                                   \
4574 _(one_stats_enable_disable_reply)                       \
4575 _(one_add_del_l2_arp_entry_reply)                       \
4576 _(one_stats_flush_reply)                                \
4577 _(gpe_enable_disable_reply)                             \
4578 _(gpe_set_encap_mode_reply)                             \
4579 _(gpe_add_del_iface_reply)                              \
4580 _(gpe_add_del_native_fwd_rpath_reply)                   \
4581 _(vxlan_gpe_add_del_tunnel_reply)                       \
4582 _(af_packet_delete_reply)                               \
4583 _(policer_classify_set_interface_reply)                 \
4584 _(netmap_create_reply)                                  \
4585 _(netmap_delete_reply)                                  \
4586 _(set_ipfix_exporter_reply)                             \
4587 _(set_ipfix_classify_stream_reply)                      \
4588 _(ipfix_classify_table_add_del_reply)                   \
4589 _(flow_classify_set_interface_reply)                    \
4590 _(sw_interface_span_enable_disable_reply)               \
4591 _(pg_capture_reply)                                     \
4592 _(pg_enable_disable_reply)                              \
4593 _(ip_source_and_port_range_check_add_del_reply)         \
4594 _(ip_source_and_port_range_check_interface_add_del_reply)\
4595 _(delete_subif_reply)                                   \
4596 _(l2_interface_pbb_tag_rewrite_reply)                   \
4597 _(punt_reply)                                           \
4598 _(feature_enable_disable_reply)                         \
4599 _(sw_interface_tag_add_del_reply)                       \
4600 _(sw_interface_set_mtu_reply)                           \
4601 _(p2p_ethernet_add_reply)                               \
4602 _(p2p_ethernet_del_reply)
4603
4604 #define _(n)                                    \
4605     static void vl_api_##n##_t_handler          \
4606     (vl_api_##n##_t * mp)                       \
4607     {                                           \
4608         vat_main_t * vam = &vat_main;           \
4609         i32 retval = ntohl(mp->retval);         \
4610         if (vam->async_mode) {                  \
4611             vam->async_errors += (retval < 0);  \
4612         } else {                                \
4613             vam->retval = retval;               \
4614             vam->result_ready = 1;              \
4615         }                                       \
4616     }
4617 foreach_standard_reply_retval_handler;
4618 #undef _
4619
4620 #define _(n)                                    \
4621     static void vl_api_##n##_t_handler_json     \
4622     (vl_api_##n##_t * mp)                       \
4623     {                                           \
4624         vat_main_t * vam = &vat_main;           \
4625         vat_json_node_t node;                   \
4626         vat_json_init_object(&node);            \
4627         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
4628         vat_json_print(vam->ofp, &node);        \
4629         vam->retval = ntohl(mp->retval);        \
4630         vam->result_ready = 1;                  \
4631     }
4632 foreach_standard_reply_retval_handler;
4633 #undef _
4634
4635 /*
4636  * Table of message reply handlers, must include boilerplate handlers
4637  * we just generated
4638  */
4639
4640 #define foreach_vpe_api_reply_msg                                       \
4641 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
4642 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
4643 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
4644 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
4645 _(CONTROL_PING_REPLY, control_ping_reply)                               \
4646 _(CLI_REPLY, cli_reply)                                                 \
4647 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
4648 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
4649   sw_interface_add_del_address_reply)                                   \
4650 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
4651 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
4652 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
4653 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
4654 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
4655   sw_interface_set_l2_xconnect_reply)                                   \
4656 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
4657   sw_interface_set_l2_bridge_reply)                                     \
4658 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
4659 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
4660 _(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply)     \
4661 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
4662 _(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply)                         \
4663 _(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply)                           \
4664 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
4665 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
4666 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
4667 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
4668 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
4669 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
4670 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
4671 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
4672 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
4673 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
4674 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
4675 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
4676   proxy_arp_intfc_enable_disable_reply)                                 \
4677 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
4678 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
4679   sw_interface_set_unnumbered_reply)                                    \
4680 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
4681 _(RESET_VRF_REPLY, reset_vrf_reply)                                     \
4682 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
4683 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
4684 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
4685 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
4686 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
4687 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
4688 _(DHCP_PROXY_DETAILS, dhcp_proxy_details)                               \
4689 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
4690 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
4691 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
4692   sw_interface_ip6_enable_disable_reply)                                \
4693 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY,                        \
4694   sw_interface_ip6_set_link_local_address_reply)                        \
4695 _(IP6ND_PROXY_ADD_DEL_REPLY, ip6nd_proxy_add_del_reply)                 \
4696 _(IP6ND_PROXY_DETAILS, ip6nd_proxy_details)                             \
4697 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
4698   sw_interface_ip6nd_ra_prefix_reply)                                   \
4699 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
4700   sw_interface_ip6nd_ra_config_reply)                                   \
4701 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
4702 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
4703 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
4704 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
4705 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
4706 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
4707 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
4708 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
4709 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
4710 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
4711 classify_set_interface_ip_table_reply)                                  \
4712 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
4713   classify_set_interface_l2_tables_reply)                               \
4714 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
4715 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
4716 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
4717 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
4718 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
4719   l2tpv3_interface_enable_disable_reply)                                \
4720 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
4721 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
4722 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
4723 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
4724 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
4725 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
4726 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
4727 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
4728 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
4729 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
4730 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
4731 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
4732 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
4733 _(SHOW_VERSION_REPLY, show_version_reply)                               \
4734 _(L2_FIB_TABLE_DETAILS, l2_fib_table_details)                           \
4735 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)           \
4736 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
4737 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
4738 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
4739 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
4740 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
4741 _(IP6_ND_EVENT, ip6_nd_event)                                           \
4742 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
4743 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
4744 _(IP_DETAILS, ip_details)                                               \
4745 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
4746 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
4747 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
4748 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
4749 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
4750 _(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply)         \
4751 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
4752 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
4753 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
4754 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
4755 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
4756 _(IKEV2_SET_RESPONDER_REPLY, ikev2_set_responder_reply)                 \
4757 _(IKEV2_SET_IKE_TRANSFORMS_REPLY, ikev2_set_ike_transforms_reply)       \
4758 _(IKEV2_SET_ESP_TRANSFORMS_REPLY, ikev2_set_esp_transforms_reply)       \
4759 _(IKEV2_SET_SA_LIFETIME_REPLY, ikev2_set_sa_lifetime_reply)             \
4760 _(IKEV2_INITIATE_SA_INIT_REPLY, ikev2_initiate_sa_init_reply)           \
4761 _(IKEV2_INITIATE_DEL_IKE_SA_REPLY, ikev2_initiate_del_ike_sa_reply)     \
4762 _(IKEV2_INITIATE_DEL_CHILD_SA_REPLY, ikev2_initiate_del_child_sa_reply) \
4763 _(IKEV2_INITIATE_REKEY_CHILD_SA_REPLY, ikev2_initiate_rekey_child_sa_reply) \
4764 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
4765 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
4766 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
4767 _(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply)                           \
4768 _(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply)                           \
4769 _(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply)                       \
4770 _(MAP_DOMAIN_DETAILS, map_domain_details)                               \
4771 _(MAP_RULE_DETAILS, map_rule_details)                                   \
4772 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
4773 _(WANT_STATS_REPLY, want_stats_reply)                                   \
4774 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
4775 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
4776 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
4777 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
4778 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
4779 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
4780 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
4781 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
4782 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
4783 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
4784 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
4785 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
4786 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
4787 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
4788 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
4789 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
4790   one_map_register_enable_disable_reply)                                \
4791 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
4792   one_rloc_probe_enable_disable_reply)                                  \
4793 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
4794 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
4795 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
4796 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
4797 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
4798 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
4799 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
4800 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
4801 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
4802 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
4803 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
4804 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
4805 _(ONE_STATS_DETAILS, one_stats_details)                                 \
4806 _(ONE_STATS_FLUSH_REPLY, one_stats_flush_reply)                         \
4807 _(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply)       \
4808 _(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,                                  \
4809   show_one_stats_enable_disable_reply)                                  \
4810 _(ONE_ADD_DEL_L2_ARP_ENTRY_REPLY, one_add_del_l2_arp_entry_reply)       \
4811 _(ONE_L2_ARP_BD_GET_REPLY, one_l2_arp_bd_get_reply)                     \
4812 _(ONE_L2_ARP_ENTRIES_GET_REPLY, one_l2_arp_entries_get_reply)           \
4813 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
4814 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
4815 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
4816 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
4817 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
4818 _(GPE_FWD_ENTRY_VNIS_GET_REPLY, gpe_fwd_entry_vnis_get_reply)           \
4819 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
4820 _(GPE_NATIVE_FWD_RPATHS_GET_REPLY, gpe_native_fwd_rpaths_get_reply)     \
4821 _(GPE_ADD_DEL_NATIVE_FWD_RPATH_REPLY,                                   \
4822   gpe_add_del_native_fwd_rpath_reply)                                   \
4823 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
4824   gpe_fwd_entry_path_details)                                           \
4825 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
4826 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
4827   one_add_del_map_request_itr_rlocs_reply)                              \
4828 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
4829   one_get_map_request_itr_rlocs_reply)                                  \
4830 _(SHOW_ONE_NSH_MAPPING_REPLY, show_one_nsh_mapping_reply)               \
4831 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
4832 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
4833 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
4834 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
4835 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
4836   show_one_map_register_state_reply)                                    \
4837 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
4838 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
4839 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
4840 _(POLICER_DETAILS, policer_details)                                     \
4841 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
4842 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
4843 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
4844 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
4845 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
4846 _(MPLS_FIB_DETAILS, mpls_fib_details)                                   \
4847 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
4848 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
4849 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
4850 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
4851 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
4852 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
4853 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
4854 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
4855 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
4856 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
4857 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
4858 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
4859 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
4860 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
4861 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
4862 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
4863 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
4864 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
4865 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
4866  ip_source_and_port_range_check_add_del_reply)                          \
4867 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
4868  ip_source_and_port_range_check_interface_add_del_reply)                \
4869 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
4870 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
4871 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
4872 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
4873 _(PUNT_REPLY, punt_reply)                                               \
4874 _(IP_FIB_DETAILS, ip_fib_details)                                       \
4875 _(IP6_FIB_DETAILS, ip6_fib_details)                                     \
4876 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
4877 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
4878 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
4879 _(SW_INTERFACE_SET_MTU_REPLY, sw_interface_set_mtu_reply)               \
4880 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
4881 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)           \
4882 _(P2P_ETHERNET_ADD_REPLY, p2p_ethernet_add_reply)                       \
4883 _(P2P_ETHERNET_DEL_REPLY, p2p_ethernet_del_reply)
4884
4885 #define foreach_standalone_reply_msg                                    \
4886 _(SW_INTERFACE_SET_FLAGS, sw_interface_set_flags)                       \
4887 _(VNET_INTERFACE_SIMPLE_COUNTERS, vnet_interface_simple_counters)       \
4888 _(VNET_INTERFACE_COMBINED_COUNTERS, vnet_interface_combined_counters)   \
4889 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
4890 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
4891 _(VNET_IP4_NBR_COUNTERS, vnet_ip4_nbr_counters)                         \
4892 _(VNET_IP6_NBR_COUNTERS, vnet_ip6_nbr_counters)
4893
4894 typedef struct
4895 {
4896   u8 *name;
4897   u32 value;
4898 } name_sort_t;
4899
4900
4901 #define STR_VTR_OP_CASE(op)     \
4902     case L2_VTR_ ## op:         \
4903         return "" # op;
4904
4905 static const char *
4906 str_vtr_op (u32 vtr_op)
4907 {
4908   switch (vtr_op)
4909     {
4910       STR_VTR_OP_CASE (DISABLED);
4911       STR_VTR_OP_CASE (PUSH_1);
4912       STR_VTR_OP_CASE (PUSH_2);
4913       STR_VTR_OP_CASE (POP_1);
4914       STR_VTR_OP_CASE (POP_2);
4915       STR_VTR_OP_CASE (TRANSLATE_1_1);
4916       STR_VTR_OP_CASE (TRANSLATE_1_2);
4917       STR_VTR_OP_CASE (TRANSLATE_2_1);
4918       STR_VTR_OP_CASE (TRANSLATE_2_2);
4919     }
4920
4921   return "UNKNOWN";
4922 }
4923
4924 static int
4925 dump_sub_interface_table (vat_main_t * vam)
4926 {
4927   const sw_interface_subif_t *sub = NULL;
4928
4929   if (vam->json_output)
4930     {
4931       clib_warning
4932         ("JSON output supported only for VPE API calls and dump_stats_table");
4933       return -99;
4934     }
4935
4936   print (vam->ofp,
4937          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
4938          "Interface", "sw_if_index",
4939          "sub id", "dot1ad", "tags", "outer id",
4940          "inner id", "exact", "default", "outer any", "inner any");
4941
4942   vec_foreach (sub, vam->sw_if_subif_table)
4943   {
4944     print (vam->ofp,
4945            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
4946            sub->interface_name,
4947            sub->sw_if_index,
4948            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
4949            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
4950            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
4951            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
4952     if (sub->vtr_op != L2_VTR_DISABLED)
4953       {
4954         print (vam->ofp,
4955                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
4956                "tag1: %d tag2: %d ]",
4957                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
4958                sub->vtr_tag1, sub->vtr_tag2);
4959       }
4960   }
4961
4962   return 0;
4963 }
4964
4965 static int
4966 name_sort_cmp (void *a1, void *a2)
4967 {
4968   name_sort_t *n1 = a1;
4969   name_sort_t *n2 = a2;
4970
4971   return strcmp ((char *) n1->name, (char *) n2->name);
4972 }
4973
4974 static int
4975 dump_interface_table (vat_main_t * vam)
4976 {
4977   hash_pair_t *p;
4978   name_sort_t *nses = 0, *ns;
4979
4980   if (vam->json_output)
4981     {
4982       clib_warning
4983         ("JSON output supported only for VPE API calls and dump_stats_table");
4984       return -99;
4985     }
4986
4987   /* *INDENT-OFF* */
4988   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
4989   ({
4990     vec_add2 (nses, ns, 1);
4991     ns->name = (u8 *)(p->key);
4992     ns->value = (u32) p->value[0];
4993   }));
4994   /* *INDENT-ON* */
4995
4996   vec_sort_with_function (nses, name_sort_cmp);
4997
4998   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
4999   vec_foreach (ns, nses)
5000   {
5001     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
5002   }
5003   vec_free (nses);
5004   return 0;
5005 }
5006
5007 static int
5008 dump_ip_table (vat_main_t * vam, int is_ipv6)
5009 {
5010   const ip_details_t *det = NULL;
5011   const ip_address_details_t *address = NULL;
5012   u32 i = ~0;
5013
5014   print (vam->ofp, "%-12s", "sw_if_index");
5015
5016   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
5017   {
5018     i++;
5019     if (!det->present)
5020       {
5021         continue;
5022       }
5023     print (vam->ofp, "%-12d", i);
5024     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
5025     if (!det->addr)
5026       {
5027         continue;
5028       }
5029     vec_foreach (address, det->addr)
5030     {
5031       print (vam->ofp,
5032              "            %-30U%-13d",
5033              is_ipv6 ? format_ip6_address : format_ip4_address,
5034              address->ip, address->prefix_length);
5035     }
5036   }
5037
5038   return 0;
5039 }
5040
5041 static int
5042 dump_ipv4_table (vat_main_t * vam)
5043 {
5044   if (vam->json_output)
5045     {
5046       clib_warning
5047         ("JSON output supported only for VPE API calls and dump_stats_table");
5048       return -99;
5049     }
5050
5051   return dump_ip_table (vam, 0);
5052 }
5053
5054 static int
5055 dump_ipv6_table (vat_main_t * vam)
5056 {
5057   if (vam->json_output)
5058     {
5059       clib_warning
5060         ("JSON output supported only for VPE API calls and dump_stats_table");
5061       return -99;
5062     }
5063
5064   return dump_ip_table (vam, 1);
5065 }
5066
5067 static char *
5068 counter_type_to_str (u8 counter_type, u8 is_combined)
5069 {
5070   if (!is_combined)
5071     {
5072       switch (counter_type)
5073         {
5074         case VNET_INTERFACE_COUNTER_DROP:
5075           return "drop";
5076         case VNET_INTERFACE_COUNTER_PUNT:
5077           return "punt";
5078         case VNET_INTERFACE_COUNTER_IP4:
5079           return "ip4";
5080         case VNET_INTERFACE_COUNTER_IP6:
5081           return "ip6";
5082         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
5083           return "rx-no-buf";
5084         case VNET_INTERFACE_COUNTER_RX_MISS:
5085           return "rx-miss";
5086         case VNET_INTERFACE_COUNTER_RX_ERROR:
5087           return "rx-error";
5088         case VNET_INTERFACE_COUNTER_TX_ERROR:
5089           return "tx-error";
5090         default:
5091           return "INVALID-COUNTER-TYPE";
5092         }
5093     }
5094   else
5095     {
5096       switch (counter_type)
5097         {
5098         case VNET_INTERFACE_COUNTER_RX:
5099           return "rx";
5100         case VNET_INTERFACE_COUNTER_TX:
5101           return "tx";
5102         default:
5103           return "INVALID-COUNTER-TYPE";
5104         }
5105     }
5106 }
5107
5108 static int
5109 dump_stats_table (vat_main_t * vam)
5110 {
5111   vat_json_node_t node;
5112   vat_json_node_t *msg_array;
5113   vat_json_node_t *msg;
5114   vat_json_node_t *counter_array;
5115   vat_json_node_t *counter;
5116   interface_counter_t c;
5117   u64 packets;
5118   ip4_fib_counter_t *c4;
5119   ip6_fib_counter_t *c6;
5120   ip4_nbr_counter_t *n4;
5121   ip6_nbr_counter_t *n6;
5122   int i, j;
5123
5124   if (!vam->json_output)
5125     {
5126       clib_warning ("dump_stats_table supported only in JSON format");
5127       return -99;
5128     }
5129
5130   vat_json_init_object (&node);
5131
5132   /* interface counters */
5133   msg_array = vat_json_object_add (&node, "interface_counters");
5134   vat_json_init_array (msg_array);
5135   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
5136     {
5137       msg = vat_json_array_add (msg_array);
5138       vat_json_init_object (msg);
5139       vat_json_object_add_string_copy (msg, "vnet_counter_type",
5140                                        (u8 *) counter_type_to_str (i, 0));
5141       vat_json_object_add_int (msg, "is_combined", 0);
5142       counter_array = vat_json_object_add (msg, "data");
5143       vat_json_init_array (counter_array);
5144       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
5145         {
5146           packets = vam->simple_interface_counters[i][j];
5147           vat_json_array_add_uint (counter_array, packets);
5148         }
5149     }
5150   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
5151     {
5152       msg = vat_json_array_add (msg_array);
5153       vat_json_init_object (msg);
5154       vat_json_object_add_string_copy (msg, "vnet_counter_type",
5155                                        (u8 *) counter_type_to_str (i, 1));
5156       vat_json_object_add_int (msg, "is_combined", 1);
5157       counter_array = vat_json_object_add (msg, "data");
5158       vat_json_init_array (counter_array);
5159       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
5160         {
5161           c = vam->combined_interface_counters[i][j];
5162           counter = vat_json_array_add (counter_array);
5163           vat_json_init_object (counter);
5164           vat_json_object_add_uint (counter, "packets", c.packets);
5165           vat_json_object_add_uint (counter, "bytes", c.bytes);
5166         }
5167     }
5168
5169   /* ip4 fib counters */
5170   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
5171   vat_json_init_array (msg_array);
5172   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
5173     {
5174       msg = vat_json_array_add (msg_array);
5175       vat_json_init_object (msg);
5176       vat_json_object_add_uint (msg, "vrf_id",
5177                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
5178       counter_array = vat_json_object_add (msg, "c");
5179       vat_json_init_array (counter_array);
5180       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
5181         {
5182           counter = vat_json_array_add (counter_array);
5183           vat_json_init_object (counter);
5184           c4 = &vam->ip4_fib_counters[i][j];
5185           vat_json_object_add_ip4 (counter, "address", c4->address);
5186           vat_json_object_add_uint (counter, "address_length",
5187                                     c4->address_length);
5188           vat_json_object_add_uint (counter, "packets", c4->packets);
5189           vat_json_object_add_uint (counter, "bytes", c4->bytes);
5190         }
5191     }
5192
5193   /* ip6 fib counters */
5194   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
5195   vat_json_init_array (msg_array);
5196   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
5197     {
5198       msg = vat_json_array_add (msg_array);
5199       vat_json_init_object (msg);
5200       vat_json_object_add_uint (msg, "vrf_id",
5201                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
5202       counter_array = vat_json_object_add (msg, "c");
5203       vat_json_init_array (counter_array);
5204       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
5205         {
5206           counter = vat_json_array_add (counter_array);
5207           vat_json_init_object (counter);
5208           c6 = &vam->ip6_fib_counters[i][j];
5209           vat_json_object_add_ip6 (counter, "address", c6->address);
5210           vat_json_object_add_uint (counter, "address_length",
5211                                     c6->address_length);
5212           vat_json_object_add_uint (counter, "packets", c6->packets);
5213           vat_json_object_add_uint (counter, "bytes", c6->bytes);
5214         }
5215     }
5216
5217   /* ip4 nbr counters */
5218   msg_array = vat_json_object_add (&node, "ip4_nbr_counters");
5219   vat_json_init_array (msg_array);
5220   for (i = 0; i < vec_len (vam->ip4_nbr_counters); i++)
5221     {
5222       msg = vat_json_array_add (msg_array);
5223       vat_json_init_object (msg);
5224       vat_json_object_add_uint (msg, "sw_if_index", i);
5225       counter_array = vat_json_object_add (msg, "c");
5226       vat_json_init_array (counter_array);
5227       for (j = 0; j < vec_len (vam->ip4_nbr_counters[i]); j++)
5228         {
5229           counter = vat_json_array_add (counter_array);
5230           vat_json_init_object (counter);
5231           n4 = &vam->ip4_nbr_counters[i][j];
5232           vat_json_object_add_ip4 (counter, "address", n4->address);
5233           vat_json_object_add_uint (counter, "link-type", n4->linkt);
5234           vat_json_object_add_uint (counter, "packets", n4->packets);
5235           vat_json_object_add_uint (counter, "bytes", n4->bytes);
5236         }
5237     }
5238
5239   /* ip6 nbr counters */
5240   msg_array = vat_json_object_add (&node, "ip6_nbr_counters");
5241   vat_json_init_array (msg_array);
5242   for (i = 0; i < vec_len (vam->ip6_nbr_counters); i++)
5243     {
5244       msg = vat_json_array_add (msg_array);
5245       vat_json_init_object (msg);
5246       vat_json_object_add_uint (msg, "sw_if_index", i);
5247       counter_array = vat_json_object_add (msg, "c");
5248       vat_json_init_array (counter_array);
5249       for (j = 0; j < vec_len (vam->ip6_nbr_counters[i]); j++)
5250         {
5251           counter = vat_json_array_add (counter_array);
5252           vat_json_init_object (counter);
5253           n6 = &vam->ip6_nbr_counters[i][j];
5254           vat_json_object_add_ip6 (counter, "address", n6->address);
5255           vat_json_object_add_uint (counter, "packets", n6->packets);
5256           vat_json_object_add_uint (counter, "bytes", n6->bytes);
5257         }
5258     }
5259
5260   vat_json_print (vam->ofp, &node);
5261   vat_json_free (&node);
5262
5263   return 0;
5264 }
5265
5266 int
5267 exec (vat_main_t * vam)
5268 {
5269   api_main_t *am = &api_main;
5270   vl_api_cli_t *mp;
5271   f64 timeout;
5272   void *oldheap;
5273   u8 *cmd = 0;
5274   unformat_input_t *i = vam->input;
5275
5276   if (vec_len (i->buffer) == 0)
5277     return -1;
5278
5279   if (vam->exec_mode == 0 && unformat (i, "mode"))
5280     {
5281       vam->exec_mode = 1;
5282       return 0;
5283     }
5284   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
5285     {
5286       vam->exec_mode = 0;
5287       return 0;
5288     }
5289
5290
5291   M (CLI, mp);
5292
5293   /*
5294    * Copy cmd into shared memory.
5295    * In order for the CLI command to work, it
5296    * must be a vector ending in \n, not a C-string ending
5297    * in \n\0.
5298    */
5299   pthread_mutex_lock (&am->vlib_rp->mutex);
5300   oldheap = svm_push_data_heap (am->vlib_rp);
5301
5302   vec_validate (cmd, vec_len (vam->input->buffer) - 1);
5303   clib_memcpy (cmd, vam->input->buffer, vec_len (vam->input->buffer));
5304
5305   svm_pop_heap (oldheap);
5306   pthread_mutex_unlock (&am->vlib_rp->mutex);
5307
5308   mp->cmd_in_shmem = pointer_to_uword (cmd);
5309   S (mp);
5310   timeout = vat_time_now (vam) + 10.0;
5311
5312   while (vat_time_now (vam) < timeout)
5313     {
5314       if (vam->result_ready == 1)
5315         {
5316           u8 *free_me;
5317           if (vam->shmem_result != NULL)
5318             print (vam->ofp, "%s", vam->shmem_result);
5319           pthread_mutex_lock (&am->vlib_rp->mutex);
5320           oldheap = svm_push_data_heap (am->vlib_rp);
5321
5322           free_me = (u8 *) vam->shmem_result;
5323           vec_free (free_me);
5324
5325           svm_pop_heap (oldheap);
5326           pthread_mutex_unlock (&am->vlib_rp->mutex);
5327           return 0;
5328         }
5329     }
5330   return -99;
5331 }
5332
5333 /*
5334  * Future replacement of exec() that passes CLI buffers directly in
5335  * the API messages instead of an additional shared memory area.
5336  */
5337 static int
5338 exec_inband (vat_main_t * vam)
5339 {
5340   vl_api_cli_inband_t *mp;
5341   unformat_input_t *i = vam->input;
5342   int ret;
5343
5344   if (vec_len (i->buffer) == 0)
5345     return -1;
5346
5347   if (vam->exec_mode == 0 && unformat (i, "mode"))
5348     {
5349       vam->exec_mode = 1;
5350       return 0;
5351     }
5352   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
5353     {
5354       vam->exec_mode = 0;
5355       return 0;
5356     }
5357
5358   /*
5359    * In order for the CLI command to work, it
5360    * must be a vector ending in \n, not a C-string ending
5361    * in \n\0.
5362    */
5363   u32 len = vec_len (vam->input->buffer);
5364   M2 (CLI_INBAND, mp, len);
5365   clib_memcpy (mp->cmd, vam->input->buffer, len);
5366   mp->length = htonl (len);
5367
5368   S (mp);
5369   W2 (ret, print (vam->ofp, "%s", vam->cmd_reply));
5370   return ret;
5371 }
5372
5373 static int
5374 api_create_loopback (vat_main_t * vam)
5375 {
5376   unformat_input_t *i = vam->input;
5377   vl_api_create_loopback_t *mp;
5378   vl_api_create_loopback_instance_t *mp_lbi;
5379   u8 mac_address[6];
5380   u8 mac_set = 0;
5381   u8 is_specified = 0;
5382   u32 user_instance = 0;
5383   int ret;
5384
5385   memset (mac_address, 0, sizeof (mac_address));
5386
5387   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5388     {
5389       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5390         mac_set = 1;
5391       if (unformat (i, "instance %d", &user_instance))
5392         is_specified = 1;
5393       else
5394         break;
5395     }
5396
5397   if (is_specified)
5398     {
5399       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
5400       mp_lbi->is_specified = is_specified;
5401       if (is_specified)
5402         mp_lbi->user_instance = htonl (user_instance);
5403       if (mac_set)
5404         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
5405       S (mp_lbi);
5406     }
5407   else
5408     {
5409       /* Construct the API message */
5410       M (CREATE_LOOPBACK, mp);
5411       if (mac_set)
5412         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
5413       S (mp);
5414     }
5415
5416   W (ret);
5417   return ret;
5418 }
5419
5420 static int
5421 api_delete_loopback (vat_main_t * vam)
5422 {
5423   unformat_input_t *i = vam->input;
5424   vl_api_delete_loopback_t *mp;
5425   u32 sw_if_index = ~0;
5426   int ret;
5427
5428   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5429     {
5430       if (unformat (i, "sw_if_index %d", &sw_if_index))
5431         ;
5432       else
5433         break;
5434     }
5435
5436   if (sw_if_index == ~0)
5437     {
5438       errmsg ("missing sw_if_index");
5439       return -99;
5440     }
5441
5442   /* Construct the API message */
5443   M (DELETE_LOOPBACK, mp);
5444   mp->sw_if_index = ntohl (sw_if_index);
5445
5446   S (mp);
5447   W (ret);
5448   return ret;
5449 }
5450
5451 static int
5452 api_want_stats (vat_main_t * vam)
5453 {
5454   unformat_input_t *i = vam->input;
5455   vl_api_want_stats_t *mp;
5456   int enable = -1;
5457   int ret;
5458
5459   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5460     {
5461       if (unformat (i, "enable"))
5462         enable = 1;
5463       else if (unformat (i, "disable"))
5464         enable = 0;
5465       else
5466         break;
5467     }
5468
5469   if (enable == -1)
5470     {
5471       errmsg ("missing enable|disable");
5472       return -99;
5473     }
5474
5475   M (WANT_STATS, mp);
5476   mp->enable_disable = enable;
5477
5478   S (mp);
5479   W (ret);
5480   return ret;
5481 }
5482
5483 static int
5484 api_want_interface_events (vat_main_t * vam)
5485 {
5486   unformat_input_t *i = vam->input;
5487   vl_api_want_interface_events_t *mp;
5488   int enable = -1;
5489   int ret;
5490
5491   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5492     {
5493       if (unformat (i, "enable"))
5494         enable = 1;
5495       else if (unformat (i, "disable"))
5496         enable = 0;
5497       else
5498         break;
5499     }
5500
5501   if (enable == -1)
5502     {
5503       errmsg ("missing enable|disable");
5504       return -99;
5505     }
5506
5507   M (WANT_INTERFACE_EVENTS, mp);
5508   mp->enable_disable = enable;
5509
5510   vam->interface_event_display = enable;
5511
5512   S (mp);
5513   W (ret);
5514   return ret;
5515 }
5516
5517
5518 /* Note: non-static, called once to set up the initial intfc table */
5519 int
5520 api_sw_interface_dump (vat_main_t * vam)
5521 {
5522   vl_api_sw_interface_dump_t *mp;
5523   vl_api_control_ping_t *mp_ping;
5524   hash_pair_t *p;
5525   name_sort_t *nses = 0, *ns;
5526   sw_interface_subif_t *sub = NULL;
5527   int ret;
5528
5529   /* Toss the old name table */
5530   /* *INDENT-OFF* */
5531   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5532   ({
5533     vec_add2 (nses, ns, 1);
5534     ns->name = (u8 *)(p->key);
5535     ns->value = (u32) p->value[0];
5536   }));
5537   /* *INDENT-ON* */
5538
5539   hash_free (vam->sw_if_index_by_interface_name);
5540
5541   vec_foreach (ns, nses) vec_free (ns->name);
5542
5543   vec_free (nses);
5544
5545   vec_foreach (sub, vam->sw_if_subif_table)
5546   {
5547     vec_free (sub->interface_name);
5548   }
5549   vec_free (vam->sw_if_subif_table);
5550
5551   /* recreate the interface name hash table */
5552   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
5553
5554   /* Get list of ethernets */
5555   M (SW_INTERFACE_DUMP, mp);
5556   mp->name_filter_valid = 1;
5557   strncpy ((char *) mp->name_filter, "Ether", sizeof (mp->name_filter) - 1);
5558   S (mp);
5559
5560   /* and local / loopback interfaces */
5561   M (SW_INTERFACE_DUMP, mp);
5562   mp->name_filter_valid = 1;
5563   strncpy ((char *) mp->name_filter, "lo", sizeof (mp->name_filter) - 1);
5564   S (mp);
5565
5566   /* and packet-generator interfaces */
5567   M (SW_INTERFACE_DUMP, mp);
5568   mp->name_filter_valid = 1;
5569   strncpy ((char *) mp->name_filter, "pg", sizeof (mp->name_filter) - 1);
5570   S (mp);
5571
5572   /* and vxlan-gpe tunnel interfaces */
5573   M (SW_INTERFACE_DUMP, mp);
5574   mp->name_filter_valid = 1;
5575   strncpy ((char *) mp->name_filter, "vxlan_gpe",
5576            sizeof (mp->name_filter) - 1);
5577   S (mp);
5578
5579   /* and vxlan tunnel interfaces */
5580   M (SW_INTERFACE_DUMP, mp);
5581   mp->name_filter_valid = 1;
5582   strncpy ((char *) mp->name_filter, "vxlan", sizeof (mp->name_filter) - 1);
5583   S (mp);
5584
5585   /* and host (af_packet) interfaces */
5586   M (SW_INTERFACE_DUMP, mp);
5587   mp->name_filter_valid = 1;
5588   strncpy ((char *) mp->name_filter, "host", sizeof (mp->name_filter) - 1);
5589   S (mp);
5590
5591   /* and l2tpv3 tunnel interfaces */
5592   M (SW_INTERFACE_DUMP, mp);
5593   mp->name_filter_valid = 1;
5594   strncpy ((char *) mp->name_filter, "l2tpv3_tunnel",
5595            sizeof (mp->name_filter) - 1);
5596   S (mp);
5597
5598   /* and GRE tunnel interfaces */
5599   M (SW_INTERFACE_DUMP, mp);
5600   mp->name_filter_valid = 1;
5601   strncpy ((char *) mp->name_filter, "gre", sizeof (mp->name_filter) - 1);
5602   S (mp);
5603
5604   /* and LISP-GPE interfaces */
5605   M (SW_INTERFACE_DUMP, mp);
5606   mp->name_filter_valid = 1;
5607   strncpy ((char *) mp->name_filter, "lisp_gpe",
5608            sizeof (mp->name_filter) - 1);
5609   S (mp);
5610
5611   /* and IPSEC tunnel interfaces */
5612   M (SW_INTERFACE_DUMP, mp);
5613   mp->name_filter_valid = 1;
5614   strncpy ((char *) mp->name_filter, "ipsec", sizeof (mp->name_filter) - 1);
5615   S (mp);
5616
5617   /* Use a control ping for synchronization */
5618   M (CONTROL_PING, mp_ping);
5619   S (mp_ping);
5620
5621   W (ret);
5622   return ret;
5623 }
5624
5625 static int
5626 api_sw_interface_set_flags (vat_main_t * vam)
5627 {
5628   unformat_input_t *i = vam->input;
5629   vl_api_sw_interface_set_flags_t *mp;
5630   u32 sw_if_index;
5631   u8 sw_if_index_set = 0;
5632   u8 admin_up = 0, link_up = 0;
5633   int ret;
5634
5635   /* Parse args required to build the message */
5636   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5637     {
5638       if (unformat (i, "admin-up"))
5639         admin_up = 1;
5640       else if (unformat (i, "admin-down"))
5641         admin_up = 0;
5642       else if (unformat (i, "link-up"))
5643         link_up = 1;
5644       else if (unformat (i, "link-down"))
5645         link_up = 0;
5646       else
5647         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5648         sw_if_index_set = 1;
5649       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5650         sw_if_index_set = 1;
5651       else
5652         break;
5653     }
5654
5655   if (sw_if_index_set == 0)
5656     {
5657       errmsg ("missing interface name or sw_if_index");
5658       return -99;
5659     }
5660
5661   /* Construct the API message */
5662   M (SW_INTERFACE_SET_FLAGS, mp);
5663   mp->sw_if_index = ntohl (sw_if_index);
5664   mp->admin_up_down = admin_up;
5665   mp->link_up_down = link_up;
5666
5667   /* send it... */
5668   S (mp);
5669
5670   /* Wait for a reply, return the good/bad news... */
5671   W (ret);
5672   return ret;
5673 }
5674
5675 static int
5676 api_sw_interface_clear_stats (vat_main_t * vam)
5677 {
5678   unformat_input_t *i = vam->input;
5679   vl_api_sw_interface_clear_stats_t *mp;
5680   u32 sw_if_index;
5681   u8 sw_if_index_set = 0;
5682   int ret;
5683
5684   /* Parse args required to build the message */
5685   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5686     {
5687       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5688         sw_if_index_set = 1;
5689       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5690         sw_if_index_set = 1;
5691       else
5692         break;
5693     }
5694
5695   /* Construct the API message */
5696   M (SW_INTERFACE_CLEAR_STATS, mp);
5697
5698   if (sw_if_index_set == 1)
5699     mp->sw_if_index = ntohl (sw_if_index);
5700   else
5701     mp->sw_if_index = ~0;
5702
5703   /* send it... */
5704   S (mp);
5705
5706   /* Wait for a reply, return the good/bad news... */
5707   W (ret);
5708   return ret;
5709 }
5710
5711 static int
5712 api_sw_interface_add_del_address (vat_main_t * vam)
5713 {
5714   unformat_input_t *i = vam->input;
5715   vl_api_sw_interface_add_del_address_t *mp;
5716   u32 sw_if_index;
5717   u8 sw_if_index_set = 0;
5718   u8 is_add = 1, del_all = 0;
5719   u32 address_length = 0;
5720   u8 v4_address_set = 0;
5721   u8 v6_address_set = 0;
5722   ip4_address_t v4address;
5723   ip6_address_t v6address;
5724   int ret;
5725
5726   /* Parse args required to build the message */
5727   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5728     {
5729       if (unformat (i, "del-all"))
5730         del_all = 1;
5731       else if (unformat (i, "del"))
5732         is_add = 0;
5733       else
5734         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5735         sw_if_index_set = 1;
5736       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5737         sw_if_index_set = 1;
5738       else if (unformat (i, "%U/%d",
5739                          unformat_ip4_address, &v4address, &address_length))
5740         v4_address_set = 1;
5741       else if (unformat (i, "%U/%d",
5742                          unformat_ip6_address, &v6address, &address_length))
5743         v6_address_set = 1;
5744       else
5745         break;
5746     }
5747
5748   if (sw_if_index_set == 0)
5749     {
5750       errmsg ("missing interface name or sw_if_index");
5751       return -99;
5752     }
5753   if (v4_address_set && v6_address_set)
5754     {
5755       errmsg ("both v4 and v6 addresses set");
5756       return -99;
5757     }
5758   if (!v4_address_set && !v6_address_set && !del_all)
5759     {
5760       errmsg ("no addresses set");
5761       return -99;
5762     }
5763
5764   /* Construct the API message */
5765   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
5766
5767   mp->sw_if_index = ntohl (sw_if_index);
5768   mp->is_add = is_add;
5769   mp->del_all = del_all;
5770   if (v6_address_set)
5771     {
5772       mp->is_ipv6 = 1;
5773       clib_memcpy (mp->address, &v6address, sizeof (v6address));
5774     }
5775   else
5776     {
5777       clib_memcpy (mp->address, &v4address, sizeof (v4address));
5778     }
5779   mp->address_length = address_length;
5780
5781   /* send it... */
5782   S (mp);
5783
5784   /* Wait for a reply, return good/bad news  */
5785   W (ret);
5786   return ret;
5787 }
5788
5789 static int
5790 api_sw_interface_set_mpls_enable (vat_main_t * vam)
5791 {
5792   unformat_input_t *i = vam->input;
5793   vl_api_sw_interface_set_mpls_enable_t *mp;
5794   u32 sw_if_index;
5795   u8 sw_if_index_set = 0;
5796   u8 enable = 1;
5797   int ret;
5798
5799   /* Parse args required to build the message */
5800   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5801     {
5802       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5803         sw_if_index_set = 1;
5804       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5805         sw_if_index_set = 1;
5806       else if (unformat (i, "disable"))
5807         enable = 0;
5808       else if (unformat (i, "dis"))
5809         enable = 0;
5810       else
5811         break;
5812     }
5813
5814   if (sw_if_index_set == 0)
5815     {
5816       errmsg ("missing interface name or sw_if_index");
5817       return -99;
5818     }
5819
5820   /* Construct the API message */
5821   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
5822
5823   mp->sw_if_index = ntohl (sw_if_index);
5824   mp->enable = enable;
5825
5826   /* send it... */
5827   S (mp);
5828
5829   /* Wait for a reply... */
5830   W (ret);
5831   return ret;
5832 }
5833
5834 static int
5835 api_sw_interface_set_table (vat_main_t * vam)
5836 {
5837   unformat_input_t *i = vam->input;
5838   vl_api_sw_interface_set_table_t *mp;
5839   u32 sw_if_index, vrf_id = 0;
5840   u8 sw_if_index_set = 0;
5841   u8 is_ipv6 = 0;
5842   int ret;
5843
5844   /* Parse args required to build the message */
5845   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5846     {
5847       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5848         sw_if_index_set = 1;
5849       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5850         sw_if_index_set = 1;
5851       else if (unformat (i, "vrf %d", &vrf_id))
5852         ;
5853       else if (unformat (i, "ipv6"))
5854         is_ipv6 = 1;
5855       else
5856         break;
5857     }
5858
5859   if (sw_if_index_set == 0)
5860     {
5861       errmsg ("missing interface name or sw_if_index");
5862       return -99;
5863     }
5864
5865   /* Construct the API message */
5866   M (SW_INTERFACE_SET_TABLE, mp);
5867
5868   mp->sw_if_index = ntohl (sw_if_index);
5869   mp->is_ipv6 = is_ipv6;
5870   mp->vrf_id = ntohl (vrf_id);
5871
5872   /* send it... */
5873   S (mp);
5874
5875   /* Wait for a reply... */
5876   W (ret);
5877   return ret;
5878 }
5879
5880 static void vl_api_sw_interface_get_table_reply_t_handler
5881   (vl_api_sw_interface_get_table_reply_t * mp)
5882 {
5883   vat_main_t *vam = &vat_main;
5884
5885   print (vam->ofp, "%d", ntohl (mp->vrf_id));
5886
5887   vam->retval = ntohl (mp->retval);
5888   vam->result_ready = 1;
5889
5890 }
5891
5892 static void vl_api_sw_interface_get_table_reply_t_handler_json
5893   (vl_api_sw_interface_get_table_reply_t * mp)
5894 {
5895   vat_main_t *vam = &vat_main;
5896   vat_json_node_t node;
5897
5898   vat_json_init_object (&node);
5899   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
5900   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
5901
5902   vat_json_print (vam->ofp, &node);
5903   vat_json_free (&node);
5904
5905   vam->retval = ntohl (mp->retval);
5906   vam->result_ready = 1;
5907 }
5908
5909 static int
5910 api_sw_interface_get_table (vat_main_t * vam)
5911 {
5912   unformat_input_t *i = vam->input;
5913   vl_api_sw_interface_get_table_t *mp;
5914   u32 sw_if_index;
5915   u8 sw_if_index_set = 0;
5916   u8 is_ipv6 = 0;
5917   int ret;
5918
5919   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5920     {
5921       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5922         sw_if_index_set = 1;
5923       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5924         sw_if_index_set = 1;
5925       else if (unformat (i, "ipv6"))
5926         is_ipv6 = 1;
5927       else
5928         break;
5929     }
5930
5931   if (sw_if_index_set == 0)
5932     {
5933       errmsg ("missing interface name or sw_if_index");
5934       return -99;
5935     }
5936
5937   M (SW_INTERFACE_GET_TABLE, mp);
5938   mp->sw_if_index = htonl (sw_if_index);
5939   mp->is_ipv6 = is_ipv6;
5940
5941   S (mp);
5942   W (ret);
5943   return ret;
5944 }
5945
5946 static int
5947 api_sw_interface_set_vpath (vat_main_t * vam)
5948 {
5949   unformat_input_t *i = vam->input;
5950   vl_api_sw_interface_set_vpath_t *mp;
5951   u32 sw_if_index = 0;
5952   u8 sw_if_index_set = 0;
5953   u8 is_enable = 0;
5954   int ret;
5955
5956   /* Parse args required to build the message */
5957   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5958     {
5959       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5960         sw_if_index_set = 1;
5961       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5962         sw_if_index_set = 1;
5963       else if (unformat (i, "enable"))
5964         is_enable = 1;
5965       else if (unformat (i, "disable"))
5966         is_enable = 0;
5967       else
5968         break;
5969     }
5970
5971   if (sw_if_index_set == 0)
5972     {
5973       errmsg ("missing interface name or sw_if_index");
5974       return -99;
5975     }
5976
5977   /* Construct the API message */
5978   M (SW_INTERFACE_SET_VPATH, mp);
5979
5980   mp->sw_if_index = ntohl (sw_if_index);
5981   mp->enable = is_enable;
5982
5983   /* send it... */
5984   S (mp);
5985
5986   /* Wait for a reply... */
5987   W (ret);
5988   return ret;
5989 }
5990
5991 static int
5992 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
5993 {
5994   unformat_input_t *i = vam->input;
5995   vl_api_sw_interface_set_vxlan_bypass_t *mp;
5996   u32 sw_if_index = 0;
5997   u8 sw_if_index_set = 0;
5998   u8 is_enable = 1;
5999   u8 is_ipv6 = 0;
6000   int ret;
6001
6002   /* Parse args required to build the message */
6003   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6004     {
6005       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6006         sw_if_index_set = 1;
6007       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6008         sw_if_index_set = 1;
6009       else if (unformat (i, "enable"))
6010         is_enable = 1;
6011       else if (unformat (i, "disable"))
6012         is_enable = 0;
6013       else if (unformat (i, "ip4"))
6014         is_ipv6 = 0;
6015       else if (unformat (i, "ip6"))
6016         is_ipv6 = 1;
6017       else
6018         break;
6019     }
6020
6021   if (sw_if_index_set == 0)
6022     {
6023       errmsg ("missing interface name or sw_if_index");
6024       return -99;
6025     }
6026
6027   /* Construct the API message */
6028   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
6029
6030   mp->sw_if_index = ntohl (sw_if_index);
6031   mp->enable = is_enable;
6032   mp->is_ipv6 = is_ipv6;
6033
6034   /* send it... */
6035   S (mp);
6036
6037   /* Wait for a reply... */
6038   W (ret);
6039   return ret;
6040 }
6041
6042 static int
6043 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
6044 {
6045   unformat_input_t *i = vam->input;
6046   vl_api_sw_interface_set_l2_xconnect_t *mp;
6047   u32 rx_sw_if_index;
6048   u8 rx_sw_if_index_set = 0;
6049   u32 tx_sw_if_index;
6050   u8 tx_sw_if_index_set = 0;
6051   u8 enable = 1;
6052   int ret;
6053
6054   /* Parse args required to build the message */
6055   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6056     {
6057       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
6058         rx_sw_if_index_set = 1;
6059       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
6060         tx_sw_if_index_set = 1;
6061       else if (unformat (i, "rx"))
6062         {
6063           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6064             {
6065               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6066                             &rx_sw_if_index))
6067                 rx_sw_if_index_set = 1;
6068             }
6069           else
6070             break;
6071         }
6072       else if (unformat (i, "tx"))
6073         {
6074           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6075             {
6076               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6077                             &tx_sw_if_index))
6078                 tx_sw_if_index_set = 1;
6079             }
6080           else
6081             break;
6082         }
6083       else if (unformat (i, "enable"))
6084         enable = 1;
6085       else if (unformat (i, "disable"))
6086         enable = 0;
6087       else
6088         break;
6089     }
6090
6091   if (rx_sw_if_index_set == 0)
6092     {
6093       errmsg ("missing rx interface name or rx_sw_if_index");
6094       return -99;
6095     }
6096
6097   if (enable && (tx_sw_if_index_set == 0))
6098     {
6099       errmsg ("missing tx interface name or tx_sw_if_index");
6100       return -99;
6101     }
6102
6103   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
6104
6105   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6106   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
6107   mp->enable = enable;
6108
6109   S (mp);
6110   W (ret);
6111   return ret;
6112 }
6113
6114 static int
6115 api_sw_interface_set_l2_bridge (vat_main_t * vam)
6116 {
6117   unformat_input_t *i = vam->input;
6118   vl_api_sw_interface_set_l2_bridge_t *mp;
6119   u32 rx_sw_if_index;
6120   u8 rx_sw_if_index_set = 0;
6121   u32 bd_id;
6122   u8 bd_id_set = 0;
6123   u8 bvi = 0;
6124   u32 shg = 0;
6125   u8 enable = 1;
6126   int ret;
6127
6128   /* Parse args required to build the message */
6129   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6130     {
6131       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
6132         rx_sw_if_index_set = 1;
6133       else if (unformat (i, "bd_id %d", &bd_id))
6134         bd_id_set = 1;
6135       else
6136         if (unformat
6137             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
6138         rx_sw_if_index_set = 1;
6139       else if (unformat (i, "shg %d", &shg))
6140         ;
6141       else if (unformat (i, "bvi"))
6142         bvi = 1;
6143       else if (unformat (i, "enable"))
6144         enable = 1;
6145       else if (unformat (i, "disable"))
6146         enable = 0;
6147       else
6148         break;
6149     }
6150
6151   if (rx_sw_if_index_set == 0)
6152     {
6153       errmsg ("missing rx interface name or sw_if_index");
6154       return -99;
6155     }
6156
6157   if (enable && (bd_id_set == 0))
6158     {
6159       errmsg ("missing bridge domain");
6160       return -99;
6161     }
6162
6163   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
6164
6165   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6166   mp->bd_id = ntohl (bd_id);
6167   mp->shg = (u8) shg;
6168   mp->bvi = bvi;
6169   mp->enable = enable;
6170
6171   S (mp);
6172   W (ret);
6173   return ret;
6174 }
6175
6176 static int
6177 api_bridge_domain_dump (vat_main_t * vam)
6178 {
6179   unformat_input_t *i = vam->input;
6180   vl_api_bridge_domain_dump_t *mp;
6181   vl_api_control_ping_t *mp_ping;
6182   u32 bd_id = ~0;
6183   int ret;
6184
6185   /* Parse args required to build the message */
6186   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6187     {
6188       if (unformat (i, "bd_id %d", &bd_id))
6189         ;
6190       else
6191         break;
6192     }
6193
6194   M (BRIDGE_DOMAIN_DUMP, mp);
6195   mp->bd_id = ntohl (bd_id);
6196   S (mp);
6197
6198   /* Use a control ping for synchronization */
6199   M (CONTROL_PING, mp_ping);
6200   S (mp_ping);
6201
6202   W (ret);
6203   return ret;
6204 }
6205
6206 static int
6207 api_bridge_domain_add_del (vat_main_t * vam)
6208 {
6209   unformat_input_t *i = vam->input;
6210   vl_api_bridge_domain_add_del_t *mp;
6211   u32 bd_id = ~0;
6212   u8 is_add = 1;
6213   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
6214   u32 mac_age = 0;
6215   int ret;
6216
6217   /* Parse args required to build the message */
6218   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6219     {
6220       if (unformat (i, "bd_id %d", &bd_id))
6221         ;
6222       else if (unformat (i, "flood %d", &flood))
6223         ;
6224       else if (unformat (i, "uu-flood %d", &uu_flood))
6225         ;
6226       else if (unformat (i, "forward %d", &forward))
6227         ;
6228       else if (unformat (i, "learn %d", &learn))
6229         ;
6230       else if (unformat (i, "arp-term %d", &arp_term))
6231         ;
6232       else if (unformat (i, "mac-age %d", &mac_age))
6233         ;
6234       else if (unformat (i, "del"))
6235         {
6236           is_add = 0;
6237           flood = uu_flood = forward = learn = 0;
6238         }
6239       else
6240         break;
6241     }
6242
6243   if (bd_id == ~0)
6244     {
6245       errmsg ("missing bridge domain");
6246       return -99;
6247     }
6248
6249   if (mac_age > 255)
6250     {
6251       errmsg ("mac age must be less than 256 ");
6252       return -99;
6253     }
6254
6255   M (BRIDGE_DOMAIN_ADD_DEL, mp);
6256
6257   mp->bd_id = ntohl (bd_id);
6258   mp->flood = flood;
6259   mp->uu_flood = uu_flood;
6260   mp->forward = forward;
6261   mp->learn = learn;
6262   mp->arp_term = arp_term;
6263   mp->is_add = is_add;
6264   mp->mac_age = (u8) mac_age;
6265
6266   S (mp);
6267   W (ret);
6268   return ret;
6269 }
6270
6271 static int
6272 api_l2fib_flush_bd (vat_main_t * vam)
6273 {
6274   unformat_input_t *i = vam->input;
6275   vl_api_l2fib_flush_bd_t *mp;
6276   u32 bd_id = ~0;
6277   int ret;
6278
6279   /* Parse args required to build the message */
6280   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6281     {
6282       if (unformat (i, "bd_id %d", &bd_id));
6283       else
6284         break;
6285     }
6286
6287   if (bd_id == ~0)
6288     {
6289       errmsg ("missing bridge domain");
6290       return -99;
6291     }
6292
6293   M (L2FIB_FLUSH_BD, mp);
6294
6295   mp->bd_id = htonl (bd_id);
6296
6297   S (mp);
6298   W (ret);
6299   return ret;
6300 }
6301
6302 static int
6303 api_l2fib_flush_int (vat_main_t * vam)
6304 {
6305   unformat_input_t *i = vam->input;
6306   vl_api_l2fib_flush_int_t *mp;
6307   u32 sw_if_index = ~0;
6308   int ret;
6309
6310   /* Parse args required to build the message */
6311   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6312     {
6313       if (unformat (i, "sw_if_index %d", &sw_if_index));
6314       else
6315         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
6316       else
6317         break;
6318     }
6319
6320   if (sw_if_index == ~0)
6321     {
6322       errmsg ("missing interface name or sw_if_index");
6323       return -99;
6324     }
6325
6326   M (L2FIB_FLUSH_INT, mp);
6327
6328   mp->sw_if_index = ntohl (sw_if_index);
6329
6330   S (mp);
6331   W (ret);
6332   return ret;
6333 }
6334
6335 static int
6336 api_l2fib_add_del (vat_main_t * vam)
6337 {
6338   unformat_input_t *i = vam->input;
6339   vl_api_l2fib_add_del_t *mp;
6340   f64 timeout;
6341   u64 mac = 0;
6342   u8 mac_set = 0;
6343   u32 bd_id;
6344   u8 bd_id_set = 0;
6345   u32 sw_if_index = ~0;
6346   u8 sw_if_index_set = 0;
6347   u8 is_add = 1;
6348   u8 static_mac = 0;
6349   u8 filter_mac = 0;
6350   u8 bvi_mac = 0;
6351   int count = 1;
6352   f64 before = 0;
6353   int j;
6354
6355   /* Parse args required to build the message */
6356   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6357     {
6358       if (unformat (i, "mac %U", unformat_ethernet_address, &mac))
6359         mac_set = 1;
6360       else if (unformat (i, "bd_id %d", &bd_id))
6361         bd_id_set = 1;
6362       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6363         sw_if_index_set = 1;
6364       else if (unformat (i, "sw_if"))
6365         {
6366           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6367             {
6368               if (unformat
6369                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6370                 sw_if_index_set = 1;
6371             }
6372           else
6373             break;
6374         }
6375       else if (unformat (i, "static"))
6376         static_mac = 1;
6377       else if (unformat (i, "filter"))
6378         {
6379           filter_mac = 1;
6380           static_mac = 1;
6381         }
6382       else if (unformat (i, "bvi"))
6383         {
6384           bvi_mac = 1;
6385           static_mac = 1;
6386         }
6387       else if (unformat (i, "del"))
6388         is_add = 0;
6389       else if (unformat (i, "count %d", &count))
6390         ;
6391       else
6392         break;
6393     }
6394
6395   if (mac_set == 0)
6396     {
6397       errmsg ("missing mac address");
6398       return -99;
6399     }
6400
6401   if (bd_id_set == 0)
6402     {
6403       errmsg ("missing bridge domain");
6404       return -99;
6405     }
6406
6407   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
6408     {
6409       errmsg ("missing interface name or sw_if_index");
6410       return -99;
6411     }
6412
6413   if (count > 1)
6414     {
6415       /* Turn on async mode */
6416       vam->async_mode = 1;
6417       vam->async_errors = 0;
6418       before = vat_time_now (vam);
6419     }
6420
6421   for (j = 0; j < count; j++)
6422     {
6423       M (L2FIB_ADD_DEL, mp);
6424
6425       mp->mac = mac;
6426       mp->bd_id = ntohl (bd_id);
6427       mp->is_add = is_add;
6428
6429       if (is_add)
6430         {
6431           mp->sw_if_index = ntohl (sw_if_index);
6432           mp->static_mac = static_mac;
6433           mp->filter_mac = filter_mac;
6434           mp->bvi_mac = bvi_mac;
6435         }
6436       increment_mac_address (&mac);
6437       /* send it... */
6438       S (mp);
6439     }
6440
6441   if (count > 1)
6442     {
6443       vl_api_control_ping_t *mp_ping;
6444       f64 after;
6445
6446       /* Shut off async mode */
6447       vam->async_mode = 0;
6448
6449       M (CONTROL_PING, mp_ping);
6450       S (mp_ping);
6451
6452       timeout = vat_time_now (vam) + 1.0;
6453       while (vat_time_now (vam) < timeout)
6454         if (vam->result_ready == 1)
6455           goto out;
6456       vam->retval = -99;
6457
6458     out:
6459       if (vam->retval == -99)
6460         errmsg ("timeout");
6461
6462       if (vam->async_errors > 0)
6463         {
6464           errmsg ("%d asynchronous errors", vam->async_errors);
6465           vam->retval = -98;
6466         }
6467       vam->async_errors = 0;
6468       after = vat_time_now (vam);
6469
6470       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6471              count, after - before, count / (after - before));
6472     }
6473   else
6474     {
6475       int ret;
6476
6477       /* Wait for a reply... */
6478       W (ret);
6479       return ret;
6480     }
6481   /* Return the good/bad news */
6482   return (vam->retval);
6483 }
6484
6485 static int
6486 api_bridge_domain_set_mac_age (vat_main_t * vam)
6487 {
6488   unformat_input_t *i = vam->input;
6489   vl_api_bridge_domain_set_mac_age_t *mp;
6490   u32 bd_id = ~0;
6491   u32 mac_age = 0;
6492   int ret;
6493
6494   /* Parse args required to build the message */
6495   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6496     {
6497       if (unformat (i, "bd_id %d", &bd_id));
6498       else if (unformat (i, "mac-age %d", &mac_age));
6499       else
6500         break;
6501     }
6502
6503   if (bd_id == ~0)
6504     {
6505       errmsg ("missing bridge domain");
6506       return -99;
6507     }
6508
6509   if (mac_age > 255)
6510     {
6511       errmsg ("mac age must be less than 256 ");
6512       return -99;
6513     }
6514
6515   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
6516
6517   mp->bd_id = htonl (bd_id);
6518   mp->mac_age = (u8) mac_age;
6519
6520   S (mp);
6521   W (ret);
6522   return ret;
6523 }
6524
6525 static int
6526 api_l2_flags (vat_main_t * vam)
6527 {
6528   unformat_input_t *i = vam->input;
6529   vl_api_l2_flags_t *mp;
6530   u32 sw_if_index;
6531   u32 feature_bitmap = 0;
6532   u8 sw_if_index_set = 0;
6533   int ret;
6534
6535   /* Parse args required to build the message */
6536   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6537     {
6538       if (unformat (i, "sw_if_index %d", &sw_if_index))
6539         sw_if_index_set = 1;
6540       else if (unformat (i, "sw_if"))
6541         {
6542           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6543             {
6544               if (unformat
6545                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6546                 sw_if_index_set = 1;
6547             }
6548           else
6549             break;
6550         }
6551       else if (unformat (i, "learn"))
6552         feature_bitmap |= L2INPUT_FEAT_LEARN;
6553       else if (unformat (i, "forward"))
6554         feature_bitmap |= L2INPUT_FEAT_FWD;
6555       else if (unformat (i, "flood"))
6556         feature_bitmap |= L2INPUT_FEAT_FLOOD;
6557       else if (unformat (i, "uu-flood"))
6558         feature_bitmap |= L2INPUT_FEAT_UU_FLOOD;
6559       else
6560         break;
6561     }
6562
6563   if (sw_if_index_set == 0)
6564     {
6565       errmsg ("missing interface name or sw_if_index");
6566       return -99;
6567     }
6568
6569   M (L2_FLAGS, mp);
6570
6571   mp->sw_if_index = ntohl (sw_if_index);
6572   mp->feature_bitmap = ntohl (feature_bitmap);
6573
6574   S (mp);
6575   W (ret);
6576   return ret;
6577 }
6578
6579 static int
6580 api_bridge_flags (vat_main_t * vam)
6581 {
6582   unformat_input_t *i = vam->input;
6583   vl_api_bridge_flags_t *mp;
6584   u32 bd_id;
6585   u8 bd_id_set = 0;
6586   u8 is_set = 1;
6587   u32 flags = 0;
6588   int ret;
6589
6590   /* Parse args required to build the message */
6591   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6592     {
6593       if (unformat (i, "bd_id %d", &bd_id))
6594         bd_id_set = 1;
6595       else if (unformat (i, "learn"))
6596         flags |= L2_LEARN;
6597       else if (unformat (i, "forward"))
6598         flags |= L2_FWD;
6599       else if (unformat (i, "flood"))
6600         flags |= L2_FLOOD;
6601       else if (unformat (i, "uu-flood"))
6602         flags |= L2_UU_FLOOD;
6603       else if (unformat (i, "arp-term"))
6604         flags |= L2_ARP_TERM;
6605       else if (unformat (i, "off"))
6606         is_set = 0;
6607       else if (unformat (i, "disable"))
6608         is_set = 0;
6609       else
6610         break;
6611     }
6612
6613   if (bd_id_set == 0)
6614     {
6615       errmsg ("missing bridge domain");
6616       return -99;
6617     }
6618
6619   M (BRIDGE_FLAGS, mp);
6620
6621   mp->bd_id = ntohl (bd_id);
6622   mp->feature_bitmap = ntohl (flags);
6623   mp->is_set = is_set;
6624
6625   S (mp);
6626   W (ret);
6627   return ret;
6628 }
6629
6630 static int
6631 api_bd_ip_mac_add_del (vat_main_t * vam)
6632 {
6633   unformat_input_t *i = vam->input;
6634   vl_api_bd_ip_mac_add_del_t *mp;
6635   u32 bd_id;
6636   u8 is_ipv6 = 0;
6637   u8 is_add = 1;
6638   u8 bd_id_set = 0;
6639   u8 ip_set = 0;
6640   u8 mac_set = 0;
6641   ip4_address_t v4addr;
6642   ip6_address_t v6addr;
6643   u8 macaddr[6];
6644   int ret;
6645
6646
6647   /* Parse args required to build the message */
6648   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6649     {
6650       if (unformat (i, "bd_id %d", &bd_id))
6651         {
6652           bd_id_set++;
6653         }
6654       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
6655         {
6656           ip_set++;
6657         }
6658       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
6659         {
6660           ip_set++;
6661           is_ipv6++;
6662         }
6663       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
6664         {
6665           mac_set++;
6666         }
6667       else if (unformat (i, "del"))
6668         is_add = 0;
6669       else
6670         break;
6671     }
6672
6673   if (bd_id_set == 0)
6674     {
6675       errmsg ("missing bridge domain");
6676       return -99;
6677     }
6678   else if (ip_set == 0)
6679     {
6680       errmsg ("missing IP address");
6681       return -99;
6682     }
6683   else if (mac_set == 0)
6684     {
6685       errmsg ("missing MAC address");
6686       return -99;
6687     }
6688
6689   M (BD_IP_MAC_ADD_DEL, mp);
6690
6691   mp->bd_id = ntohl (bd_id);
6692   mp->is_ipv6 = is_ipv6;
6693   mp->is_add = is_add;
6694   if (is_ipv6)
6695     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
6696   else
6697     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
6698   clib_memcpy (mp->mac_address, macaddr, 6);
6699   S (mp);
6700   W (ret);
6701   return ret;
6702 }
6703
6704 static int
6705 api_tap_connect (vat_main_t * vam)
6706 {
6707   unformat_input_t *i = vam->input;
6708   vl_api_tap_connect_t *mp;
6709   u8 mac_address[6];
6710   u8 random_mac = 1;
6711   u8 name_set = 0;
6712   u8 *tap_name;
6713   u8 *tag = 0;
6714   ip4_address_t ip4_address;
6715   u32 ip4_mask_width;
6716   int ip4_address_set = 0;
6717   ip6_address_t ip6_address;
6718   u32 ip6_mask_width;
6719   int ip6_address_set = 0;
6720   int ret;
6721
6722   memset (mac_address, 0, sizeof (mac_address));
6723
6724   /* Parse args required to build the message */
6725   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6726     {
6727       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6728         {
6729           random_mac = 0;
6730         }
6731       else if (unformat (i, "random-mac"))
6732         random_mac = 1;
6733       else if (unformat (i, "tapname %s", &tap_name))
6734         name_set = 1;
6735       else if (unformat (i, "tag %s", &tag))
6736         ;
6737       else if (unformat (i, "address %U/%d",
6738                          unformat_ip4_address, &ip4_address, &ip4_mask_width))
6739         ip4_address_set = 1;
6740       else if (unformat (i, "address %U/%d",
6741                          unformat_ip6_address, &ip6_address, &ip6_mask_width))
6742         ip6_address_set = 1;
6743       else
6744         break;
6745     }
6746
6747   if (name_set == 0)
6748     {
6749       errmsg ("missing tap name");
6750       return -99;
6751     }
6752   if (vec_len (tap_name) > 63)
6753     {
6754       errmsg ("tap name too long");
6755       return -99;
6756     }
6757   vec_add1 (tap_name, 0);
6758
6759   if (vec_len (tag) > 63)
6760     {
6761       errmsg ("tag too long");
6762       return -99;
6763     }
6764
6765   /* Construct the API message */
6766   M (TAP_CONNECT, mp);
6767
6768   mp->use_random_mac = random_mac;
6769   clib_memcpy (mp->mac_address, mac_address, 6);
6770   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
6771   if (tag)
6772     clib_memcpy (mp->tag, tag, vec_len (tag));
6773
6774   if (ip4_address_set)
6775     {
6776       mp->ip4_address_set = 1;
6777       clib_memcpy (mp->ip4_address, &ip4_address, sizeof (mp->ip4_address));
6778       mp->ip4_mask_width = ip4_mask_width;
6779     }
6780   if (ip6_address_set)
6781     {
6782       mp->ip6_address_set = 1;
6783       clib_memcpy (mp->ip6_address, &ip6_address, sizeof (mp->ip6_address));
6784       mp->ip6_mask_width = ip6_mask_width;
6785     }
6786
6787   vec_free (tap_name);
6788   vec_free (tag);
6789
6790   /* send it... */
6791   S (mp);
6792
6793   /* Wait for a reply... */
6794   W (ret);
6795   return ret;
6796 }
6797
6798 static int
6799 api_tap_modify (vat_main_t * vam)
6800 {
6801   unformat_input_t *i = vam->input;
6802   vl_api_tap_modify_t *mp;
6803   u8 mac_address[6];
6804   u8 random_mac = 1;
6805   u8 name_set = 0;
6806   u8 *tap_name;
6807   u32 sw_if_index = ~0;
6808   u8 sw_if_index_set = 0;
6809   int ret;
6810
6811   memset (mac_address, 0, sizeof (mac_address));
6812
6813   /* Parse args required to build the message */
6814   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6815     {
6816       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6817         sw_if_index_set = 1;
6818       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6819         sw_if_index_set = 1;
6820       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6821         {
6822           random_mac = 0;
6823         }
6824       else if (unformat (i, "random-mac"))
6825         random_mac = 1;
6826       else if (unformat (i, "tapname %s", &tap_name))
6827         name_set = 1;
6828       else
6829         break;
6830     }
6831
6832   if (sw_if_index_set == 0)
6833     {
6834       errmsg ("missing vpp interface name");
6835       return -99;
6836     }
6837   if (name_set == 0)
6838     {
6839       errmsg ("missing tap name");
6840       return -99;
6841     }
6842   if (vec_len (tap_name) > 63)
6843     {
6844       errmsg ("tap name too long");
6845     }
6846   vec_add1 (tap_name, 0);
6847
6848   /* Construct the API message */
6849   M (TAP_MODIFY, mp);
6850
6851   mp->use_random_mac = random_mac;
6852   mp->sw_if_index = ntohl (sw_if_index);
6853   clib_memcpy (mp->mac_address, mac_address, 6);
6854   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
6855   vec_free (tap_name);
6856
6857   /* send it... */
6858   S (mp);
6859
6860   /* Wait for a reply... */
6861   W (ret);
6862   return ret;
6863 }
6864
6865 static int
6866 api_tap_delete (vat_main_t * vam)
6867 {
6868   unformat_input_t *i = vam->input;
6869   vl_api_tap_delete_t *mp;
6870   u32 sw_if_index = ~0;
6871   u8 sw_if_index_set = 0;
6872   int ret;
6873
6874   /* Parse args required to build the message */
6875   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6876     {
6877       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6878         sw_if_index_set = 1;
6879       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6880         sw_if_index_set = 1;
6881       else
6882         break;
6883     }
6884
6885   if (sw_if_index_set == 0)
6886     {
6887       errmsg ("missing vpp interface name");
6888       return -99;
6889     }
6890
6891   /* Construct the API message */
6892   M (TAP_DELETE, mp);
6893
6894   mp->sw_if_index = ntohl (sw_if_index);
6895
6896   /* send it... */
6897   S (mp);
6898
6899   /* Wait for a reply... */
6900   W (ret);
6901   return ret;
6902 }
6903
6904 static int
6905 api_ip_add_del_route (vat_main_t * vam)
6906 {
6907   unformat_input_t *i = vam->input;
6908   vl_api_ip_add_del_route_t *mp;
6909   u32 sw_if_index = ~0, vrf_id = 0;
6910   u8 is_ipv6 = 0;
6911   u8 is_local = 0, is_drop = 0;
6912   u8 is_unreach = 0, is_prohibit = 0;
6913   u8 create_vrf_if_needed = 0;
6914   u8 is_add = 1;
6915   u32 next_hop_weight = 1;
6916   u8 not_last = 0;
6917   u8 is_multipath = 0;
6918   u8 address_set = 0;
6919   u8 address_length_set = 0;
6920   u32 next_hop_table_id = 0;
6921   u32 resolve_attempts = 0;
6922   u32 dst_address_length = 0;
6923   u8 next_hop_set = 0;
6924   ip4_address_t v4_dst_address, v4_next_hop_address;
6925   ip6_address_t v6_dst_address, v6_next_hop_address;
6926   int count = 1;
6927   int j;
6928   f64 before = 0;
6929   u32 random_add_del = 0;
6930   u32 *random_vector = 0;
6931   uword *random_hash;
6932   u32 random_seed = 0xdeaddabe;
6933   u32 classify_table_index = ~0;
6934   u8 is_classify = 0;
6935   u8 resolve_host = 0, resolve_attached = 0;
6936   mpls_label_t *next_hop_out_label_stack = NULL;
6937   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
6938   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
6939
6940   /* Parse args required to build the message */
6941   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6942     {
6943       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6944         ;
6945       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6946         ;
6947       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
6948         {
6949           address_set = 1;
6950           is_ipv6 = 0;
6951         }
6952       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
6953         {
6954           address_set = 1;
6955           is_ipv6 = 1;
6956         }
6957       else if (unformat (i, "/%d", &dst_address_length))
6958         {
6959           address_length_set = 1;
6960         }
6961
6962       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
6963                                          &v4_next_hop_address))
6964         {
6965           next_hop_set = 1;
6966         }
6967       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
6968                                          &v6_next_hop_address))
6969         {
6970           next_hop_set = 1;
6971         }
6972       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
6973         ;
6974       else if (unformat (i, "weight %d", &next_hop_weight))
6975         ;
6976       else if (unformat (i, "drop"))
6977         {
6978           is_drop = 1;
6979         }
6980       else if (unformat (i, "null-send-unreach"))
6981         {
6982           is_unreach = 1;
6983         }
6984       else if (unformat (i, "null-send-prohibit"))
6985         {
6986           is_prohibit = 1;
6987         }
6988       else if (unformat (i, "local"))
6989         {
6990           is_local = 1;
6991         }
6992       else if (unformat (i, "classify %d", &classify_table_index))
6993         {
6994           is_classify = 1;
6995         }
6996       else if (unformat (i, "del"))
6997         is_add = 0;
6998       else if (unformat (i, "add"))
6999         is_add = 1;
7000       else if (unformat (i, "not-last"))
7001         not_last = 1;
7002       else if (unformat (i, "resolve-via-host"))
7003         resolve_host = 1;
7004       else if (unformat (i, "resolve-via-attached"))
7005         resolve_attached = 1;
7006       else if (unformat (i, "multipath"))
7007         is_multipath = 1;
7008       else if (unformat (i, "vrf %d", &vrf_id))
7009         ;
7010       else if (unformat (i, "create-vrf"))
7011         create_vrf_if_needed = 1;
7012       else if (unformat (i, "count %d", &count))
7013         ;
7014       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
7015         ;
7016       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
7017         ;
7018       else if (unformat (i, "out-label %d", &next_hop_out_label))
7019         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
7020       else if (unformat (i, "via-label %d", &next_hop_via_label))
7021         ;
7022       else if (unformat (i, "random"))
7023         random_add_del = 1;
7024       else if (unformat (i, "seed %d", &random_seed))
7025         ;
7026       else
7027         {
7028           clib_warning ("parse error '%U'", format_unformat_error, i);
7029           return -99;
7030         }
7031     }
7032
7033   if (!next_hop_set && !is_drop && !is_local &&
7034       !is_classify && !is_unreach && !is_prohibit &&
7035       MPLS_LABEL_INVALID == next_hop_via_label)
7036     {
7037       errmsg
7038         ("next hop / local / drop / unreach / prohibit / classify not set");
7039       return -99;
7040     }
7041
7042   if (next_hop_set && MPLS_LABEL_INVALID != next_hop_via_label)
7043     {
7044       errmsg ("next hop and next-hop via label set");
7045       return -99;
7046     }
7047   if (address_set == 0)
7048     {
7049       errmsg ("missing addresses");
7050       return -99;
7051     }
7052
7053   if (address_length_set == 0)
7054     {
7055       errmsg ("missing address length");
7056       return -99;
7057     }
7058
7059   /* Generate a pile of unique, random routes */
7060   if (random_add_del)
7061     {
7062       u32 this_random_address;
7063       random_hash = hash_create (count, sizeof (uword));
7064
7065       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
7066       for (j = 0; j <= count; j++)
7067         {
7068           do
7069             {
7070               this_random_address = random_u32 (&random_seed);
7071               this_random_address =
7072                 clib_host_to_net_u32 (this_random_address);
7073             }
7074           while (hash_get (random_hash, this_random_address));
7075           vec_add1 (random_vector, this_random_address);
7076           hash_set (random_hash, this_random_address, 1);
7077         }
7078       hash_free (random_hash);
7079       v4_dst_address.as_u32 = random_vector[0];
7080     }
7081
7082   if (count > 1)
7083     {
7084       /* Turn on async mode */
7085       vam->async_mode = 1;
7086       vam->async_errors = 0;
7087       before = vat_time_now (vam);
7088     }
7089
7090   for (j = 0; j < count; j++)
7091     {
7092       /* Construct the API message */
7093       M2 (IP_ADD_DEL_ROUTE, mp,
7094           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
7095
7096       mp->next_hop_sw_if_index = ntohl (sw_if_index);
7097       mp->table_id = ntohl (vrf_id);
7098       mp->create_vrf_if_needed = create_vrf_if_needed;
7099
7100       mp->is_add = is_add;
7101       mp->is_drop = is_drop;
7102       mp->is_unreach = is_unreach;
7103       mp->is_prohibit = is_prohibit;
7104       mp->is_ipv6 = is_ipv6;
7105       mp->is_local = is_local;
7106       mp->is_classify = is_classify;
7107       mp->is_multipath = is_multipath;
7108       mp->is_resolve_host = resolve_host;
7109       mp->is_resolve_attached = resolve_attached;
7110       mp->not_last = not_last;
7111       mp->next_hop_weight = next_hop_weight;
7112       mp->dst_address_length = dst_address_length;
7113       mp->next_hop_table_id = ntohl (next_hop_table_id);
7114       mp->classify_table_index = ntohl (classify_table_index);
7115       mp->next_hop_via_label = ntohl (next_hop_via_label);
7116       mp->next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
7117       if (0 != mp->next_hop_n_out_labels)
7118         {
7119           memcpy (mp->next_hop_out_label_stack,
7120                   next_hop_out_label_stack,
7121                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
7122           vec_free (next_hop_out_label_stack);
7123         }
7124
7125       if (is_ipv6)
7126         {
7127           clib_memcpy (mp->dst_address, &v6_dst_address,
7128                        sizeof (v6_dst_address));
7129           if (next_hop_set)
7130             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
7131                          sizeof (v6_next_hop_address));
7132           increment_v6_address (&v6_dst_address);
7133         }
7134       else
7135         {
7136           clib_memcpy (mp->dst_address, &v4_dst_address,
7137                        sizeof (v4_dst_address));
7138           if (next_hop_set)
7139             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
7140                          sizeof (v4_next_hop_address));
7141           if (random_add_del)
7142             v4_dst_address.as_u32 = random_vector[j + 1];
7143           else
7144             increment_v4_address (&v4_dst_address);
7145         }
7146       /* send it... */
7147       S (mp);
7148       /* If we receive SIGTERM, stop now... */
7149       if (vam->do_exit)
7150         break;
7151     }
7152
7153   /* When testing multiple add/del ops, use a control-ping to sync */
7154   if (count > 1)
7155     {
7156       vl_api_control_ping_t *mp_ping;
7157       f64 after;
7158       f64 timeout;
7159
7160       /* Shut off async mode */
7161       vam->async_mode = 0;
7162
7163       M (CONTROL_PING, mp_ping);
7164       S (mp_ping);
7165
7166       timeout = vat_time_now (vam) + 1.0;
7167       while (vat_time_now (vam) < timeout)
7168         if (vam->result_ready == 1)
7169           goto out;
7170       vam->retval = -99;
7171
7172     out:
7173       if (vam->retval == -99)
7174         errmsg ("timeout");
7175
7176       if (vam->async_errors > 0)
7177         {
7178           errmsg ("%d asynchronous errors", vam->async_errors);
7179           vam->retval = -98;
7180         }
7181       vam->async_errors = 0;
7182       after = vat_time_now (vam);
7183
7184       /* slim chance, but we might have eaten SIGTERM on the first iteration */
7185       if (j > 0)
7186         count = j;
7187
7188       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
7189              count, after - before, count / (after - before));
7190     }
7191   else
7192     {
7193       int ret;
7194
7195       /* Wait for a reply... */
7196       W (ret);
7197       return ret;
7198     }
7199
7200   /* Return the good/bad news */
7201   return (vam->retval);
7202 }
7203
7204 static int
7205 api_ip_mroute_add_del (vat_main_t * vam)
7206 {
7207   unformat_input_t *i = vam->input;
7208   vl_api_ip_mroute_add_del_t *mp;
7209   u32 sw_if_index = ~0, vrf_id = 0;
7210   u8 is_ipv6 = 0;
7211   u8 is_local = 0;
7212   u8 create_vrf_if_needed = 0;
7213   u8 is_add = 1;
7214   u8 address_set = 0;
7215   u32 grp_address_length = 0;
7216   ip4_address_t v4_grp_address, v4_src_address;
7217   ip6_address_t v6_grp_address, v6_src_address;
7218   mfib_itf_flags_t iflags = 0;
7219   mfib_entry_flags_t eflags = 0;
7220   int ret;
7221
7222   /* Parse args required to build the message */
7223   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7224     {
7225       if (unformat (i, "sw_if_index %d", &sw_if_index))
7226         ;
7227       else if (unformat (i, "%U %U",
7228                          unformat_ip4_address, &v4_src_address,
7229                          unformat_ip4_address, &v4_grp_address))
7230         {
7231           grp_address_length = 64;
7232           address_set = 1;
7233           is_ipv6 = 0;
7234         }
7235       else if (unformat (i, "%U %U",
7236                          unformat_ip6_address, &v6_src_address,
7237                          unformat_ip6_address, &v6_grp_address))
7238         {
7239           grp_address_length = 256;
7240           address_set = 1;
7241           is_ipv6 = 1;
7242         }
7243       else if (unformat (i, "%U", unformat_ip4_address, &v4_grp_address))
7244         {
7245           memset (&v4_src_address, 0, sizeof (v4_src_address));
7246           grp_address_length = 32;
7247           address_set = 1;
7248           is_ipv6 = 0;
7249         }
7250       else if (unformat (i, "%U", unformat_ip6_address, &v6_grp_address))
7251         {
7252           memset (&v6_src_address, 0, sizeof (v6_src_address));
7253           grp_address_length = 128;
7254           address_set = 1;
7255           is_ipv6 = 1;
7256         }
7257       else if (unformat (i, "/%d", &grp_address_length))
7258         ;
7259       else if (unformat (i, "local"))
7260         {
7261           is_local = 1;
7262         }
7263       else if (unformat (i, "del"))
7264         is_add = 0;
7265       else if (unformat (i, "add"))
7266         is_add = 1;
7267       else if (unformat (i, "vrf %d", &vrf_id))
7268         ;
7269       else if (unformat (i, "create-vrf"))
7270         create_vrf_if_needed = 1;
7271       else if (unformat (i, "%U", unformat_mfib_itf_flags, &iflags))
7272         ;
7273       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
7274         ;
7275       else
7276         {
7277           clib_warning ("parse error '%U'", format_unformat_error, i);
7278           return -99;
7279         }
7280     }
7281
7282   if (address_set == 0)
7283     {
7284       errmsg ("missing addresses\n");
7285       return -99;
7286     }
7287
7288   /* Construct the API message */
7289   M (IP_MROUTE_ADD_DEL, mp);
7290
7291   mp->next_hop_sw_if_index = ntohl (sw_if_index);
7292   mp->table_id = ntohl (vrf_id);
7293   mp->create_vrf_if_needed = create_vrf_if_needed;
7294
7295   mp->is_add = is_add;
7296   mp->is_ipv6 = is_ipv6;
7297   mp->is_local = is_local;
7298   mp->itf_flags = ntohl (iflags);
7299   mp->entry_flags = ntohl (eflags);
7300   mp->grp_address_length = grp_address_length;
7301   mp->grp_address_length = ntohs (mp->grp_address_length);
7302
7303   if (is_ipv6)
7304     {
7305       clib_memcpy (mp->grp_address, &v6_grp_address, sizeof (v6_grp_address));
7306       clib_memcpy (mp->src_address, &v6_src_address, sizeof (v6_src_address));
7307     }
7308   else
7309     {
7310       clib_memcpy (mp->grp_address, &v4_grp_address, sizeof (v4_grp_address));
7311       clib_memcpy (mp->src_address, &v4_src_address, sizeof (v4_src_address));
7312
7313     }
7314
7315   /* send it... */
7316   S (mp);
7317   /* Wait for a reply... */
7318   W (ret);
7319   return ret;
7320 }
7321
7322 static int
7323 api_mpls_route_add_del (vat_main_t * vam)
7324 {
7325   unformat_input_t *i = vam->input;
7326   vl_api_mpls_route_add_del_t *mp;
7327   u32 sw_if_index = ~0, table_id = 0;
7328   u8 create_table_if_needed = 0;
7329   u8 is_add = 1;
7330   u32 next_hop_weight = 1;
7331   u8 is_multipath = 0;
7332   u32 next_hop_table_id = 0;
7333   u8 next_hop_set = 0;
7334   ip4_address_t v4_next_hop_address = {
7335     .as_u32 = 0,
7336   };
7337   ip6_address_t v6_next_hop_address = { {0} };
7338   int count = 1;
7339   int j;
7340   f64 before = 0;
7341   u32 classify_table_index = ~0;
7342   u8 is_classify = 0;
7343   u8 resolve_host = 0, resolve_attached = 0;
7344   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
7345   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
7346   mpls_label_t *next_hop_out_label_stack = NULL;
7347   mpls_label_t local_label = MPLS_LABEL_INVALID;
7348   u8 is_eos = 0;
7349   u8 next_hop_proto_is_ip4 = 1;
7350
7351   /* Parse args required to build the message */
7352   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7353     {
7354       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7355         ;
7356       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7357         ;
7358       else if (unformat (i, "%d", &local_label))
7359         ;
7360       else if (unformat (i, "eos"))
7361         is_eos = 1;
7362       else if (unformat (i, "non-eos"))
7363         is_eos = 0;
7364       else if (unformat (i, "via %U", unformat_ip4_address,
7365                          &v4_next_hop_address))
7366         {
7367           next_hop_set = 1;
7368           next_hop_proto_is_ip4 = 1;
7369         }
7370       else if (unformat (i, "via %U", unformat_ip6_address,
7371                          &v6_next_hop_address))
7372         {
7373           next_hop_set = 1;
7374           next_hop_proto_is_ip4 = 0;
7375         }
7376       else if (unformat (i, "weight %d", &next_hop_weight))
7377         ;
7378       else if (unformat (i, "create-table"))
7379         create_table_if_needed = 1;
7380       else if (unformat (i, "classify %d", &classify_table_index))
7381         {
7382           is_classify = 1;
7383         }
7384       else if (unformat (i, "del"))
7385         is_add = 0;
7386       else if (unformat (i, "add"))
7387         is_add = 1;
7388       else if (unformat (i, "resolve-via-host"))
7389         resolve_host = 1;
7390       else if (unformat (i, "resolve-via-attached"))
7391         resolve_attached = 1;
7392       else if (unformat (i, "multipath"))
7393         is_multipath = 1;
7394       else if (unformat (i, "count %d", &count))
7395         ;
7396       else if (unformat (i, "lookup-in-ip4-table %d", &next_hop_table_id))
7397         {
7398           next_hop_set = 1;
7399           next_hop_proto_is_ip4 = 1;
7400         }
7401       else if (unformat (i, "lookup-in-ip6-table %d", &next_hop_table_id))
7402         {
7403           next_hop_set = 1;
7404           next_hop_proto_is_ip4 = 0;
7405         }
7406       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
7407         ;
7408       else if (unformat (i, "via-label %d", &next_hop_via_label))
7409         ;
7410       else if (unformat (i, "out-label %d", &next_hop_out_label))
7411         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
7412       else
7413         {
7414           clib_warning ("parse error '%U'", format_unformat_error, i);
7415           return -99;
7416         }
7417     }
7418
7419   if (!next_hop_set && !is_classify)
7420     {
7421       errmsg ("next hop / classify not set");
7422       return -99;
7423     }
7424
7425   if (MPLS_LABEL_INVALID == local_label)
7426     {
7427       errmsg ("missing label");
7428       return -99;
7429     }
7430
7431   if (count > 1)
7432     {
7433       /* Turn on async mode */
7434       vam->async_mode = 1;
7435       vam->async_errors = 0;
7436       before = vat_time_now (vam);
7437     }
7438
7439   for (j = 0; j < count; j++)
7440     {
7441       /* Construct the API message */
7442       M2 (MPLS_ROUTE_ADD_DEL, mp,
7443           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
7444
7445       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
7446       mp->mr_table_id = ntohl (table_id);
7447       mp->mr_create_table_if_needed = create_table_if_needed;
7448
7449       mp->mr_is_add = is_add;
7450       mp->mr_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
7451       mp->mr_is_classify = is_classify;
7452       mp->mr_is_multipath = is_multipath;
7453       mp->mr_is_resolve_host = resolve_host;
7454       mp->mr_is_resolve_attached = resolve_attached;
7455       mp->mr_next_hop_weight = next_hop_weight;
7456       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
7457       mp->mr_classify_table_index = ntohl (classify_table_index);
7458       mp->mr_next_hop_via_label = ntohl (next_hop_via_label);
7459       mp->mr_label = ntohl (local_label);
7460       mp->mr_eos = is_eos;
7461
7462       mp->mr_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
7463       if (0 != mp->mr_next_hop_n_out_labels)
7464         {
7465           memcpy (mp->mr_next_hop_out_label_stack,
7466                   next_hop_out_label_stack,
7467                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
7468           vec_free (next_hop_out_label_stack);
7469         }
7470
7471       if (next_hop_set)
7472         {
7473           if (next_hop_proto_is_ip4)
7474             {
7475               clib_memcpy (mp->mr_next_hop,
7476                            &v4_next_hop_address,
7477                            sizeof (v4_next_hop_address));
7478             }
7479           else
7480             {
7481               clib_memcpy (mp->mr_next_hop,
7482                            &v6_next_hop_address,
7483                            sizeof (v6_next_hop_address));
7484             }
7485         }
7486       local_label++;
7487
7488       /* send it... */
7489       S (mp);
7490       /* If we receive SIGTERM, stop now... */
7491       if (vam->do_exit)
7492         break;
7493     }
7494
7495   /* When testing multiple add/del ops, use a control-ping to sync */
7496   if (count > 1)
7497     {
7498       vl_api_control_ping_t *mp_ping;
7499       f64 after;
7500       f64 timeout;
7501
7502       /* Shut off async mode */
7503       vam->async_mode = 0;
7504
7505       M (CONTROL_PING, mp_ping);
7506       S (mp_ping);
7507
7508       timeout = vat_time_now (vam) + 1.0;
7509       while (vat_time_now (vam) < timeout)
7510         if (vam->result_ready == 1)
7511           goto out;
7512       vam->retval = -99;
7513
7514     out:
7515       if (vam->retval == -99)
7516         errmsg ("timeout");
7517
7518       if (vam->async_errors > 0)
7519         {
7520           errmsg ("%d asynchronous errors", vam->async_errors);
7521           vam->retval = -98;
7522         }
7523       vam->async_errors = 0;
7524       after = vat_time_now (vam);
7525
7526       /* slim chance, but we might have eaten SIGTERM on the first iteration */
7527       if (j > 0)
7528         count = j;
7529
7530       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
7531              count, after - before, count / (after - before));
7532     }
7533   else
7534     {
7535       int ret;
7536
7537       /* Wait for a reply... */
7538       W (ret);
7539       return ret;
7540     }
7541
7542   /* Return the good/bad news */
7543   return (vam->retval);
7544 }
7545
7546 static int
7547 api_mpls_ip_bind_unbind (vat_main_t * vam)
7548 {
7549   unformat_input_t *i = vam->input;
7550   vl_api_mpls_ip_bind_unbind_t *mp;
7551   u32 ip_table_id = 0;
7552   u8 create_table_if_needed = 0;
7553   u8 is_bind = 1;
7554   u8 is_ip4 = 1;
7555   ip4_address_t v4_address;
7556   ip6_address_t v6_address;
7557   u32 address_length;
7558   u8 address_set = 0;
7559   mpls_label_t local_label = MPLS_LABEL_INVALID;
7560   int ret;
7561
7562   /* Parse args required to build the message */
7563   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7564     {
7565       if (unformat (i, "%U/%d", unformat_ip4_address,
7566                     &v4_address, &address_length))
7567         {
7568           is_ip4 = 1;
7569           address_set = 1;
7570         }
7571       else if (unformat (i, "%U/%d", unformat_ip6_address,
7572                          &v6_address, &address_length))
7573         {
7574           is_ip4 = 0;
7575           address_set = 1;
7576         }
7577       else if (unformat (i, "%d", &local_label))
7578         ;
7579       else if (unformat (i, "create-table"))
7580         create_table_if_needed = 1;
7581       else if (unformat (i, "table-id %d", &ip_table_id))
7582         ;
7583       else if (unformat (i, "unbind"))
7584         is_bind = 0;
7585       else if (unformat (i, "bind"))
7586         is_bind = 1;
7587       else
7588         {
7589           clib_warning ("parse error '%U'", format_unformat_error, i);
7590           return -99;
7591         }
7592     }
7593
7594   if (!address_set)
7595     {
7596       errmsg ("IP addres not set");
7597       return -99;
7598     }
7599
7600   if (MPLS_LABEL_INVALID == local_label)
7601     {
7602       errmsg ("missing label");
7603       return -99;
7604     }
7605
7606   /* Construct the API message */
7607   M (MPLS_IP_BIND_UNBIND, mp);
7608
7609   mp->mb_create_table_if_needed = create_table_if_needed;
7610   mp->mb_is_bind = is_bind;
7611   mp->mb_is_ip4 = is_ip4;
7612   mp->mb_ip_table_id = ntohl (ip_table_id);
7613   mp->mb_mpls_table_id = 0;
7614   mp->mb_label = ntohl (local_label);
7615   mp->mb_address_length = address_length;
7616
7617   if (is_ip4)
7618     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
7619   else
7620     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
7621
7622   /* send it... */
7623   S (mp);
7624
7625   /* Wait for a reply... */
7626   W (ret);
7627   return ret;
7628 }
7629
7630 static int
7631 api_proxy_arp_add_del (vat_main_t * vam)
7632 {
7633   unformat_input_t *i = vam->input;
7634   vl_api_proxy_arp_add_del_t *mp;
7635   u32 vrf_id = 0;
7636   u8 is_add = 1;
7637   ip4_address_t lo, hi;
7638   u8 range_set = 0;
7639   int ret;
7640
7641   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7642     {
7643       if (unformat (i, "vrf %d", &vrf_id))
7644         ;
7645       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
7646                          unformat_ip4_address, &hi))
7647         range_set = 1;
7648       else if (unformat (i, "del"))
7649         is_add = 0;
7650       else
7651         {
7652           clib_warning ("parse error '%U'", format_unformat_error, i);
7653           return -99;
7654         }
7655     }
7656
7657   if (range_set == 0)
7658     {
7659       errmsg ("address range not set");
7660       return -99;
7661     }
7662
7663   M (PROXY_ARP_ADD_DEL, mp);
7664
7665   mp->vrf_id = ntohl (vrf_id);
7666   mp->is_add = is_add;
7667   clib_memcpy (mp->low_address, &lo, sizeof (mp->low_address));
7668   clib_memcpy (mp->hi_address, &hi, sizeof (mp->hi_address));
7669
7670   S (mp);
7671   W (ret);
7672   return ret;
7673 }
7674
7675 static int
7676 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
7677 {
7678   unformat_input_t *i = vam->input;
7679   vl_api_proxy_arp_intfc_enable_disable_t *mp;
7680   u32 sw_if_index;
7681   u8 enable = 1;
7682   u8 sw_if_index_set = 0;
7683   int ret;
7684
7685   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7686     {
7687       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7688         sw_if_index_set = 1;
7689       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7690         sw_if_index_set = 1;
7691       else if (unformat (i, "enable"))
7692         enable = 1;
7693       else if (unformat (i, "disable"))
7694         enable = 0;
7695       else
7696         {
7697           clib_warning ("parse error '%U'", format_unformat_error, i);
7698           return -99;
7699         }
7700     }
7701
7702   if (sw_if_index_set == 0)
7703     {
7704       errmsg ("missing interface name or sw_if_index");
7705       return -99;
7706     }
7707
7708   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
7709
7710   mp->sw_if_index = ntohl (sw_if_index);
7711   mp->enable_disable = enable;
7712
7713   S (mp);
7714   W (ret);
7715   return ret;
7716 }
7717
7718 static int
7719 api_mpls_tunnel_add_del (vat_main_t * vam)
7720 {
7721   unformat_input_t *i = vam->input;
7722   vl_api_mpls_tunnel_add_del_t *mp;
7723
7724   u8 is_add = 1;
7725   u8 l2_only = 0;
7726   u32 sw_if_index = ~0;
7727   u32 next_hop_sw_if_index = ~0;
7728   u32 next_hop_proto_is_ip4 = 1;
7729
7730   u32 next_hop_table_id = 0;
7731   ip4_address_t v4_next_hop_address = {
7732     .as_u32 = 0,
7733   };
7734   ip6_address_t v6_next_hop_address = { {0} };
7735   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID, *labels = NULL;
7736   int ret;
7737
7738   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7739     {
7740       if (unformat (i, "add"))
7741         is_add = 1;
7742       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
7743         is_add = 0;
7744       else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
7745         ;
7746       else if (unformat (i, "via %U",
7747                          unformat_ip4_address, &v4_next_hop_address))
7748         {
7749           next_hop_proto_is_ip4 = 1;
7750         }
7751       else if (unformat (i, "via %U",
7752                          unformat_ip6_address, &v6_next_hop_address))
7753         {
7754           next_hop_proto_is_ip4 = 0;
7755         }
7756       else if (unformat (i, "l2-only"))
7757         l2_only = 1;
7758       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
7759         ;
7760       else if (unformat (i, "out-label %d", &next_hop_out_label))
7761         vec_add1 (labels, ntohl (next_hop_out_label));
7762       else
7763         {
7764           clib_warning ("parse error '%U'", format_unformat_error, i);
7765           return -99;
7766         }
7767     }
7768
7769   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (mpls_label_t) * vec_len (labels));
7770
7771   mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
7772   mp->mt_sw_if_index = ntohl (sw_if_index);
7773   mp->mt_is_add = is_add;
7774   mp->mt_l2_only = l2_only;
7775   mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
7776   mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
7777
7778   mp->mt_next_hop_n_out_labels = vec_len (labels);
7779
7780   if (0 != mp->mt_next_hop_n_out_labels)
7781     {
7782       clib_memcpy (mp->mt_next_hop_out_label_stack, labels,
7783                    sizeof (mpls_label_t) * mp->mt_next_hop_n_out_labels);
7784       vec_free (labels);
7785     }
7786
7787   if (next_hop_proto_is_ip4)
7788     {
7789       clib_memcpy (mp->mt_next_hop,
7790                    &v4_next_hop_address, sizeof (v4_next_hop_address));
7791     }
7792   else
7793     {
7794       clib_memcpy (mp->mt_next_hop,
7795                    &v6_next_hop_address, sizeof (v6_next_hop_address));
7796     }
7797
7798   S (mp);
7799   W (ret);
7800   return ret;
7801 }
7802
7803 static int
7804 api_sw_interface_set_unnumbered (vat_main_t * vam)
7805 {
7806   unformat_input_t *i = vam->input;
7807   vl_api_sw_interface_set_unnumbered_t *mp;
7808   u32 sw_if_index;
7809   u32 unnum_sw_index = ~0;
7810   u8 is_add = 1;
7811   u8 sw_if_index_set = 0;
7812   int ret;
7813
7814   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7815     {
7816       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7817         sw_if_index_set = 1;
7818       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7819         sw_if_index_set = 1;
7820       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
7821         ;
7822       else if (unformat (i, "del"))
7823         is_add = 0;
7824       else
7825         {
7826           clib_warning ("parse error '%U'", format_unformat_error, i);
7827           return -99;
7828         }
7829     }
7830
7831   if (sw_if_index_set == 0)
7832     {
7833       errmsg ("missing interface name or sw_if_index");
7834       return -99;
7835     }
7836
7837   M (SW_INTERFACE_SET_UNNUMBERED, mp);
7838
7839   mp->sw_if_index = ntohl (sw_if_index);
7840   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
7841   mp->is_add = is_add;
7842
7843   S (mp);
7844   W (ret);
7845   return ret;
7846 }
7847
7848 static int
7849 api_ip_neighbor_add_del (vat_main_t * vam)
7850 {
7851   unformat_input_t *i = vam->input;
7852   vl_api_ip_neighbor_add_del_t *mp;
7853   u32 sw_if_index;
7854   u8 sw_if_index_set = 0;
7855   u8 is_add = 1;
7856   u8 is_static = 0;
7857   u8 is_no_fib_entry = 0;
7858   u8 mac_address[6];
7859   u8 mac_set = 0;
7860   u8 v4_address_set = 0;
7861   u8 v6_address_set = 0;
7862   ip4_address_t v4address;
7863   ip6_address_t v6address;
7864   int ret;
7865
7866   memset (mac_address, 0, sizeof (mac_address));
7867
7868   /* Parse args required to build the message */
7869   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7870     {
7871       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7872         {
7873           mac_set = 1;
7874         }
7875       else if (unformat (i, "del"))
7876         is_add = 0;
7877       else
7878         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7879         sw_if_index_set = 1;
7880       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7881         sw_if_index_set = 1;
7882       else if (unformat (i, "is_static"))
7883         is_static = 1;
7884       else if (unformat (i, "no-fib-entry"))
7885         is_no_fib_entry = 1;
7886       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
7887         v4_address_set = 1;
7888       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
7889         v6_address_set = 1;
7890       else
7891         {
7892           clib_warning ("parse error '%U'", format_unformat_error, i);
7893           return -99;
7894         }
7895     }
7896
7897   if (sw_if_index_set == 0)
7898     {
7899       errmsg ("missing interface name or sw_if_index");
7900       return -99;
7901     }
7902   if (v4_address_set && v6_address_set)
7903     {
7904       errmsg ("both v4 and v6 addresses set");
7905       return -99;
7906     }
7907   if (!v4_address_set && !v6_address_set)
7908     {
7909       errmsg ("no address set");
7910       return -99;
7911     }
7912
7913   /* Construct the API message */
7914   M (IP_NEIGHBOR_ADD_DEL, mp);
7915
7916   mp->sw_if_index = ntohl (sw_if_index);
7917   mp->is_add = is_add;
7918   mp->is_static = is_static;
7919   mp->is_no_adj_fib = is_no_fib_entry;
7920   if (mac_set)
7921     clib_memcpy (mp->mac_address, mac_address, 6);
7922   if (v6_address_set)
7923     {
7924       mp->is_ipv6 = 1;
7925       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
7926     }
7927   else
7928     {
7929       /* mp->is_ipv6 = 0; via memset in M macro above */
7930       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
7931     }
7932
7933   /* send it... */
7934   S (mp);
7935
7936   /* Wait for a reply, return good/bad news  */
7937   W (ret);
7938   return ret;
7939 }
7940
7941 static int
7942 api_reset_vrf (vat_main_t * vam)
7943 {
7944   unformat_input_t *i = vam->input;
7945   vl_api_reset_vrf_t *mp;
7946   u32 vrf_id = 0;
7947   u8 is_ipv6 = 0;
7948   u8 vrf_id_set = 0;
7949   int ret;
7950
7951   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7952     {
7953       if (unformat (i, "vrf %d", &vrf_id))
7954         vrf_id_set = 1;
7955       else if (unformat (i, "ipv6"))
7956         is_ipv6 = 1;
7957       else
7958         {
7959           clib_warning ("parse error '%U'", format_unformat_error, i);
7960           return -99;
7961         }
7962     }
7963
7964   if (vrf_id_set == 0)
7965     {
7966       errmsg ("missing vrf id");
7967       return -99;
7968     }
7969
7970   M (RESET_VRF, mp);
7971
7972   mp->vrf_id = ntohl (vrf_id);
7973   mp->is_ipv6 = is_ipv6;
7974
7975   S (mp);
7976   W (ret);
7977   return ret;
7978 }
7979
7980 static int
7981 api_create_vlan_subif (vat_main_t * vam)
7982 {
7983   unformat_input_t *i = vam->input;
7984   vl_api_create_vlan_subif_t *mp;
7985   u32 sw_if_index;
7986   u8 sw_if_index_set = 0;
7987   u32 vlan_id;
7988   u8 vlan_id_set = 0;
7989   int ret;
7990
7991   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7992     {
7993       if (unformat (i, "sw_if_index %d", &sw_if_index))
7994         sw_if_index_set = 1;
7995       else
7996         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7997         sw_if_index_set = 1;
7998       else if (unformat (i, "vlan %d", &vlan_id))
7999         vlan_id_set = 1;
8000       else
8001         {
8002           clib_warning ("parse error '%U'", format_unformat_error, i);
8003           return -99;
8004         }
8005     }
8006
8007   if (sw_if_index_set == 0)
8008     {
8009       errmsg ("missing interface name or sw_if_index");
8010       return -99;
8011     }
8012
8013   if (vlan_id_set == 0)
8014     {
8015       errmsg ("missing vlan_id");
8016       return -99;
8017     }
8018   M (CREATE_VLAN_SUBIF, mp);
8019
8020   mp->sw_if_index = ntohl (sw_if_index);
8021   mp->vlan_id = ntohl (vlan_id);
8022
8023   S (mp);
8024   W (ret);
8025   return ret;
8026 }
8027
8028 #define foreach_create_subif_bit                \
8029 _(no_tags)                                      \
8030 _(one_tag)                                      \
8031 _(two_tags)                                     \
8032 _(dot1ad)                                       \
8033 _(exact_match)                                  \
8034 _(default_sub)                                  \
8035 _(outer_vlan_id_any)                            \
8036 _(inner_vlan_id_any)
8037
8038 static int
8039 api_create_subif (vat_main_t * vam)
8040 {
8041   unformat_input_t *i = vam->input;
8042   vl_api_create_subif_t *mp;
8043   u32 sw_if_index;
8044   u8 sw_if_index_set = 0;
8045   u32 sub_id;
8046   u8 sub_id_set = 0;
8047   u32 no_tags = 0;
8048   u32 one_tag = 0;
8049   u32 two_tags = 0;
8050   u32 dot1ad = 0;
8051   u32 exact_match = 0;
8052   u32 default_sub = 0;
8053   u32 outer_vlan_id_any = 0;
8054   u32 inner_vlan_id_any = 0;
8055   u32 tmp;
8056   u16 outer_vlan_id = 0;
8057   u16 inner_vlan_id = 0;
8058   int ret;
8059
8060   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8061     {
8062       if (unformat (i, "sw_if_index %d", &sw_if_index))
8063         sw_if_index_set = 1;
8064       else
8065         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8066         sw_if_index_set = 1;
8067       else if (unformat (i, "sub_id %d", &sub_id))
8068         sub_id_set = 1;
8069       else if (unformat (i, "outer_vlan_id %d", &tmp))
8070         outer_vlan_id = tmp;
8071       else if (unformat (i, "inner_vlan_id %d", &tmp))
8072         inner_vlan_id = tmp;
8073
8074 #define _(a) else if (unformat (i, #a)) a = 1 ;
8075       foreach_create_subif_bit
8076 #undef _
8077         else
8078         {
8079           clib_warning ("parse error '%U'", format_unformat_error, i);
8080           return -99;
8081         }
8082     }
8083
8084   if (sw_if_index_set == 0)
8085     {
8086       errmsg ("missing interface name or sw_if_index");
8087       return -99;
8088     }
8089
8090   if (sub_id_set == 0)
8091     {
8092       errmsg ("missing sub_id");
8093       return -99;
8094     }
8095   M (CREATE_SUBIF, mp);
8096
8097   mp->sw_if_index = ntohl (sw_if_index);
8098   mp->sub_id = ntohl (sub_id);
8099
8100 #define _(a) mp->a = a;
8101   foreach_create_subif_bit;
8102 #undef _
8103
8104   mp->outer_vlan_id = ntohs (outer_vlan_id);
8105   mp->inner_vlan_id = ntohs (inner_vlan_id);
8106
8107   S (mp);
8108   W (ret);
8109   return ret;
8110 }
8111
8112 static int
8113 api_oam_add_del (vat_main_t * vam)
8114 {
8115   unformat_input_t *i = vam->input;
8116   vl_api_oam_add_del_t *mp;
8117   u32 vrf_id = 0;
8118   u8 is_add = 1;
8119   ip4_address_t src, dst;
8120   u8 src_set = 0;
8121   u8 dst_set = 0;
8122   int ret;
8123
8124   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8125     {
8126       if (unformat (i, "vrf %d", &vrf_id))
8127         ;
8128       else if (unformat (i, "src %U", unformat_ip4_address, &src))
8129         src_set = 1;
8130       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
8131         dst_set = 1;
8132       else if (unformat (i, "del"))
8133         is_add = 0;
8134       else
8135         {
8136           clib_warning ("parse error '%U'", format_unformat_error, i);
8137           return -99;
8138         }
8139     }
8140
8141   if (src_set == 0)
8142     {
8143       errmsg ("missing src addr");
8144       return -99;
8145     }
8146
8147   if (dst_set == 0)
8148     {
8149       errmsg ("missing dst addr");
8150       return -99;
8151     }
8152
8153   M (OAM_ADD_DEL, mp);
8154
8155   mp->vrf_id = ntohl (vrf_id);
8156   mp->is_add = is_add;
8157   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
8158   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
8159
8160   S (mp);
8161   W (ret);
8162   return ret;
8163 }
8164
8165 static int
8166 api_reset_fib (vat_main_t * vam)
8167 {
8168   unformat_input_t *i = vam->input;
8169   vl_api_reset_fib_t *mp;
8170   u32 vrf_id = 0;
8171   u8 is_ipv6 = 0;
8172   u8 vrf_id_set = 0;
8173
8174   int ret;
8175   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8176     {
8177       if (unformat (i, "vrf %d", &vrf_id))
8178         vrf_id_set = 1;
8179       else if (unformat (i, "ipv6"))
8180         is_ipv6 = 1;
8181       else
8182         {
8183           clib_warning ("parse error '%U'", format_unformat_error, i);
8184           return -99;
8185         }
8186     }
8187
8188   if (vrf_id_set == 0)
8189     {
8190       errmsg ("missing vrf id");
8191       return -99;
8192     }
8193
8194   M (RESET_FIB, mp);
8195
8196   mp->vrf_id = ntohl (vrf_id);
8197   mp->is_ipv6 = is_ipv6;
8198
8199   S (mp);
8200   W (ret);
8201   return ret;
8202 }
8203
8204 static int
8205 api_dhcp_proxy_config (vat_main_t * vam)
8206 {
8207   unformat_input_t *i = vam->input;
8208   vl_api_dhcp_proxy_config_t *mp;
8209   u32 rx_vrf_id = 0;
8210   u32 server_vrf_id = 0;
8211   u8 is_add = 1;
8212   u8 v4_address_set = 0;
8213   u8 v6_address_set = 0;
8214   ip4_address_t v4address;
8215   ip6_address_t v6address;
8216   u8 v4_src_address_set = 0;
8217   u8 v6_src_address_set = 0;
8218   ip4_address_t v4srcaddress;
8219   ip6_address_t v6srcaddress;
8220   int ret;
8221
8222   /* Parse args required to build the message */
8223   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8224     {
8225       if (unformat (i, "del"))
8226         is_add = 0;
8227       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
8228         ;
8229       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
8230         ;
8231       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
8232         v4_address_set = 1;
8233       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
8234         v6_address_set = 1;
8235       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
8236         v4_src_address_set = 1;
8237       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
8238         v6_src_address_set = 1;
8239       else
8240         break;
8241     }
8242
8243   if (v4_address_set && v6_address_set)
8244     {
8245       errmsg ("both v4 and v6 server addresses set");
8246       return -99;
8247     }
8248   if (!v4_address_set && !v6_address_set)
8249     {
8250       errmsg ("no server addresses set");
8251       return -99;
8252     }
8253
8254   if (v4_src_address_set && v6_src_address_set)
8255     {
8256       errmsg ("both v4 and v6  src addresses set");
8257       return -99;
8258     }
8259   if (!v4_src_address_set && !v6_src_address_set)
8260     {
8261       errmsg ("no src addresses set");
8262       return -99;
8263     }
8264
8265   if (!(v4_src_address_set && v4_address_set) &&
8266       !(v6_src_address_set && v6_address_set))
8267     {
8268       errmsg ("no matching server and src addresses set");
8269       return -99;
8270     }
8271
8272   /* Construct the API message */
8273   M (DHCP_PROXY_CONFIG, mp);
8274
8275   mp->is_add = is_add;
8276   mp->rx_vrf_id = ntohl (rx_vrf_id);
8277   mp->server_vrf_id = ntohl (server_vrf_id);
8278   if (v6_address_set)
8279     {
8280       mp->is_ipv6 = 1;
8281       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
8282       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
8283     }
8284   else
8285     {
8286       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
8287       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
8288     }
8289
8290   /* send it... */
8291   S (mp);
8292
8293   /* Wait for a reply, return good/bad news  */
8294   W (ret);
8295   return ret;
8296 }
8297
8298 #define vl_api_dhcp_proxy_details_t_endian vl_noop_handler
8299 #define vl_api_dhcp_proxy_details_t_print vl_noop_handler
8300
8301 static void
8302 vl_api_dhcp_proxy_details_t_handler (vl_api_dhcp_proxy_details_t * mp)
8303 {
8304   vat_main_t *vam = &vat_main;
8305   u32 i, count = mp->count;
8306   vl_api_dhcp_server_t *s;
8307
8308   if (mp->is_ipv6)
8309     print (vam->ofp,
8310            "RX Table-ID %d, Source Address %U, VSS FIB-ID %d, VSS OUI %d",
8311            ntohl (mp->rx_vrf_id),
8312            format_ip6_address, mp->dhcp_src_address,
8313            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
8314   else
8315     print (vam->ofp,
8316            "RX Table-ID %d, Source Address %U, VSS FIB-ID %d, VSS OUI %d",
8317            ntohl (mp->rx_vrf_id),
8318            format_ip4_address, mp->dhcp_src_address,
8319            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
8320
8321   for (i = 0; i < count; i++)
8322     {
8323       s = &mp->servers[i];
8324
8325       if (mp->is_ipv6)
8326         print (vam->ofp,
8327                " Server Table-ID %d, Server Address %U",
8328                ntohl (s->server_vrf_id), format_ip6_address, s->dhcp_server);
8329       else
8330         print (vam->ofp,
8331                " Server Table-ID %d, Server Address %U",
8332                ntohl (s->server_vrf_id), format_ip4_address, s->dhcp_server);
8333     }
8334 }
8335
8336 static void vl_api_dhcp_proxy_details_t_handler_json
8337   (vl_api_dhcp_proxy_details_t * mp)
8338 {
8339   vat_main_t *vam = &vat_main;
8340   vat_json_node_t *node = NULL;
8341   u32 i, count = mp->count;
8342   struct in_addr ip4;
8343   struct in6_addr ip6;
8344   vl_api_dhcp_server_t *s;
8345
8346   if (VAT_JSON_ARRAY != vam->json_tree.type)
8347     {
8348       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
8349       vat_json_init_array (&vam->json_tree);
8350     }
8351   node = vat_json_array_add (&vam->json_tree);
8352
8353   vat_json_init_object (node);
8354   vat_json_object_add_uint (node, "rx-table-id", ntohl (mp->rx_vrf_id));
8355   vat_json_object_add_uint (node, "vss-fib-id", ntohl (mp->vss_fib_id));
8356   vat_json_object_add_uint (node, "vss-oui", ntohl (mp->vss_oui));
8357
8358   if (mp->is_ipv6)
8359     {
8360       clib_memcpy (&ip6, &mp->dhcp_src_address, sizeof (ip6));
8361       vat_json_object_add_ip6 (node, "src_address", ip6);
8362     }
8363   else
8364     {
8365       clib_memcpy (&ip4, &mp->dhcp_src_address, sizeof (ip4));
8366       vat_json_object_add_ip4 (node, "src_address", ip4);
8367     }
8368
8369   for (i = 0; i < count; i++)
8370     {
8371       s = &mp->servers[i];
8372
8373       vat_json_object_add_uint (node, "server-table-id",
8374                                 ntohl (s->server_vrf_id));
8375
8376       if (mp->is_ipv6)
8377         {
8378           clib_memcpy (&ip4, &s->dhcp_server, sizeof (ip4));
8379           vat_json_object_add_ip4 (node, "src_address", ip4);
8380         }
8381       else
8382         {
8383           clib_memcpy (&ip6, &s->dhcp_server, sizeof (ip6));
8384           vat_json_object_add_ip6 (node, "server_address", ip6);
8385         }
8386     }
8387 }
8388
8389 static int
8390 api_dhcp_proxy_dump (vat_main_t * vam)
8391 {
8392   unformat_input_t *i = vam->input;
8393   vl_api_control_ping_t *mp_ping;
8394   vl_api_dhcp_proxy_dump_t *mp;
8395   u8 is_ipv6 = 0;
8396   int ret;
8397
8398   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8399     {
8400       if (unformat (i, "ipv6"))
8401         is_ipv6 = 1;
8402       else
8403         {
8404           clib_warning ("parse error '%U'", format_unformat_error, i);
8405           return -99;
8406         }
8407     }
8408
8409   M (DHCP_PROXY_DUMP, mp);
8410
8411   mp->is_ip6 = is_ipv6;
8412   S (mp);
8413
8414   /* Use a control ping for synchronization */
8415   M (CONTROL_PING, mp_ping);
8416   S (mp_ping);
8417
8418   W (ret);
8419   return ret;
8420 }
8421
8422 static int
8423 api_dhcp_proxy_set_vss (vat_main_t * vam)
8424 {
8425   unformat_input_t *i = vam->input;
8426   vl_api_dhcp_proxy_set_vss_t *mp;
8427   u8 is_ipv6 = 0;
8428   u8 is_add = 1;
8429   u32 tbl_id;
8430   u8 tbl_id_set = 0;
8431   u32 oui;
8432   u8 oui_set = 0;
8433   u32 fib_id;
8434   u8 fib_id_set = 0;
8435   int ret;
8436
8437   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8438     {
8439       if (unformat (i, "tbl_id %d", &tbl_id))
8440         tbl_id_set = 1;
8441       if (unformat (i, "fib_id %d", &fib_id))
8442         fib_id_set = 1;
8443       if (unformat (i, "oui %d", &oui))
8444         oui_set = 1;
8445       else if (unformat (i, "ipv6"))
8446         is_ipv6 = 1;
8447       else if (unformat (i, "del"))
8448         is_add = 0;
8449       else
8450         {
8451           clib_warning ("parse error '%U'", format_unformat_error, i);
8452           return -99;
8453         }
8454     }
8455
8456   if (tbl_id_set == 0)
8457     {
8458       errmsg ("missing tbl id");
8459       return -99;
8460     }
8461
8462   if (fib_id_set == 0)
8463     {
8464       errmsg ("missing fib id");
8465       return -99;
8466     }
8467   if (oui_set == 0)
8468     {
8469       errmsg ("missing oui");
8470       return -99;
8471     }
8472
8473   M (DHCP_PROXY_SET_VSS, mp);
8474   mp->tbl_id = ntohl (tbl_id);
8475   mp->fib_id = ntohl (fib_id);
8476   mp->oui = ntohl (oui);
8477   mp->is_ipv6 = is_ipv6;
8478   mp->is_add = is_add;
8479
8480   S (mp);
8481   W (ret);
8482   return ret;
8483 }
8484
8485 static int
8486 api_dhcp_client_config (vat_main_t * vam)
8487 {
8488   unformat_input_t *i = vam->input;
8489   vl_api_dhcp_client_config_t *mp;
8490   u32 sw_if_index;
8491   u8 sw_if_index_set = 0;
8492   u8 is_add = 1;
8493   u8 *hostname = 0;
8494   u8 disable_event = 0;
8495   int ret;
8496
8497   /* Parse args required to build the message */
8498   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8499     {
8500       if (unformat (i, "del"))
8501         is_add = 0;
8502       else
8503         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8504         sw_if_index_set = 1;
8505       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8506         sw_if_index_set = 1;
8507       else if (unformat (i, "hostname %s", &hostname))
8508         ;
8509       else if (unformat (i, "disable_event"))
8510         disable_event = 1;
8511       else
8512         break;
8513     }
8514
8515   if (sw_if_index_set == 0)
8516     {
8517       errmsg ("missing interface name or sw_if_index");
8518       return -99;
8519     }
8520
8521   if (vec_len (hostname) > 63)
8522     {
8523       errmsg ("hostname too long");
8524     }
8525   vec_add1 (hostname, 0);
8526
8527   /* Construct the API message */
8528   M (DHCP_CLIENT_CONFIG, mp);
8529
8530   mp->sw_if_index = htonl (sw_if_index);
8531   clib_memcpy (mp->hostname, hostname, vec_len (hostname));
8532   vec_free (hostname);
8533   mp->is_add = is_add;
8534   mp->want_dhcp_event = disable_event ? 0 : 1;
8535   mp->pid = htonl (getpid ());
8536
8537   /* send it... */
8538   S (mp);
8539
8540   /* Wait for a reply, return good/bad news  */
8541   W (ret);
8542   return ret;
8543 }
8544
8545 static int
8546 api_set_ip_flow_hash (vat_main_t * vam)
8547 {
8548   unformat_input_t *i = vam->input;
8549   vl_api_set_ip_flow_hash_t *mp;
8550   u32 vrf_id = 0;
8551   u8 is_ipv6 = 0;
8552   u8 vrf_id_set = 0;
8553   u8 src = 0;
8554   u8 dst = 0;
8555   u8 sport = 0;
8556   u8 dport = 0;
8557   u8 proto = 0;
8558   u8 reverse = 0;
8559   int ret;
8560
8561   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8562     {
8563       if (unformat (i, "vrf %d", &vrf_id))
8564         vrf_id_set = 1;
8565       else if (unformat (i, "ipv6"))
8566         is_ipv6 = 1;
8567       else if (unformat (i, "src"))
8568         src = 1;
8569       else if (unformat (i, "dst"))
8570         dst = 1;
8571       else if (unformat (i, "sport"))
8572         sport = 1;
8573       else if (unformat (i, "dport"))
8574         dport = 1;
8575       else if (unformat (i, "proto"))
8576         proto = 1;
8577       else if (unformat (i, "reverse"))
8578         reverse = 1;
8579
8580       else
8581         {
8582           clib_warning ("parse error '%U'", format_unformat_error, i);
8583           return -99;
8584         }
8585     }
8586
8587   if (vrf_id_set == 0)
8588     {
8589       errmsg ("missing vrf id");
8590       return -99;
8591     }
8592
8593   M (SET_IP_FLOW_HASH, mp);
8594   mp->src = src;
8595   mp->dst = dst;
8596   mp->sport = sport;
8597   mp->dport = dport;
8598   mp->proto = proto;
8599   mp->reverse = reverse;
8600   mp->vrf_id = ntohl (vrf_id);
8601   mp->is_ipv6 = is_ipv6;
8602
8603   S (mp);
8604   W (ret);
8605   return ret;
8606 }
8607
8608 static int
8609 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
8610 {
8611   unformat_input_t *i = vam->input;
8612   vl_api_sw_interface_ip6_enable_disable_t *mp;
8613   u32 sw_if_index;
8614   u8 sw_if_index_set = 0;
8615   u8 enable = 0;
8616   int ret;
8617
8618   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8619     {
8620       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8621         sw_if_index_set = 1;
8622       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8623         sw_if_index_set = 1;
8624       else if (unformat (i, "enable"))
8625         enable = 1;
8626       else if (unformat (i, "disable"))
8627         enable = 0;
8628       else
8629         {
8630           clib_warning ("parse error '%U'", format_unformat_error, i);
8631           return -99;
8632         }
8633     }
8634
8635   if (sw_if_index_set == 0)
8636     {
8637       errmsg ("missing interface name or sw_if_index");
8638       return -99;
8639     }
8640
8641   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
8642
8643   mp->sw_if_index = ntohl (sw_if_index);
8644   mp->enable = enable;
8645
8646   S (mp);
8647   W (ret);
8648   return ret;
8649 }
8650
8651 static int
8652 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
8653 {
8654   unformat_input_t *i = vam->input;
8655   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
8656   u32 sw_if_index;
8657   u8 sw_if_index_set = 0;
8658   u8 v6_address_set = 0;
8659   ip6_address_t v6address;
8660   int ret;
8661
8662   /* Parse args required to build the message */
8663   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8664     {
8665       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8666         sw_if_index_set = 1;
8667       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8668         sw_if_index_set = 1;
8669       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
8670         v6_address_set = 1;
8671       else
8672         break;
8673     }
8674
8675   if (sw_if_index_set == 0)
8676     {
8677       errmsg ("missing interface name or sw_if_index");
8678       return -99;
8679     }
8680   if (!v6_address_set)
8681     {
8682       errmsg ("no address set");
8683       return -99;
8684     }
8685
8686   /* Construct the API message */
8687   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS, mp);
8688
8689   mp->sw_if_index = ntohl (sw_if_index);
8690   clib_memcpy (mp->address, &v6address, sizeof (v6address));
8691
8692   /* send it... */
8693   S (mp);
8694
8695   /* Wait for a reply, return good/bad news  */
8696   W (ret);
8697   return ret;
8698 }
8699
8700 static int
8701 api_ip6nd_proxy_add_del (vat_main_t * vam)
8702 {
8703   unformat_input_t *i = vam->input;
8704   vl_api_ip6nd_proxy_add_del_t *mp;
8705   u32 sw_if_index = ~0;
8706   u8 v6_address_set = 0;
8707   ip6_address_t v6address;
8708   u8 is_del = 0;
8709   int ret;
8710
8711   /* Parse args required to build the message */
8712   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8713     {
8714       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8715         ;
8716       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8717         ;
8718       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
8719         v6_address_set = 1;
8720       if (unformat (i, "del"))
8721         is_del = 1;
8722       else
8723         {
8724           clib_warning ("parse error '%U'", format_unformat_error, i);
8725           return -99;
8726         }
8727     }
8728
8729   if (sw_if_index == ~0)
8730     {
8731       errmsg ("missing interface name or sw_if_index");
8732       return -99;
8733     }
8734   if (!v6_address_set)
8735     {
8736       errmsg ("no address set");
8737       return -99;
8738     }
8739
8740   /* Construct the API message */
8741   M (IP6ND_PROXY_ADD_DEL, mp);
8742
8743   mp->is_del = is_del;
8744   mp->sw_if_index = ntohl (sw_if_index);
8745   clib_memcpy (mp->address, &v6address, sizeof (v6address));
8746
8747   /* send it... */
8748   S (mp);
8749
8750   /* Wait for a reply, return good/bad news  */
8751   W (ret);
8752   return ret;
8753 }
8754
8755 static int
8756 api_ip6nd_proxy_dump (vat_main_t * vam)
8757 {
8758   vl_api_ip6nd_proxy_dump_t *mp;
8759   vl_api_control_ping_t *mp_ping;
8760   int ret;
8761
8762   M (IP6ND_PROXY_DUMP, mp);
8763
8764   S (mp);
8765
8766   /* Use a control ping for synchronization */
8767   M (CONTROL_PING, mp_ping);
8768   S (mp_ping);
8769
8770   W (ret);
8771   return ret;
8772 }
8773
8774 static void vl_api_ip6nd_proxy_details_t_handler
8775   (vl_api_ip6nd_proxy_details_t * mp)
8776 {
8777   vat_main_t *vam = &vat_main;
8778
8779   print (vam->ofp, "host %U sw_if_index %d",
8780          format_ip6_address, mp->address, ntohl (mp->sw_if_index));
8781 }
8782
8783 static void vl_api_ip6nd_proxy_details_t_handler_json
8784   (vl_api_ip6nd_proxy_details_t * mp)
8785 {
8786   vat_main_t *vam = &vat_main;
8787   struct in6_addr ip6;
8788   vat_json_node_t *node = NULL;
8789
8790   if (VAT_JSON_ARRAY != vam->json_tree.type)
8791     {
8792       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
8793       vat_json_init_array (&vam->json_tree);
8794     }
8795   node = vat_json_array_add (&vam->json_tree);
8796
8797   vat_json_init_object (node);
8798   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
8799
8800   clib_memcpy (&ip6, mp->address, sizeof (ip6));
8801   vat_json_object_add_ip6 (node, "host", ip6);
8802 }
8803
8804 static int
8805 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
8806 {
8807   unformat_input_t *i = vam->input;
8808   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
8809   u32 sw_if_index;
8810   u8 sw_if_index_set = 0;
8811   u32 address_length = 0;
8812   u8 v6_address_set = 0;
8813   ip6_address_t v6address;
8814   u8 use_default = 0;
8815   u8 no_advertise = 0;
8816   u8 off_link = 0;
8817   u8 no_autoconfig = 0;
8818   u8 no_onlink = 0;
8819   u8 is_no = 0;
8820   u32 val_lifetime = 0;
8821   u32 pref_lifetime = 0;
8822   int ret;
8823
8824   /* Parse args required to build the message */
8825   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8826     {
8827       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8828         sw_if_index_set = 1;
8829       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8830         sw_if_index_set = 1;
8831       else if (unformat (i, "%U/%d",
8832                          unformat_ip6_address, &v6address, &address_length))
8833         v6_address_set = 1;
8834       else if (unformat (i, "val_life %d", &val_lifetime))
8835         ;
8836       else if (unformat (i, "pref_life %d", &pref_lifetime))
8837         ;
8838       else if (unformat (i, "def"))
8839         use_default = 1;
8840       else if (unformat (i, "noadv"))
8841         no_advertise = 1;
8842       else if (unformat (i, "offl"))
8843         off_link = 1;
8844       else if (unformat (i, "noauto"))
8845         no_autoconfig = 1;
8846       else if (unformat (i, "nolink"))
8847         no_onlink = 1;
8848       else if (unformat (i, "isno"))
8849         is_no = 1;
8850       else
8851         {
8852           clib_warning ("parse error '%U'", format_unformat_error, i);
8853           return -99;
8854         }
8855     }
8856
8857   if (sw_if_index_set == 0)
8858     {
8859       errmsg ("missing interface name or sw_if_index");
8860       return -99;
8861     }
8862   if (!v6_address_set)
8863     {
8864       errmsg ("no address set");
8865       return -99;
8866     }
8867
8868   /* Construct the API message */
8869   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
8870
8871   mp->sw_if_index = ntohl (sw_if_index);
8872   clib_memcpy (mp->address, &v6address, sizeof (v6address));
8873   mp->address_length = address_length;
8874   mp->use_default = use_default;
8875   mp->no_advertise = no_advertise;
8876   mp->off_link = off_link;
8877   mp->no_autoconfig = no_autoconfig;
8878   mp->no_onlink = no_onlink;
8879   mp->is_no = is_no;
8880   mp->val_lifetime = ntohl (val_lifetime);
8881   mp->pref_lifetime = ntohl (pref_lifetime);
8882
8883   /* send it... */
8884   S (mp);
8885
8886   /* Wait for a reply, return good/bad news  */
8887   W (ret);
8888   return ret;
8889 }
8890
8891 static int
8892 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
8893 {
8894   unformat_input_t *i = vam->input;
8895   vl_api_sw_interface_ip6nd_ra_config_t *mp;
8896   u32 sw_if_index;
8897   u8 sw_if_index_set = 0;
8898   u8 suppress = 0;
8899   u8 managed = 0;
8900   u8 other = 0;
8901   u8 ll_option = 0;
8902   u8 send_unicast = 0;
8903   u8 cease = 0;
8904   u8 is_no = 0;
8905   u8 default_router = 0;
8906   u32 max_interval = 0;
8907   u32 min_interval = 0;
8908   u32 lifetime = 0;
8909   u32 initial_count = 0;
8910   u32 initial_interval = 0;
8911   int ret;
8912
8913
8914   /* Parse args required to build the message */
8915   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8916     {
8917       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8918         sw_if_index_set = 1;
8919       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8920         sw_if_index_set = 1;
8921       else if (unformat (i, "maxint %d", &max_interval))
8922         ;
8923       else if (unformat (i, "minint %d", &min_interval))
8924         ;
8925       else if (unformat (i, "life %d", &lifetime))
8926         ;
8927       else if (unformat (i, "count %d", &initial_count))
8928         ;
8929       else if (unformat (i, "interval %d", &initial_interval))
8930         ;
8931       else if (unformat (i, "suppress") || unformat (i, "surpress"))
8932         suppress = 1;
8933       else if (unformat (i, "managed"))
8934         managed = 1;
8935       else if (unformat (i, "other"))
8936         other = 1;
8937       else if (unformat (i, "ll"))
8938         ll_option = 1;
8939       else if (unformat (i, "send"))
8940         send_unicast = 1;
8941       else if (unformat (i, "cease"))
8942         cease = 1;
8943       else if (unformat (i, "isno"))
8944         is_no = 1;
8945       else if (unformat (i, "def"))
8946         default_router = 1;
8947       else
8948         {
8949           clib_warning ("parse error '%U'", format_unformat_error, i);
8950           return -99;
8951         }
8952     }
8953
8954   if (sw_if_index_set == 0)
8955     {
8956       errmsg ("missing interface name or sw_if_index");
8957       return -99;
8958     }
8959
8960   /* Construct the API message */
8961   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
8962
8963   mp->sw_if_index = ntohl (sw_if_index);
8964   mp->max_interval = ntohl (max_interval);
8965   mp->min_interval = ntohl (min_interval);
8966   mp->lifetime = ntohl (lifetime);
8967   mp->initial_count = ntohl (initial_count);
8968   mp->initial_interval = ntohl (initial_interval);
8969   mp->suppress = suppress;
8970   mp->managed = managed;
8971   mp->other = other;
8972   mp->ll_option = ll_option;
8973   mp->send_unicast = send_unicast;
8974   mp->cease = cease;
8975   mp->is_no = is_no;
8976   mp->default_router = default_router;
8977
8978   /* send it... */
8979   S (mp);
8980
8981   /* Wait for a reply, return good/bad news  */
8982   W (ret);
8983   return ret;
8984 }
8985
8986 static int
8987 api_set_arp_neighbor_limit (vat_main_t * vam)
8988 {
8989   unformat_input_t *i = vam->input;
8990   vl_api_set_arp_neighbor_limit_t *mp;
8991   u32 arp_nbr_limit;
8992   u8 limit_set = 0;
8993   u8 is_ipv6 = 0;
8994   int ret;
8995
8996   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8997     {
8998       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
8999         limit_set = 1;
9000       else if (unformat (i, "ipv6"))
9001         is_ipv6 = 1;
9002       else
9003         {
9004           clib_warning ("parse error '%U'", format_unformat_error, i);
9005           return -99;
9006         }
9007     }
9008
9009   if (limit_set == 0)
9010     {
9011       errmsg ("missing limit value");
9012       return -99;
9013     }
9014
9015   M (SET_ARP_NEIGHBOR_LIMIT, mp);
9016
9017   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
9018   mp->is_ipv6 = is_ipv6;
9019
9020   S (mp);
9021   W (ret);
9022   return ret;
9023 }
9024
9025 static int
9026 api_l2_patch_add_del (vat_main_t * vam)
9027 {
9028   unformat_input_t *i = vam->input;
9029   vl_api_l2_patch_add_del_t *mp;
9030   u32 rx_sw_if_index;
9031   u8 rx_sw_if_index_set = 0;
9032   u32 tx_sw_if_index;
9033   u8 tx_sw_if_index_set = 0;
9034   u8 is_add = 1;
9035   int ret;
9036
9037   /* Parse args required to build the message */
9038   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9039     {
9040       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
9041         rx_sw_if_index_set = 1;
9042       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
9043         tx_sw_if_index_set = 1;
9044       else if (unformat (i, "rx"))
9045         {
9046           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9047             {
9048               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
9049                             &rx_sw_if_index))
9050                 rx_sw_if_index_set = 1;
9051             }
9052           else
9053             break;
9054         }
9055       else if (unformat (i, "tx"))
9056         {
9057           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9058             {
9059               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
9060                             &tx_sw_if_index))
9061                 tx_sw_if_index_set = 1;
9062             }
9063           else
9064             break;
9065         }
9066       else if (unformat (i, "del"))
9067         is_add = 0;
9068       else
9069         break;
9070     }
9071
9072   if (rx_sw_if_index_set == 0)
9073     {
9074       errmsg ("missing rx interface name or rx_sw_if_index");
9075       return -99;
9076     }
9077
9078   if (tx_sw_if_index_set == 0)
9079     {
9080       errmsg ("missing tx interface name or tx_sw_if_index");
9081       return -99;
9082     }
9083
9084   M (L2_PATCH_ADD_DEL, mp);
9085
9086   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
9087   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
9088   mp->is_add = is_add;
9089
9090   S (mp);
9091   W (ret);
9092   return ret;
9093 }
9094
9095 u8 is_del;
9096 u8 localsid_addr[16];
9097 u8 end_psp;
9098 u8 behavior;
9099 u32 sw_if_index;
9100 u32 vlan_index;
9101 u32 fib_table;
9102 u8 nh_addr[16];
9103
9104 static int
9105 api_sr_localsid_add_del (vat_main_t * vam)
9106 {
9107   unformat_input_t *i = vam->input;
9108   vl_api_sr_localsid_add_del_t *mp;
9109
9110   u8 is_del;
9111   ip6_address_t localsid;
9112   u8 end_psp = 0;
9113   u8 behavior = ~0;
9114   u32 sw_if_index;
9115   u32 fib_table = ~(u32) 0;
9116   ip6_address_t next_hop;
9117
9118   bool nexthop_set = 0;
9119
9120   int ret;
9121
9122   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9123     {
9124       if (unformat (i, "del"))
9125         is_del = 1;
9126       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
9127       else if (unformat (i, "next-hop %U", unformat_ip6_address, &next_hop))
9128         nexthop_set = 1;
9129       else if (unformat (i, "behavior %u", &behavior));
9130       else if (unformat (i, "sw_if_index %u", &sw_if_index));
9131       else if (unformat (i, "fib-table %u", &fib_table));
9132       else if (unformat (i, "end.psp %u", &behavior));
9133       else
9134         break;
9135     }
9136
9137   M (SR_LOCALSID_ADD_DEL, mp);
9138
9139   clib_memcpy (mp->localsid_addr, &localsid, sizeof (mp->localsid_addr));
9140   if (nexthop_set)
9141     clib_memcpy (mp->nh_addr, &next_hop, sizeof (mp->nh_addr));
9142   mp->behavior = behavior;
9143   mp->sw_if_index = ntohl (sw_if_index);
9144   mp->fib_table = ntohl (fib_table);
9145   mp->end_psp = end_psp;
9146   mp->is_del = is_del;
9147
9148   S (mp);
9149   W (ret);
9150   return ret;
9151 }
9152
9153 static int
9154 api_ioam_enable (vat_main_t * vam)
9155 {
9156   unformat_input_t *input = vam->input;
9157   vl_api_ioam_enable_t *mp;
9158   u32 id = 0;
9159   int has_trace_option = 0;
9160   int has_pot_option = 0;
9161   int has_seqno_option = 0;
9162   int has_analyse_option = 0;
9163   int ret;
9164
9165   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9166     {
9167       if (unformat (input, "trace"))
9168         has_trace_option = 1;
9169       else if (unformat (input, "pot"))
9170         has_pot_option = 1;
9171       else if (unformat (input, "seqno"))
9172         has_seqno_option = 1;
9173       else if (unformat (input, "analyse"))
9174         has_analyse_option = 1;
9175       else
9176         break;
9177     }
9178   M (IOAM_ENABLE, mp);
9179   mp->id = htons (id);
9180   mp->seqno = has_seqno_option;
9181   mp->analyse = has_analyse_option;
9182   mp->pot_enable = has_pot_option;
9183   mp->trace_enable = has_trace_option;
9184
9185   S (mp);
9186   W (ret);
9187   return ret;
9188 }
9189
9190
9191 static int
9192 api_ioam_disable (vat_main_t * vam)
9193 {
9194   vl_api_ioam_disable_t *mp;
9195   int ret;
9196
9197   M (IOAM_DISABLE, mp);
9198   S (mp);
9199   W (ret);
9200   return ret;
9201 }
9202
9203 #define foreach_tcp_proto_field                 \
9204 _(src_port)                                     \
9205 _(dst_port)
9206
9207 #define foreach_udp_proto_field                 \
9208 _(src_port)                                     \
9209 _(dst_port)
9210
9211 #define foreach_ip4_proto_field                 \
9212 _(src_address)                                  \
9213 _(dst_address)                                  \
9214 _(tos)                                          \
9215 _(length)                                       \
9216 _(fragment_id)                                  \
9217 _(ttl)                                          \
9218 _(protocol)                                     \
9219 _(checksum)
9220
9221 typedef struct
9222 {
9223   u16 src_port, dst_port;
9224 } tcpudp_header_t;
9225
9226 #if VPP_API_TEST_BUILTIN == 0
9227 uword
9228 unformat_tcp_mask (unformat_input_t * input, va_list * args)
9229 {
9230   u8 **maskp = va_arg (*args, u8 **);
9231   u8 *mask = 0;
9232   u8 found_something = 0;
9233   tcp_header_t *tcp;
9234
9235 #define _(a) u8 a=0;
9236   foreach_tcp_proto_field;
9237 #undef _
9238
9239   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9240     {
9241       if (0);
9242 #define _(a) else if (unformat (input, #a)) a=1;
9243       foreach_tcp_proto_field
9244 #undef _
9245         else
9246         break;
9247     }
9248
9249 #define _(a) found_something += a;
9250   foreach_tcp_proto_field;
9251 #undef _
9252
9253   if (found_something == 0)
9254     return 0;
9255
9256   vec_validate (mask, sizeof (*tcp) - 1);
9257
9258   tcp = (tcp_header_t *) mask;
9259
9260 #define _(a) if (a) memset (&tcp->a, 0xff, sizeof (tcp->a));
9261   foreach_tcp_proto_field;
9262 #undef _
9263
9264   *maskp = mask;
9265   return 1;
9266 }
9267
9268 uword
9269 unformat_udp_mask (unformat_input_t * input, va_list * args)
9270 {
9271   u8 **maskp = va_arg (*args, u8 **);
9272   u8 *mask = 0;
9273   u8 found_something = 0;
9274   udp_header_t *udp;
9275
9276 #define _(a) u8 a=0;
9277   foreach_udp_proto_field;
9278 #undef _
9279
9280   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9281     {
9282       if (0);
9283 #define _(a) else if (unformat (input, #a)) a=1;
9284       foreach_udp_proto_field
9285 #undef _
9286         else
9287         break;
9288     }
9289
9290 #define _(a) found_something += a;
9291   foreach_udp_proto_field;
9292 #undef _
9293
9294   if (found_something == 0)
9295     return 0;
9296
9297   vec_validate (mask, sizeof (*udp) - 1);
9298
9299   udp = (udp_header_t *) mask;
9300
9301 #define _(a) if (a) memset (&udp->a, 0xff, sizeof (udp->a));
9302   foreach_udp_proto_field;
9303 #undef _
9304
9305   *maskp = mask;
9306   return 1;
9307 }
9308
9309 uword
9310 unformat_l4_mask (unformat_input_t * input, va_list * args)
9311 {
9312   u8 **maskp = va_arg (*args, u8 **);
9313   u16 src_port = 0, dst_port = 0;
9314   tcpudp_header_t *tcpudp;
9315
9316   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9317     {
9318       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
9319         return 1;
9320       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
9321         return 1;
9322       else if (unformat (input, "src_port"))
9323         src_port = 0xFFFF;
9324       else if (unformat (input, "dst_port"))
9325         dst_port = 0xFFFF;
9326       else
9327         return 0;
9328     }
9329
9330   if (!src_port && !dst_port)
9331     return 0;
9332
9333   u8 *mask = 0;
9334   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
9335
9336   tcpudp = (tcpudp_header_t *) mask;
9337   tcpudp->src_port = src_port;
9338   tcpudp->dst_port = dst_port;
9339
9340   *maskp = mask;
9341
9342   return 1;
9343 }
9344
9345 uword
9346 unformat_ip4_mask (unformat_input_t * input, va_list * args)
9347 {
9348   u8 **maskp = va_arg (*args, u8 **);
9349   u8 *mask = 0;
9350   u8 found_something = 0;
9351   ip4_header_t *ip;
9352
9353 #define _(a) u8 a=0;
9354   foreach_ip4_proto_field;
9355 #undef _
9356   u8 version = 0;
9357   u8 hdr_length = 0;
9358
9359
9360   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9361     {
9362       if (unformat (input, "version"))
9363         version = 1;
9364       else if (unformat (input, "hdr_length"))
9365         hdr_length = 1;
9366       else if (unformat (input, "src"))
9367         src_address = 1;
9368       else if (unformat (input, "dst"))
9369         dst_address = 1;
9370       else if (unformat (input, "proto"))
9371         protocol = 1;
9372
9373 #define _(a) else if (unformat (input, #a)) a=1;
9374       foreach_ip4_proto_field
9375 #undef _
9376         else
9377         break;
9378     }
9379
9380 #define _(a) found_something += a;
9381   foreach_ip4_proto_field;
9382 #undef _
9383
9384   if (found_something == 0)
9385     return 0;
9386
9387   vec_validate (mask, sizeof (*ip) - 1);
9388
9389   ip = (ip4_header_t *) mask;
9390
9391 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
9392   foreach_ip4_proto_field;
9393 #undef _
9394
9395   ip->ip_version_and_header_length = 0;
9396
9397   if (version)
9398     ip->ip_version_and_header_length |= 0xF0;
9399
9400   if (hdr_length)
9401     ip->ip_version_and_header_length |= 0x0F;
9402
9403   *maskp = mask;
9404   return 1;
9405 }
9406
9407 #define foreach_ip6_proto_field                 \
9408 _(src_address)                                  \
9409 _(dst_address)                                  \
9410 _(payload_length)                               \
9411 _(hop_limit)                                    \
9412 _(protocol)
9413
9414 uword
9415 unformat_ip6_mask (unformat_input_t * input, va_list * args)
9416 {
9417   u8 **maskp = va_arg (*args, u8 **);
9418   u8 *mask = 0;
9419   u8 found_something = 0;
9420   ip6_header_t *ip;
9421   u32 ip_version_traffic_class_and_flow_label;
9422
9423 #define _(a) u8 a=0;
9424   foreach_ip6_proto_field;
9425 #undef _
9426   u8 version = 0;
9427   u8 traffic_class = 0;
9428   u8 flow_label = 0;
9429
9430   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9431     {
9432       if (unformat (input, "version"))
9433         version = 1;
9434       else if (unformat (input, "traffic-class"))
9435         traffic_class = 1;
9436       else if (unformat (input, "flow-label"))
9437         flow_label = 1;
9438       else if (unformat (input, "src"))
9439         src_address = 1;
9440       else if (unformat (input, "dst"))
9441         dst_address = 1;
9442       else if (unformat (input, "proto"))
9443         protocol = 1;
9444
9445 #define _(a) else if (unformat (input, #a)) a=1;
9446       foreach_ip6_proto_field
9447 #undef _
9448         else
9449         break;
9450     }
9451
9452 #define _(a) found_something += a;
9453   foreach_ip6_proto_field;
9454 #undef _
9455
9456   if (found_something == 0)
9457     return 0;
9458
9459   vec_validate (mask, sizeof (*ip) - 1);
9460
9461   ip = (ip6_header_t *) mask;
9462
9463 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
9464   foreach_ip6_proto_field;
9465 #undef _
9466
9467   ip_version_traffic_class_and_flow_label = 0;
9468
9469   if (version)
9470     ip_version_traffic_class_and_flow_label |= 0xF0000000;
9471
9472   if (traffic_class)
9473     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
9474
9475   if (flow_label)
9476     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
9477
9478   ip->ip_version_traffic_class_and_flow_label =
9479     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
9480
9481   *maskp = mask;
9482   return 1;
9483 }
9484
9485 uword
9486 unformat_l3_mask (unformat_input_t * input, va_list * args)
9487 {
9488   u8 **maskp = va_arg (*args, u8 **);
9489
9490   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9491     {
9492       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
9493         return 1;
9494       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
9495         return 1;
9496       else
9497         break;
9498     }
9499   return 0;
9500 }
9501
9502 uword
9503 unformat_l2_mask (unformat_input_t * input, va_list * args)
9504 {
9505   u8 **maskp = va_arg (*args, u8 **);
9506   u8 *mask = 0;
9507   u8 src = 0;
9508   u8 dst = 0;
9509   u8 proto = 0;
9510   u8 tag1 = 0;
9511   u8 tag2 = 0;
9512   u8 ignore_tag1 = 0;
9513   u8 ignore_tag2 = 0;
9514   u8 cos1 = 0;
9515   u8 cos2 = 0;
9516   u8 dot1q = 0;
9517   u8 dot1ad = 0;
9518   int len = 14;
9519
9520   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9521     {
9522       if (unformat (input, "src"))
9523         src = 1;
9524       else if (unformat (input, "dst"))
9525         dst = 1;
9526       else if (unformat (input, "proto"))
9527         proto = 1;
9528       else if (unformat (input, "tag1"))
9529         tag1 = 1;
9530       else if (unformat (input, "tag2"))
9531         tag2 = 1;
9532       else if (unformat (input, "ignore-tag1"))
9533         ignore_tag1 = 1;
9534       else if (unformat (input, "ignore-tag2"))
9535         ignore_tag2 = 1;
9536       else if (unformat (input, "cos1"))
9537         cos1 = 1;
9538       else if (unformat (input, "cos2"))
9539         cos2 = 1;
9540       else if (unformat (input, "dot1q"))
9541         dot1q = 1;
9542       else if (unformat (input, "dot1ad"))
9543         dot1ad = 1;
9544       else
9545         break;
9546     }
9547   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
9548        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
9549     return 0;
9550
9551   if (tag1 || ignore_tag1 || cos1 || dot1q)
9552     len = 18;
9553   if (tag2 || ignore_tag2 || cos2 || dot1ad)
9554     len = 22;
9555
9556   vec_validate (mask, len - 1);
9557
9558   if (dst)
9559     memset (mask, 0xff, 6);
9560
9561   if (src)
9562     memset (mask + 6, 0xff, 6);
9563
9564   if (tag2 || dot1ad)
9565     {
9566       /* inner vlan tag */
9567       if (tag2)
9568         {
9569           mask[19] = 0xff;
9570           mask[18] = 0x0f;
9571         }
9572       if (cos2)
9573         mask[18] |= 0xe0;
9574       if (proto)
9575         mask[21] = mask[20] = 0xff;
9576       if (tag1)
9577         {
9578           mask[15] = 0xff;
9579           mask[14] = 0x0f;
9580         }
9581       if (cos1)
9582         mask[14] |= 0xe0;
9583       *maskp = mask;
9584       return 1;
9585     }
9586   if (tag1 | dot1q)
9587     {
9588       if (tag1)
9589         {
9590           mask[15] = 0xff;
9591           mask[14] = 0x0f;
9592         }
9593       if (cos1)
9594         mask[14] |= 0xe0;
9595       if (proto)
9596         mask[16] = mask[17] = 0xff;
9597
9598       *maskp = mask;
9599       return 1;
9600     }
9601   if (cos2)
9602     mask[18] |= 0xe0;
9603   if (cos1)
9604     mask[14] |= 0xe0;
9605   if (proto)
9606     mask[12] = mask[13] = 0xff;
9607
9608   *maskp = mask;
9609   return 1;
9610 }
9611
9612 uword
9613 unformat_classify_mask (unformat_input_t * input, va_list * args)
9614 {
9615   u8 **maskp = va_arg (*args, u8 **);
9616   u32 *skipp = va_arg (*args, u32 *);
9617   u32 *matchp = va_arg (*args, u32 *);
9618   u32 match;
9619   u8 *mask = 0;
9620   u8 *l2 = 0;
9621   u8 *l3 = 0;
9622   u8 *l4 = 0;
9623   int i;
9624
9625   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9626     {
9627       if (unformat (input, "hex %U", unformat_hex_string, &mask))
9628         ;
9629       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
9630         ;
9631       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
9632         ;
9633       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
9634         ;
9635       else
9636         break;
9637     }
9638
9639   if (l4 && !l3)
9640     {
9641       vec_free (mask);
9642       vec_free (l2);
9643       vec_free (l4);
9644       return 0;
9645     }
9646
9647   if (mask || l2 || l3 || l4)
9648     {
9649       if (l2 || l3 || l4)
9650         {
9651           /* "With a free Ethernet header in every package" */
9652           if (l2 == 0)
9653             vec_validate (l2, 13);
9654           mask = l2;
9655           if (vec_len (l3))
9656             {
9657               vec_append (mask, l3);
9658               vec_free (l3);
9659             }
9660           if (vec_len (l4))
9661             {
9662               vec_append (mask, l4);
9663               vec_free (l4);
9664             }
9665         }
9666
9667       /* Scan forward looking for the first significant mask octet */
9668       for (i = 0; i < vec_len (mask); i++)
9669         if (mask[i])
9670           break;
9671
9672       /* compute (skip, match) params */
9673       *skipp = i / sizeof (u32x4);
9674       vec_delete (mask, *skipp * sizeof (u32x4), 0);
9675
9676       /* Pad mask to an even multiple of the vector size */
9677       while (vec_len (mask) % sizeof (u32x4))
9678         vec_add1 (mask, 0);
9679
9680       match = vec_len (mask) / sizeof (u32x4);
9681
9682       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
9683         {
9684           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
9685           if (*tmp || *(tmp + 1))
9686             break;
9687           match--;
9688         }
9689       if (match == 0)
9690         clib_warning ("BUG: match 0");
9691
9692       _vec_len (mask) = match * sizeof (u32x4);
9693
9694       *matchp = match;
9695       *maskp = mask;
9696
9697       return 1;
9698     }
9699
9700   return 0;
9701 }
9702 #endif /* VPP_API_TEST_BUILTIN */
9703
9704 #define foreach_l2_next                         \
9705 _(drop, DROP)                                   \
9706 _(ethernet, ETHERNET_INPUT)                     \
9707 _(ip4, IP4_INPUT)                               \
9708 _(ip6, IP6_INPUT)
9709
9710 uword
9711 unformat_l2_next_index (unformat_input_t * input, va_list * args)
9712 {
9713   u32 *miss_next_indexp = va_arg (*args, u32 *);
9714   u32 next_index = 0;
9715   u32 tmp;
9716
9717 #define _(n,N) \
9718   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
9719   foreach_l2_next;
9720 #undef _
9721
9722   if (unformat (input, "%d", &tmp))
9723     {
9724       next_index = tmp;
9725       goto out;
9726     }
9727
9728   return 0;
9729
9730 out:
9731   *miss_next_indexp = next_index;
9732   return 1;
9733 }
9734
9735 #define foreach_ip_next                         \
9736 _(drop, DROP)                                   \
9737 _(local, LOCAL)                                 \
9738 _(rewrite, REWRITE)
9739
9740 uword
9741 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
9742 {
9743   u32 *miss_next_indexp = va_arg (*args, u32 *);
9744   u32 next_index = 0;
9745   u32 tmp;
9746
9747 #define _(n,N) \
9748   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
9749   foreach_ip_next;
9750 #undef _
9751
9752   if (unformat (input, "%d", &tmp))
9753     {
9754       next_index = tmp;
9755       goto out;
9756     }
9757
9758   return 0;
9759
9760 out:
9761   *miss_next_indexp = next_index;
9762   return 1;
9763 }
9764
9765 #define foreach_acl_next                        \
9766 _(deny, DENY)
9767
9768 uword
9769 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
9770 {
9771   u32 *miss_next_indexp = va_arg (*args, u32 *);
9772   u32 next_index = 0;
9773   u32 tmp;
9774
9775 #define _(n,N) \
9776   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
9777   foreach_acl_next;
9778 #undef _
9779
9780   if (unformat (input, "permit"))
9781     {
9782       next_index = ~0;
9783       goto out;
9784     }
9785   else if (unformat (input, "%d", &tmp))
9786     {
9787       next_index = tmp;
9788       goto out;
9789     }
9790
9791   return 0;
9792
9793 out:
9794   *miss_next_indexp = next_index;
9795   return 1;
9796 }
9797
9798 uword
9799 unformat_policer_precolor (unformat_input_t * input, va_list * args)
9800 {
9801   u32 *r = va_arg (*args, u32 *);
9802
9803   if (unformat (input, "conform-color"))
9804     *r = POLICE_CONFORM;
9805   else if (unformat (input, "exceed-color"))
9806     *r = POLICE_EXCEED;
9807   else
9808     return 0;
9809
9810   return 1;
9811 }
9812
9813 static int
9814 api_classify_add_del_table (vat_main_t * vam)
9815 {
9816   unformat_input_t *i = vam->input;
9817   vl_api_classify_add_del_table_t *mp;
9818
9819   u32 nbuckets = 2;
9820   u32 skip = ~0;
9821   u32 match = ~0;
9822   int is_add = 1;
9823   int del_chain = 0;
9824   u32 table_index = ~0;
9825   u32 next_table_index = ~0;
9826   u32 miss_next_index = ~0;
9827   u32 memory_size = 32 << 20;
9828   u8 *mask = 0;
9829   u32 current_data_flag = 0;
9830   int current_data_offset = 0;
9831   int ret;
9832
9833   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9834     {
9835       if (unformat (i, "del"))
9836         is_add = 0;
9837       else if (unformat (i, "del-chain"))
9838         {
9839           is_add = 0;
9840           del_chain = 1;
9841         }
9842       else if (unformat (i, "buckets %d", &nbuckets))
9843         ;
9844       else if (unformat (i, "memory_size %d", &memory_size))
9845         ;
9846       else if (unformat (i, "skip %d", &skip))
9847         ;
9848       else if (unformat (i, "match %d", &match))
9849         ;
9850       else if (unformat (i, "table %d", &table_index))
9851         ;
9852       else if (unformat (i, "mask %U", unformat_classify_mask,
9853                          &mask, &skip, &match))
9854         ;
9855       else if (unformat (i, "next-table %d", &next_table_index))
9856         ;
9857       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
9858                          &miss_next_index))
9859         ;
9860       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
9861                          &miss_next_index))
9862         ;
9863       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
9864                          &miss_next_index))
9865         ;
9866       else if (unformat (i, "current-data-flag %d", &current_data_flag))
9867         ;
9868       else if (unformat (i, "current-data-offset %d", &current_data_offset))
9869         ;
9870       else
9871         break;
9872     }
9873
9874   if (is_add && mask == 0)
9875     {
9876       errmsg ("Mask required");
9877       return -99;
9878     }
9879
9880   if (is_add && skip == ~0)
9881     {
9882       errmsg ("skip count required");
9883       return -99;
9884     }
9885
9886   if (is_add && match == ~0)
9887     {
9888       errmsg ("match count required");
9889       return -99;
9890     }
9891
9892   if (!is_add && table_index == ~0)
9893     {
9894       errmsg ("table index required for delete");
9895       return -99;
9896     }
9897
9898   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
9899
9900   mp->is_add = is_add;
9901   mp->del_chain = del_chain;
9902   mp->table_index = ntohl (table_index);
9903   mp->nbuckets = ntohl (nbuckets);
9904   mp->memory_size = ntohl (memory_size);
9905   mp->skip_n_vectors = ntohl (skip);
9906   mp->match_n_vectors = ntohl (match);
9907   mp->next_table_index = ntohl (next_table_index);
9908   mp->miss_next_index = ntohl (miss_next_index);
9909   mp->current_data_flag = ntohl (current_data_flag);
9910   mp->current_data_offset = ntohl (current_data_offset);
9911   clib_memcpy (mp->mask, mask, vec_len (mask));
9912
9913   vec_free (mask);
9914
9915   S (mp);
9916   W (ret);
9917   return ret;
9918 }
9919
9920 #if VPP_API_TEST_BUILTIN == 0
9921 uword
9922 unformat_l4_match (unformat_input_t * input, va_list * args)
9923 {
9924   u8 **matchp = va_arg (*args, u8 **);
9925
9926   u8 *proto_header = 0;
9927   int src_port = 0;
9928   int dst_port = 0;
9929
9930   tcpudp_header_t h;
9931
9932   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9933     {
9934       if (unformat (input, "src_port %d", &src_port))
9935         ;
9936       else if (unformat (input, "dst_port %d", &dst_port))
9937         ;
9938       else
9939         return 0;
9940     }
9941
9942   h.src_port = clib_host_to_net_u16 (src_port);
9943   h.dst_port = clib_host_to_net_u16 (dst_port);
9944   vec_validate (proto_header, sizeof (h) - 1);
9945   memcpy (proto_header, &h, sizeof (h));
9946
9947   *matchp = proto_header;
9948
9949   return 1;
9950 }
9951
9952 uword
9953 unformat_ip4_match (unformat_input_t * input, va_list * args)
9954 {
9955   u8 **matchp = va_arg (*args, u8 **);
9956   u8 *match = 0;
9957   ip4_header_t *ip;
9958   int version = 0;
9959   u32 version_val;
9960   int hdr_length = 0;
9961   u32 hdr_length_val;
9962   int src = 0, dst = 0;
9963   ip4_address_t src_val, dst_val;
9964   int proto = 0;
9965   u32 proto_val;
9966   int tos = 0;
9967   u32 tos_val;
9968   int length = 0;
9969   u32 length_val;
9970   int fragment_id = 0;
9971   u32 fragment_id_val;
9972   int ttl = 0;
9973   int ttl_val;
9974   int checksum = 0;
9975   u32 checksum_val;
9976
9977   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9978     {
9979       if (unformat (input, "version %d", &version_val))
9980         version = 1;
9981       else if (unformat (input, "hdr_length %d", &hdr_length_val))
9982         hdr_length = 1;
9983       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
9984         src = 1;
9985       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
9986         dst = 1;
9987       else if (unformat (input, "proto %d", &proto_val))
9988         proto = 1;
9989       else if (unformat (input, "tos %d", &tos_val))
9990         tos = 1;
9991       else if (unformat (input, "length %d", &length_val))
9992         length = 1;
9993       else if (unformat (input, "fragment_id %d", &fragment_id_val))
9994         fragment_id = 1;
9995       else if (unformat (input, "ttl %d", &ttl_val))
9996         ttl = 1;
9997       else if (unformat (input, "checksum %d", &checksum_val))
9998         checksum = 1;
9999       else
10000         break;
10001     }
10002
10003   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
10004       + ttl + checksum == 0)
10005     return 0;
10006
10007   /*
10008    * Aligned because we use the real comparison functions
10009    */
10010   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
10011
10012   ip = (ip4_header_t *) match;
10013
10014   /* These are realistically matched in practice */
10015   if (src)
10016     ip->src_address.as_u32 = src_val.as_u32;
10017
10018   if (dst)
10019     ip->dst_address.as_u32 = dst_val.as_u32;
10020
10021   if (proto)
10022     ip->protocol = proto_val;
10023
10024
10025   /* These are not, but they're included for completeness */
10026   if (version)
10027     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
10028
10029   if (hdr_length)
10030     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
10031
10032   if (tos)
10033     ip->tos = tos_val;
10034
10035   if (length)
10036     ip->length = clib_host_to_net_u16 (length_val);
10037
10038   if (ttl)
10039     ip->ttl = ttl_val;
10040
10041   if (checksum)
10042     ip->checksum = clib_host_to_net_u16 (checksum_val);
10043
10044   *matchp = match;
10045   return 1;
10046 }
10047
10048 uword
10049 unformat_ip6_match (unformat_input_t * input, va_list * args)
10050 {
10051   u8 **matchp = va_arg (*args, u8 **);
10052   u8 *match = 0;
10053   ip6_header_t *ip;
10054   int version = 0;
10055   u32 version_val;
10056   u8 traffic_class = 0;
10057   u32 traffic_class_val = 0;
10058   u8 flow_label = 0;
10059   u8 flow_label_val;
10060   int src = 0, dst = 0;
10061   ip6_address_t src_val, dst_val;
10062   int proto = 0;
10063   u32 proto_val;
10064   int payload_length = 0;
10065   u32 payload_length_val;
10066   int hop_limit = 0;
10067   int hop_limit_val;
10068   u32 ip_version_traffic_class_and_flow_label;
10069
10070   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10071     {
10072       if (unformat (input, "version %d", &version_val))
10073         version = 1;
10074       else if (unformat (input, "traffic_class %d", &traffic_class_val))
10075         traffic_class = 1;
10076       else if (unformat (input, "flow_label %d", &flow_label_val))
10077         flow_label = 1;
10078       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
10079         src = 1;
10080       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
10081         dst = 1;
10082       else if (unformat (input, "proto %d", &proto_val))
10083         proto = 1;
10084       else if (unformat (input, "payload_length %d", &payload_length_val))
10085         payload_length = 1;
10086       else if (unformat (input, "hop_limit %d", &hop_limit_val))
10087         hop_limit = 1;
10088       else
10089         break;
10090     }
10091
10092   if (version + traffic_class + flow_label + src + dst + proto +
10093       payload_length + hop_limit == 0)
10094     return 0;
10095
10096   /*
10097    * Aligned because we use the real comparison functions
10098    */
10099   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
10100
10101   ip = (ip6_header_t *) match;
10102
10103   if (src)
10104     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
10105
10106   if (dst)
10107     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
10108
10109   if (proto)
10110     ip->protocol = proto_val;
10111
10112   ip_version_traffic_class_and_flow_label = 0;
10113
10114   if (version)
10115     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
10116
10117   if (traffic_class)
10118     ip_version_traffic_class_and_flow_label |=
10119       (traffic_class_val & 0xFF) << 20;
10120
10121   if (flow_label)
10122     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
10123
10124   ip->ip_version_traffic_class_and_flow_label =
10125     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
10126
10127   if (payload_length)
10128     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
10129
10130   if (hop_limit)
10131     ip->hop_limit = hop_limit_val;
10132
10133   *matchp = match;
10134   return 1;
10135 }
10136
10137 uword
10138 unformat_l3_match (unformat_input_t * input, va_list * args)
10139 {
10140   u8 **matchp = va_arg (*args, u8 **);
10141
10142   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10143     {
10144       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
10145         return 1;
10146       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
10147         return 1;
10148       else
10149         break;
10150     }
10151   return 0;
10152 }
10153
10154 uword
10155 unformat_vlan_tag (unformat_input_t * input, va_list * args)
10156 {
10157   u8 *tagp = va_arg (*args, u8 *);
10158   u32 tag;
10159
10160   if (unformat (input, "%d", &tag))
10161     {
10162       tagp[0] = (tag >> 8) & 0x0F;
10163       tagp[1] = tag & 0xFF;
10164       return 1;
10165     }
10166
10167   return 0;
10168 }
10169
10170 uword
10171 unformat_l2_match (unformat_input_t * input, va_list * args)
10172 {
10173   u8 **matchp = va_arg (*args, u8 **);
10174   u8 *match = 0;
10175   u8 src = 0;
10176   u8 src_val[6];
10177   u8 dst = 0;
10178   u8 dst_val[6];
10179   u8 proto = 0;
10180   u16 proto_val;
10181   u8 tag1 = 0;
10182   u8 tag1_val[2];
10183   u8 tag2 = 0;
10184   u8 tag2_val[2];
10185   int len = 14;
10186   u8 ignore_tag1 = 0;
10187   u8 ignore_tag2 = 0;
10188   u8 cos1 = 0;
10189   u8 cos2 = 0;
10190   u32 cos1_val = 0;
10191   u32 cos2_val = 0;
10192
10193   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10194     {
10195       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
10196         src = 1;
10197       else
10198         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
10199         dst = 1;
10200       else if (unformat (input, "proto %U",
10201                          unformat_ethernet_type_host_byte_order, &proto_val))
10202         proto = 1;
10203       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
10204         tag1 = 1;
10205       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
10206         tag2 = 1;
10207       else if (unformat (input, "ignore-tag1"))
10208         ignore_tag1 = 1;
10209       else if (unformat (input, "ignore-tag2"))
10210         ignore_tag2 = 1;
10211       else if (unformat (input, "cos1 %d", &cos1_val))
10212         cos1 = 1;
10213       else if (unformat (input, "cos2 %d", &cos2_val))
10214         cos2 = 1;
10215       else
10216         break;
10217     }
10218   if ((src + dst + proto + tag1 + tag2 +
10219        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
10220     return 0;
10221
10222   if (tag1 || ignore_tag1 || cos1)
10223     len = 18;
10224   if (tag2 || ignore_tag2 || cos2)
10225     len = 22;
10226
10227   vec_validate_aligned (match, len - 1, sizeof (u32x4));
10228
10229   if (dst)
10230     clib_memcpy (match, dst_val, 6);
10231
10232   if (src)
10233     clib_memcpy (match + 6, src_val, 6);
10234
10235   if (tag2)
10236     {
10237       /* inner vlan tag */
10238       match[19] = tag2_val[1];
10239       match[18] = tag2_val[0];
10240       if (cos2)
10241         match[18] |= (cos2_val & 0x7) << 5;
10242       if (proto)
10243         {
10244           match[21] = proto_val & 0xff;
10245           match[20] = proto_val >> 8;
10246         }
10247       if (tag1)
10248         {
10249           match[15] = tag1_val[1];
10250           match[14] = tag1_val[0];
10251         }
10252       if (cos1)
10253         match[14] |= (cos1_val & 0x7) << 5;
10254       *matchp = match;
10255       return 1;
10256     }
10257   if (tag1)
10258     {
10259       match[15] = tag1_val[1];
10260       match[14] = tag1_val[0];
10261       if (proto)
10262         {
10263           match[17] = proto_val & 0xff;
10264           match[16] = proto_val >> 8;
10265         }
10266       if (cos1)
10267         match[14] |= (cos1_val & 0x7) << 5;
10268
10269       *matchp = match;
10270       return 1;
10271     }
10272   if (cos2)
10273     match[18] |= (cos2_val & 0x7) << 5;
10274   if (cos1)
10275     match[14] |= (cos1_val & 0x7) << 5;
10276   if (proto)
10277     {
10278       match[13] = proto_val & 0xff;
10279       match[12] = proto_val >> 8;
10280     }
10281
10282   *matchp = match;
10283   return 1;
10284 }
10285 #endif
10286
10287 uword
10288 api_unformat_classify_match (unformat_input_t * input, va_list * args)
10289 {
10290   u8 **matchp = va_arg (*args, u8 **);
10291   u32 skip_n_vectors = va_arg (*args, u32);
10292   u32 match_n_vectors = va_arg (*args, u32);
10293
10294   u8 *match = 0;
10295   u8 *l2 = 0;
10296   u8 *l3 = 0;
10297   u8 *l4 = 0;
10298
10299   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10300     {
10301       if (unformat (input, "hex %U", unformat_hex_string, &match))
10302         ;
10303       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
10304         ;
10305       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
10306         ;
10307       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
10308         ;
10309       else
10310         break;
10311     }
10312
10313   if (l4 && !l3)
10314     {
10315       vec_free (match);
10316       vec_free (l2);
10317       vec_free (l4);
10318       return 0;
10319     }
10320
10321   if (match || l2 || l3 || l4)
10322     {
10323       if (l2 || l3 || l4)
10324         {
10325           /* "Win a free Ethernet header in every packet" */
10326           if (l2 == 0)
10327             vec_validate_aligned (l2, 13, sizeof (u32x4));
10328           match = l2;
10329           if (vec_len (l3))
10330             {
10331               vec_append_aligned (match, l3, sizeof (u32x4));
10332               vec_free (l3);
10333             }
10334           if (vec_len (l4))
10335             {
10336               vec_append_aligned (match, l4, sizeof (u32x4));
10337               vec_free (l4);
10338             }
10339         }
10340
10341       /* Make sure the vector is big enough even if key is all 0's */
10342       vec_validate_aligned
10343         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
10344          sizeof (u32x4));
10345
10346       /* Set size, include skipped vectors */
10347       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
10348
10349       *matchp = match;
10350
10351       return 1;
10352     }
10353
10354   return 0;
10355 }
10356
10357 static int
10358 api_classify_add_del_session (vat_main_t * vam)
10359 {
10360   unformat_input_t *i = vam->input;
10361   vl_api_classify_add_del_session_t *mp;
10362   int is_add = 1;
10363   u32 table_index = ~0;
10364   u32 hit_next_index = ~0;
10365   u32 opaque_index = ~0;
10366   u8 *match = 0;
10367   i32 advance = 0;
10368   u32 skip_n_vectors = 0;
10369   u32 match_n_vectors = 0;
10370   u32 action = 0;
10371   u32 metadata = 0;
10372   int ret;
10373
10374   /*
10375    * Warning: you have to supply skip_n and match_n
10376    * because the API client cant simply look at the classify
10377    * table object.
10378    */
10379
10380   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10381     {
10382       if (unformat (i, "del"))
10383         is_add = 0;
10384       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
10385                          &hit_next_index))
10386         ;
10387       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
10388                          &hit_next_index))
10389         ;
10390       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
10391                          &hit_next_index))
10392         ;
10393       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
10394         ;
10395       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
10396         ;
10397       else if (unformat (i, "opaque-index %d", &opaque_index))
10398         ;
10399       else if (unformat (i, "skip_n %d", &skip_n_vectors))
10400         ;
10401       else if (unformat (i, "match_n %d", &match_n_vectors))
10402         ;
10403       else if (unformat (i, "match %U", api_unformat_classify_match,
10404                          &match, skip_n_vectors, match_n_vectors))
10405         ;
10406       else if (unformat (i, "advance %d", &advance))
10407         ;
10408       else if (unformat (i, "table-index %d", &table_index))
10409         ;
10410       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
10411         action = 1;
10412       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
10413         action = 2;
10414       else if (unformat (i, "action %d", &action))
10415         ;
10416       else if (unformat (i, "metadata %d", &metadata))
10417         ;
10418       else
10419         break;
10420     }
10421
10422   if (table_index == ~0)
10423     {
10424       errmsg ("Table index required");
10425       return -99;
10426     }
10427
10428   if (is_add && match == 0)
10429     {
10430       errmsg ("Match value required");
10431       return -99;
10432     }
10433
10434   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
10435
10436   mp->is_add = is_add;
10437   mp->table_index = ntohl (table_index);
10438   mp->hit_next_index = ntohl (hit_next_index);
10439   mp->opaque_index = ntohl (opaque_index);
10440   mp->advance = ntohl (advance);
10441   mp->action = action;
10442   mp->metadata = ntohl (metadata);
10443   clib_memcpy (mp->match, match, vec_len (match));
10444   vec_free (match);
10445
10446   S (mp);
10447   W (ret);
10448   return ret;
10449 }
10450
10451 static int
10452 api_classify_set_interface_ip_table (vat_main_t * vam)
10453 {
10454   unformat_input_t *i = vam->input;
10455   vl_api_classify_set_interface_ip_table_t *mp;
10456   u32 sw_if_index;
10457   int sw_if_index_set;
10458   u32 table_index = ~0;
10459   u8 is_ipv6 = 0;
10460   int ret;
10461
10462   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10463     {
10464       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10465         sw_if_index_set = 1;
10466       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10467         sw_if_index_set = 1;
10468       else if (unformat (i, "table %d", &table_index))
10469         ;
10470       else
10471         {
10472           clib_warning ("parse error '%U'", format_unformat_error, i);
10473           return -99;
10474         }
10475     }
10476
10477   if (sw_if_index_set == 0)
10478     {
10479       errmsg ("missing interface name or sw_if_index");
10480       return -99;
10481     }
10482
10483
10484   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
10485
10486   mp->sw_if_index = ntohl (sw_if_index);
10487   mp->table_index = ntohl (table_index);
10488   mp->is_ipv6 = is_ipv6;
10489
10490   S (mp);
10491   W (ret);
10492   return ret;
10493 }
10494
10495 static int
10496 api_classify_set_interface_l2_tables (vat_main_t * vam)
10497 {
10498   unformat_input_t *i = vam->input;
10499   vl_api_classify_set_interface_l2_tables_t *mp;
10500   u32 sw_if_index;
10501   int sw_if_index_set;
10502   u32 ip4_table_index = ~0;
10503   u32 ip6_table_index = ~0;
10504   u32 other_table_index = ~0;
10505   u32 is_input = 1;
10506   int ret;
10507
10508   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10509     {
10510       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10511         sw_if_index_set = 1;
10512       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10513         sw_if_index_set = 1;
10514       else if (unformat (i, "ip4-table %d", &ip4_table_index))
10515         ;
10516       else if (unformat (i, "ip6-table %d", &ip6_table_index))
10517         ;
10518       else if (unformat (i, "other-table %d", &other_table_index))
10519         ;
10520       else if (unformat (i, "is-input %d", &is_input))
10521         ;
10522       else
10523         {
10524           clib_warning ("parse error '%U'", format_unformat_error, i);
10525           return -99;
10526         }
10527     }
10528
10529   if (sw_if_index_set == 0)
10530     {
10531       errmsg ("missing interface name or sw_if_index");
10532       return -99;
10533     }
10534
10535
10536   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
10537
10538   mp->sw_if_index = ntohl (sw_if_index);
10539   mp->ip4_table_index = ntohl (ip4_table_index);
10540   mp->ip6_table_index = ntohl (ip6_table_index);
10541   mp->other_table_index = ntohl (other_table_index);
10542   mp->is_input = (u8) is_input;
10543
10544   S (mp);
10545   W (ret);
10546   return ret;
10547 }
10548
10549 static int
10550 api_set_ipfix_exporter (vat_main_t * vam)
10551 {
10552   unformat_input_t *i = vam->input;
10553   vl_api_set_ipfix_exporter_t *mp;
10554   ip4_address_t collector_address;
10555   u8 collector_address_set = 0;
10556   u32 collector_port = ~0;
10557   ip4_address_t src_address;
10558   u8 src_address_set = 0;
10559   u32 vrf_id = ~0;
10560   u32 path_mtu = ~0;
10561   u32 template_interval = ~0;
10562   u8 udp_checksum = 0;
10563   int ret;
10564
10565   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10566     {
10567       if (unformat (i, "collector_address %U", unformat_ip4_address,
10568                     &collector_address))
10569         collector_address_set = 1;
10570       else if (unformat (i, "collector_port %d", &collector_port))
10571         ;
10572       else if (unformat (i, "src_address %U", unformat_ip4_address,
10573                          &src_address))
10574         src_address_set = 1;
10575       else if (unformat (i, "vrf_id %d", &vrf_id))
10576         ;
10577       else if (unformat (i, "path_mtu %d", &path_mtu))
10578         ;
10579       else if (unformat (i, "template_interval %d", &template_interval))
10580         ;
10581       else if (unformat (i, "udp_checksum"))
10582         udp_checksum = 1;
10583       else
10584         break;
10585     }
10586
10587   if (collector_address_set == 0)
10588     {
10589       errmsg ("collector_address required");
10590       return -99;
10591     }
10592
10593   if (src_address_set == 0)
10594     {
10595       errmsg ("src_address required");
10596       return -99;
10597     }
10598
10599   M (SET_IPFIX_EXPORTER, mp);
10600
10601   memcpy (mp->collector_address, collector_address.data,
10602           sizeof (collector_address.data));
10603   mp->collector_port = htons ((u16) collector_port);
10604   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
10605   mp->vrf_id = htonl (vrf_id);
10606   mp->path_mtu = htonl (path_mtu);
10607   mp->template_interval = htonl (template_interval);
10608   mp->udp_checksum = udp_checksum;
10609
10610   S (mp);
10611   W (ret);
10612   return ret;
10613 }
10614
10615 static int
10616 api_set_ipfix_classify_stream (vat_main_t * vam)
10617 {
10618   unformat_input_t *i = vam->input;
10619   vl_api_set_ipfix_classify_stream_t *mp;
10620   u32 domain_id = 0;
10621   u32 src_port = UDP_DST_PORT_ipfix;
10622   int ret;
10623
10624   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10625     {
10626       if (unformat (i, "domain %d", &domain_id))
10627         ;
10628       else if (unformat (i, "src_port %d", &src_port))
10629         ;
10630       else
10631         {
10632           errmsg ("unknown input `%U'", format_unformat_error, i);
10633           return -99;
10634         }
10635     }
10636
10637   M (SET_IPFIX_CLASSIFY_STREAM, mp);
10638
10639   mp->domain_id = htonl (domain_id);
10640   mp->src_port = htons ((u16) src_port);
10641
10642   S (mp);
10643   W (ret);
10644   return ret;
10645 }
10646
10647 static int
10648 api_ipfix_classify_table_add_del (vat_main_t * vam)
10649 {
10650   unformat_input_t *i = vam->input;
10651   vl_api_ipfix_classify_table_add_del_t *mp;
10652   int is_add = -1;
10653   u32 classify_table_index = ~0;
10654   u8 ip_version = 0;
10655   u8 transport_protocol = 255;
10656   int ret;
10657
10658   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10659     {
10660       if (unformat (i, "add"))
10661         is_add = 1;
10662       else if (unformat (i, "del"))
10663         is_add = 0;
10664       else if (unformat (i, "table %d", &classify_table_index))
10665         ;
10666       else if (unformat (i, "ip4"))
10667         ip_version = 4;
10668       else if (unformat (i, "ip6"))
10669         ip_version = 6;
10670       else if (unformat (i, "tcp"))
10671         transport_protocol = 6;
10672       else if (unformat (i, "udp"))
10673         transport_protocol = 17;
10674       else
10675         {
10676           errmsg ("unknown input `%U'", format_unformat_error, i);
10677           return -99;
10678         }
10679     }
10680
10681   if (is_add == -1)
10682     {
10683       errmsg ("expecting: add|del");
10684       return -99;
10685     }
10686   if (classify_table_index == ~0)
10687     {
10688       errmsg ("classifier table not specified");
10689       return -99;
10690     }
10691   if (ip_version == 0)
10692     {
10693       errmsg ("IP version not specified");
10694       return -99;
10695     }
10696
10697   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
10698
10699   mp->is_add = is_add;
10700   mp->table_id = htonl (classify_table_index);
10701   mp->ip_version = ip_version;
10702   mp->transport_protocol = transport_protocol;
10703
10704   S (mp);
10705   W (ret);
10706   return ret;
10707 }
10708
10709 static int
10710 api_get_node_index (vat_main_t * vam)
10711 {
10712   unformat_input_t *i = vam->input;
10713   vl_api_get_node_index_t *mp;
10714   u8 *name = 0;
10715   int ret;
10716
10717   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10718     {
10719       if (unformat (i, "node %s", &name))
10720         ;
10721       else
10722         break;
10723     }
10724   if (name == 0)
10725     {
10726       errmsg ("node name required");
10727       return -99;
10728     }
10729   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
10730     {
10731       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10732       return -99;
10733     }
10734
10735   M (GET_NODE_INDEX, mp);
10736   clib_memcpy (mp->node_name, name, vec_len (name));
10737   vec_free (name);
10738
10739   S (mp);
10740   W (ret);
10741   return ret;
10742 }
10743
10744 static int
10745 api_get_next_index (vat_main_t * vam)
10746 {
10747   unformat_input_t *i = vam->input;
10748   vl_api_get_next_index_t *mp;
10749   u8 *node_name = 0, *next_node_name = 0;
10750   int ret;
10751
10752   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10753     {
10754       if (unformat (i, "node-name %s", &node_name))
10755         ;
10756       else if (unformat (i, "next-node-name %s", &next_node_name))
10757         break;
10758     }
10759
10760   if (node_name == 0)
10761     {
10762       errmsg ("node name required");
10763       return -99;
10764     }
10765   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
10766     {
10767       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10768       return -99;
10769     }
10770
10771   if (next_node_name == 0)
10772     {
10773       errmsg ("next node name required");
10774       return -99;
10775     }
10776   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
10777     {
10778       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
10779       return -99;
10780     }
10781
10782   M (GET_NEXT_INDEX, mp);
10783   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
10784   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
10785   vec_free (node_name);
10786   vec_free (next_node_name);
10787
10788   S (mp);
10789   W (ret);
10790   return ret;
10791 }
10792
10793 static int
10794 api_add_node_next (vat_main_t * vam)
10795 {
10796   unformat_input_t *i = vam->input;
10797   vl_api_add_node_next_t *mp;
10798   u8 *name = 0;
10799   u8 *next = 0;
10800   int ret;
10801
10802   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10803     {
10804       if (unformat (i, "node %s", &name))
10805         ;
10806       else if (unformat (i, "next %s", &next))
10807         ;
10808       else
10809         break;
10810     }
10811   if (name == 0)
10812     {
10813       errmsg ("node name required");
10814       return -99;
10815     }
10816   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
10817     {
10818       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10819       return -99;
10820     }
10821   if (next == 0)
10822     {
10823       errmsg ("next node required");
10824       return -99;
10825     }
10826   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
10827     {
10828       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
10829       return -99;
10830     }
10831
10832   M (ADD_NODE_NEXT, mp);
10833   clib_memcpy (mp->node_name, name, vec_len (name));
10834   clib_memcpy (mp->next_name, next, vec_len (next));
10835   vec_free (name);
10836   vec_free (next);
10837
10838   S (mp);
10839   W (ret);
10840   return ret;
10841 }
10842
10843 static int
10844 api_l2tpv3_create_tunnel (vat_main_t * vam)
10845 {
10846   unformat_input_t *i = vam->input;
10847   ip6_address_t client_address, our_address;
10848   int client_address_set = 0;
10849   int our_address_set = 0;
10850   u32 local_session_id = 0;
10851   u32 remote_session_id = 0;
10852   u64 local_cookie = 0;
10853   u64 remote_cookie = 0;
10854   u8 l2_sublayer_present = 0;
10855   vl_api_l2tpv3_create_tunnel_t *mp;
10856   int ret;
10857
10858   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10859     {
10860       if (unformat (i, "client_address %U", unformat_ip6_address,
10861                     &client_address))
10862         client_address_set = 1;
10863       else if (unformat (i, "our_address %U", unformat_ip6_address,
10864                          &our_address))
10865         our_address_set = 1;
10866       else if (unformat (i, "local_session_id %d", &local_session_id))
10867         ;
10868       else if (unformat (i, "remote_session_id %d", &remote_session_id))
10869         ;
10870       else if (unformat (i, "local_cookie %lld", &local_cookie))
10871         ;
10872       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
10873         ;
10874       else if (unformat (i, "l2-sublayer-present"))
10875         l2_sublayer_present = 1;
10876       else
10877         break;
10878     }
10879
10880   if (client_address_set == 0)
10881     {
10882       errmsg ("client_address required");
10883       return -99;
10884     }
10885
10886   if (our_address_set == 0)
10887     {
10888       errmsg ("our_address required");
10889       return -99;
10890     }
10891
10892   M (L2TPV3_CREATE_TUNNEL, mp);
10893
10894   clib_memcpy (mp->client_address, client_address.as_u8,
10895                sizeof (mp->client_address));
10896
10897   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
10898
10899   mp->local_session_id = ntohl (local_session_id);
10900   mp->remote_session_id = ntohl (remote_session_id);
10901   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
10902   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
10903   mp->l2_sublayer_present = l2_sublayer_present;
10904   mp->is_ipv6 = 1;
10905
10906   S (mp);
10907   W (ret);
10908   return ret;
10909 }
10910
10911 static int
10912 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
10913 {
10914   unformat_input_t *i = vam->input;
10915   u32 sw_if_index;
10916   u8 sw_if_index_set = 0;
10917   u64 new_local_cookie = 0;
10918   u64 new_remote_cookie = 0;
10919   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
10920   int ret;
10921
10922   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10923     {
10924       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10925         sw_if_index_set = 1;
10926       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10927         sw_if_index_set = 1;
10928       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
10929         ;
10930       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
10931         ;
10932       else
10933         break;
10934     }
10935
10936   if (sw_if_index_set == 0)
10937     {
10938       errmsg ("missing interface name or sw_if_index");
10939       return -99;
10940     }
10941
10942   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
10943
10944   mp->sw_if_index = ntohl (sw_if_index);
10945   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
10946   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
10947
10948   S (mp);
10949   W (ret);
10950   return ret;
10951 }
10952
10953 static int
10954 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
10955 {
10956   unformat_input_t *i = vam->input;
10957   vl_api_l2tpv3_interface_enable_disable_t *mp;
10958   u32 sw_if_index;
10959   u8 sw_if_index_set = 0;
10960   u8 enable_disable = 1;
10961   int ret;
10962
10963   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10964     {
10965       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10966         sw_if_index_set = 1;
10967       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10968         sw_if_index_set = 1;
10969       else if (unformat (i, "enable"))
10970         enable_disable = 1;
10971       else if (unformat (i, "disable"))
10972         enable_disable = 0;
10973       else
10974         break;
10975     }
10976
10977   if (sw_if_index_set == 0)
10978     {
10979       errmsg ("missing interface name or sw_if_index");
10980       return -99;
10981     }
10982
10983   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
10984
10985   mp->sw_if_index = ntohl (sw_if_index);
10986   mp->enable_disable = enable_disable;
10987
10988   S (mp);
10989   W (ret);
10990   return ret;
10991 }
10992
10993 static int
10994 api_l2tpv3_set_lookup_key (vat_main_t * vam)
10995 {
10996   unformat_input_t *i = vam->input;
10997   vl_api_l2tpv3_set_lookup_key_t *mp;
10998   u8 key = ~0;
10999   int ret;
11000
11001   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11002     {
11003       if (unformat (i, "lookup_v6_src"))
11004         key = L2T_LOOKUP_SRC_ADDRESS;
11005       else if (unformat (i, "lookup_v6_dst"))
11006         key = L2T_LOOKUP_DST_ADDRESS;
11007       else if (unformat (i, "lookup_session_id"))
11008         key = L2T_LOOKUP_SESSION_ID;
11009       else
11010         break;
11011     }
11012
11013   if (key == (u8) ~ 0)
11014     {
11015       errmsg ("l2tp session lookup key unset");
11016       return -99;
11017     }
11018
11019   M (L2TPV3_SET_LOOKUP_KEY, mp);
11020
11021   mp->key = key;
11022
11023   S (mp);
11024   W (ret);
11025   return ret;
11026 }
11027
11028 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
11029   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
11030 {
11031   vat_main_t *vam = &vat_main;
11032
11033   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
11034          format_ip6_address, mp->our_address,
11035          format_ip6_address, mp->client_address,
11036          clib_net_to_host_u32 (mp->sw_if_index));
11037
11038   print (vam->ofp,
11039          "   local cookies %016llx %016llx remote cookie %016llx",
11040          clib_net_to_host_u64 (mp->local_cookie[0]),
11041          clib_net_to_host_u64 (mp->local_cookie[1]),
11042          clib_net_to_host_u64 (mp->remote_cookie));
11043
11044   print (vam->ofp, "   local session-id %d remote session-id %d",
11045          clib_net_to_host_u32 (mp->local_session_id),
11046          clib_net_to_host_u32 (mp->remote_session_id));
11047
11048   print (vam->ofp, "   l2 specific sublayer %s\n",
11049          mp->l2_sublayer_present ? "preset" : "absent");
11050
11051 }
11052
11053 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
11054   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
11055 {
11056   vat_main_t *vam = &vat_main;
11057   vat_json_node_t *node = NULL;
11058   struct in6_addr addr;
11059
11060   if (VAT_JSON_ARRAY != vam->json_tree.type)
11061     {
11062       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11063       vat_json_init_array (&vam->json_tree);
11064     }
11065   node = vat_json_array_add (&vam->json_tree);
11066
11067   vat_json_init_object (node);
11068
11069   clib_memcpy (&addr, mp->our_address, sizeof (addr));
11070   vat_json_object_add_ip6 (node, "our_address", addr);
11071   clib_memcpy (&addr, mp->client_address, sizeof (addr));
11072   vat_json_object_add_ip6 (node, "client_address", addr);
11073
11074   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
11075   vat_json_init_array (lc);
11076   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
11077   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
11078   vat_json_object_add_uint (node, "remote_cookie",
11079                             clib_net_to_host_u64 (mp->remote_cookie));
11080
11081   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
11082   vat_json_object_add_uint (node, "local_session_id",
11083                             clib_net_to_host_u32 (mp->local_session_id));
11084   vat_json_object_add_uint (node, "remote_session_id",
11085                             clib_net_to_host_u32 (mp->remote_session_id));
11086   vat_json_object_add_string_copy (node, "l2_sublayer",
11087                                    mp->l2_sublayer_present ? (u8 *) "present"
11088                                    : (u8 *) "absent");
11089 }
11090
11091 static int
11092 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
11093 {
11094   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
11095   vl_api_control_ping_t *mp_ping;
11096   int ret;
11097
11098   /* Get list of l2tpv3-tunnel interfaces */
11099   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
11100   S (mp);
11101
11102   /* Use a control ping for synchronization */
11103   M (CONTROL_PING, mp_ping);
11104   S (mp_ping);
11105
11106   W (ret);
11107   return ret;
11108 }
11109
11110
11111 static void vl_api_sw_interface_tap_details_t_handler
11112   (vl_api_sw_interface_tap_details_t * mp)
11113 {
11114   vat_main_t *vam = &vat_main;
11115
11116   print (vam->ofp, "%-16s %d",
11117          mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
11118 }
11119
11120 static void vl_api_sw_interface_tap_details_t_handler_json
11121   (vl_api_sw_interface_tap_details_t * mp)
11122 {
11123   vat_main_t *vam = &vat_main;
11124   vat_json_node_t *node = NULL;
11125
11126   if (VAT_JSON_ARRAY != vam->json_tree.type)
11127     {
11128       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11129       vat_json_init_array (&vam->json_tree);
11130     }
11131   node = vat_json_array_add (&vam->json_tree);
11132
11133   vat_json_init_object (node);
11134   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11135   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
11136 }
11137
11138 static int
11139 api_sw_interface_tap_dump (vat_main_t * vam)
11140 {
11141   vl_api_sw_interface_tap_dump_t *mp;
11142   vl_api_control_ping_t *mp_ping;
11143   int ret;
11144
11145   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
11146   /* Get list of tap interfaces */
11147   M (SW_INTERFACE_TAP_DUMP, mp);
11148   S (mp);
11149
11150   /* Use a control ping for synchronization */
11151   M (CONTROL_PING, mp_ping);
11152   S (mp_ping);
11153
11154   W (ret);
11155   return ret;
11156 }
11157
11158 static uword unformat_vxlan_decap_next
11159   (unformat_input_t * input, va_list * args)
11160 {
11161   u32 *result = va_arg (*args, u32 *);
11162   u32 tmp;
11163
11164   if (unformat (input, "l2"))
11165     *result = VXLAN_INPUT_NEXT_L2_INPUT;
11166   else if (unformat (input, "%d", &tmp))
11167     *result = tmp;
11168   else
11169     return 0;
11170   return 1;
11171 }
11172
11173 static int
11174 api_vxlan_add_del_tunnel (vat_main_t * vam)
11175 {
11176   unformat_input_t *line_input = vam->input;
11177   vl_api_vxlan_add_del_tunnel_t *mp;
11178   ip46_address_t src, dst;
11179   u8 is_add = 1;
11180   u8 ipv4_set = 0, ipv6_set = 0;
11181   u8 src_set = 0;
11182   u8 dst_set = 0;
11183   u8 grp_set = 0;
11184   u32 mcast_sw_if_index = ~0;
11185   u32 encap_vrf_id = 0;
11186   u32 decap_next_index = ~0;
11187   u32 vni = 0;
11188   int ret;
11189
11190   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
11191   memset (&src, 0, sizeof src);
11192   memset (&dst, 0, sizeof dst);
11193
11194   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11195     {
11196       if (unformat (line_input, "del"))
11197         is_add = 0;
11198       else
11199         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
11200         {
11201           ipv4_set = 1;
11202           src_set = 1;
11203         }
11204       else
11205         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
11206         {
11207           ipv4_set = 1;
11208           dst_set = 1;
11209         }
11210       else
11211         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
11212         {
11213           ipv6_set = 1;
11214           src_set = 1;
11215         }
11216       else
11217         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
11218         {
11219           ipv6_set = 1;
11220           dst_set = 1;
11221         }
11222       else if (unformat (line_input, "group %U %U",
11223                          unformat_ip4_address, &dst.ip4,
11224                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11225         {
11226           grp_set = dst_set = 1;
11227           ipv4_set = 1;
11228         }
11229       else if (unformat (line_input, "group %U",
11230                          unformat_ip4_address, &dst.ip4))
11231         {
11232           grp_set = dst_set = 1;
11233           ipv4_set = 1;
11234         }
11235       else if (unformat (line_input, "group %U %U",
11236                          unformat_ip6_address, &dst.ip6,
11237                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11238         {
11239           grp_set = dst_set = 1;
11240           ipv6_set = 1;
11241         }
11242       else if (unformat (line_input, "group %U",
11243                          unformat_ip6_address, &dst.ip6))
11244         {
11245           grp_set = dst_set = 1;
11246           ipv6_set = 1;
11247         }
11248       else
11249         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
11250         ;
11251       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
11252         ;
11253       else if (unformat (line_input, "decap-next %U",
11254                          unformat_vxlan_decap_next, &decap_next_index))
11255         ;
11256       else if (unformat (line_input, "vni %d", &vni))
11257         ;
11258       else
11259         {
11260           errmsg ("parse error '%U'", format_unformat_error, line_input);
11261           return -99;
11262         }
11263     }
11264
11265   if (src_set == 0)
11266     {
11267       errmsg ("tunnel src address not specified");
11268       return -99;
11269     }
11270   if (dst_set == 0)
11271     {
11272       errmsg ("tunnel dst address not specified");
11273       return -99;
11274     }
11275
11276   if (grp_set && !ip46_address_is_multicast (&dst))
11277     {
11278       errmsg ("tunnel group address not multicast");
11279       return -99;
11280     }
11281   if (grp_set && mcast_sw_if_index == ~0)
11282     {
11283       errmsg ("tunnel nonexistent multicast device");
11284       return -99;
11285     }
11286   if (grp_set == 0 && ip46_address_is_multicast (&dst))
11287     {
11288       errmsg ("tunnel dst address must be unicast");
11289       return -99;
11290     }
11291
11292
11293   if (ipv4_set && ipv6_set)
11294     {
11295       errmsg ("both IPv4 and IPv6 addresses specified");
11296       return -99;
11297     }
11298
11299   if ((vni == 0) || (vni >> 24))
11300     {
11301       errmsg ("vni not specified or out of range");
11302       return -99;
11303     }
11304
11305   M (VXLAN_ADD_DEL_TUNNEL, mp);
11306
11307   if (ipv6_set)
11308     {
11309       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
11310       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
11311     }
11312   else
11313     {
11314       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
11315       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
11316     }
11317   mp->encap_vrf_id = ntohl (encap_vrf_id);
11318   mp->decap_next_index = ntohl (decap_next_index);
11319   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
11320   mp->vni = ntohl (vni);
11321   mp->is_add = is_add;
11322   mp->is_ipv6 = ipv6_set;
11323
11324   S (mp);
11325   W (ret);
11326   return ret;
11327 }
11328
11329 static void vl_api_vxlan_tunnel_details_t_handler
11330   (vl_api_vxlan_tunnel_details_t * mp)
11331 {
11332   vat_main_t *vam = &vat_main;
11333   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
11334   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
11335
11336   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
11337          ntohl (mp->sw_if_index),
11338          format_ip46_address, &src, IP46_TYPE_ANY,
11339          format_ip46_address, &dst, IP46_TYPE_ANY,
11340          ntohl (mp->encap_vrf_id),
11341          ntohl (mp->decap_next_index), ntohl (mp->vni),
11342          ntohl (mp->mcast_sw_if_index));
11343 }
11344
11345 static void vl_api_vxlan_tunnel_details_t_handler_json
11346   (vl_api_vxlan_tunnel_details_t * mp)
11347 {
11348   vat_main_t *vam = &vat_main;
11349   vat_json_node_t *node = NULL;
11350
11351   if (VAT_JSON_ARRAY != vam->json_tree.type)
11352     {
11353       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11354       vat_json_init_array (&vam->json_tree);
11355     }
11356   node = vat_json_array_add (&vam->json_tree);
11357
11358   vat_json_init_object (node);
11359   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11360   if (mp->is_ipv6)
11361     {
11362       struct in6_addr ip6;
11363
11364       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
11365       vat_json_object_add_ip6 (node, "src_address", ip6);
11366       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
11367       vat_json_object_add_ip6 (node, "dst_address", ip6);
11368     }
11369   else
11370     {
11371       struct in_addr ip4;
11372
11373       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
11374       vat_json_object_add_ip4 (node, "src_address", ip4);
11375       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
11376       vat_json_object_add_ip4 (node, "dst_address", ip4);
11377     }
11378   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
11379   vat_json_object_add_uint (node, "decap_next_index",
11380                             ntohl (mp->decap_next_index));
11381   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
11382   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
11383   vat_json_object_add_uint (node, "mcast_sw_if_index",
11384                             ntohl (mp->mcast_sw_if_index));
11385 }
11386
11387 static int
11388 api_vxlan_tunnel_dump (vat_main_t * vam)
11389 {
11390   unformat_input_t *i = vam->input;
11391   vl_api_vxlan_tunnel_dump_t *mp;
11392   vl_api_control_ping_t *mp_ping;
11393   u32 sw_if_index;
11394   u8 sw_if_index_set = 0;
11395   int ret;
11396
11397   /* Parse args required to build the message */
11398   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11399     {
11400       if (unformat (i, "sw_if_index %d", &sw_if_index))
11401         sw_if_index_set = 1;
11402       else
11403         break;
11404     }
11405
11406   if (sw_if_index_set == 0)
11407     {
11408       sw_if_index = ~0;
11409     }
11410
11411   if (!vam->json_output)
11412     {
11413       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
11414              "sw_if_index", "src_address", "dst_address",
11415              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
11416     }
11417
11418   /* Get list of vxlan-tunnel interfaces */
11419   M (VXLAN_TUNNEL_DUMP, mp);
11420
11421   mp->sw_if_index = htonl (sw_if_index);
11422
11423   S (mp);
11424
11425   /* Use a control ping for synchronization */
11426   M (CONTROL_PING, mp_ping);
11427   S (mp_ping);
11428
11429   W (ret);
11430   return ret;
11431 }
11432
11433 static int
11434 api_gre_add_del_tunnel (vat_main_t * vam)
11435 {
11436   unformat_input_t *line_input = vam->input;
11437   vl_api_gre_add_del_tunnel_t *mp;
11438   ip4_address_t src4, dst4;
11439   ip6_address_t src6, dst6;
11440   u8 is_add = 1;
11441   u8 ipv4_set = 0;
11442   u8 ipv6_set = 0;
11443   u8 teb = 0;
11444   u8 src_set = 0;
11445   u8 dst_set = 0;
11446   u32 outer_fib_id = 0;
11447   int ret;
11448
11449   memset (&src4, 0, sizeof src4);
11450   memset (&dst4, 0, sizeof dst4);
11451   memset (&src6, 0, sizeof src6);
11452   memset (&dst6, 0, sizeof dst6);
11453
11454   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11455     {
11456       if (unformat (line_input, "del"))
11457         is_add = 0;
11458       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
11459         {
11460           src_set = 1;
11461           ipv4_set = 1;
11462         }
11463       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
11464         {
11465           dst_set = 1;
11466           ipv4_set = 1;
11467         }
11468       else if (unformat (line_input, "src %U", unformat_ip6_address, &src6))
11469         {
11470           src_set = 1;
11471           ipv6_set = 1;
11472         }
11473       else if (unformat (line_input, "dst %U", unformat_ip6_address, &dst6))
11474         {
11475           dst_set = 1;
11476           ipv6_set = 1;
11477         }
11478       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
11479         ;
11480       else if (unformat (line_input, "teb"))
11481         teb = 1;
11482       else
11483         {
11484           errmsg ("parse error '%U'", format_unformat_error, line_input);
11485           return -99;
11486         }
11487     }
11488
11489   if (src_set == 0)
11490     {
11491       errmsg ("tunnel src address not specified");
11492       return -99;
11493     }
11494   if (dst_set == 0)
11495     {
11496       errmsg ("tunnel dst address not specified");
11497       return -99;
11498     }
11499   if (ipv4_set && ipv6_set)
11500     {
11501       errmsg ("both IPv4 and IPv6 addresses specified");
11502       return -99;
11503     }
11504
11505
11506   M (GRE_ADD_DEL_TUNNEL, mp);
11507
11508   if (ipv4_set)
11509     {
11510       clib_memcpy (&mp->src_address, &src4, 4);
11511       clib_memcpy (&mp->dst_address, &dst4, 4);
11512     }
11513   else
11514     {
11515       clib_memcpy (&mp->src_address, &src6, 16);
11516       clib_memcpy (&mp->dst_address, &dst6, 16);
11517     }
11518   mp->outer_fib_id = ntohl (outer_fib_id);
11519   mp->is_add = is_add;
11520   mp->teb = teb;
11521   mp->is_ipv6 = ipv6_set;
11522
11523   S (mp);
11524   W (ret);
11525   return ret;
11526 }
11527
11528 static void vl_api_gre_tunnel_details_t_handler
11529   (vl_api_gre_tunnel_details_t * mp)
11530 {
11531   vat_main_t *vam = &vat_main;
11532   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->src_address);
11533   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->dst_address);
11534
11535   print (vam->ofp, "%11d%24U%24U%6d%14d",
11536          ntohl (mp->sw_if_index),
11537          format_ip46_address, &src, IP46_TYPE_ANY,
11538          format_ip46_address, &dst, IP46_TYPE_ANY,
11539          mp->teb, ntohl (mp->outer_fib_id));
11540 }
11541
11542 static void vl_api_gre_tunnel_details_t_handler_json
11543   (vl_api_gre_tunnel_details_t * mp)
11544 {
11545   vat_main_t *vam = &vat_main;
11546   vat_json_node_t *node = NULL;
11547   struct in_addr ip4;
11548   struct in6_addr ip6;
11549
11550   if (VAT_JSON_ARRAY != vam->json_tree.type)
11551     {
11552       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11553       vat_json_init_array (&vam->json_tree);
11554     }
11555   node = vat_json_array_add (&vam->json_tree);
11556
11557   vat_json_init_object (node);
11558   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11559   if (!mp->is_ipv6)
11560     {
11561       clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
11562       vat_json_object_add_ip4 (node, "src_address", ip4);
11563       clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
11564       vat_json_object_add_ip4 (node, "dst_address", ip4);
11565     }
11566   else
11567     {
11568       clib_memcpy (&ip6, &mp->src_address, sizeof (ip6));
11569       vat_json_object_add_ip6 (node, "src_address", ip6);
11570       clib_memcpy (&ip6, &mp->dst_address, sizeof (ip6));
11571       vat_json_object_add_ip6 (node, "dst_address", ip6);
11572     }
11573   vat_json_object_add_uint (node, "teb", mp->teb);
11574   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
11575   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6);
11576 }
11577
11578 static int
11579 api_gre_tunnel_dump (vat_main_t * vam)
11580 {
11581   unformat_input_t *i = vam->input;
11582   vl_api_gre_tunnel_dump_t *mp;
11583   vl_api_control_ping_t *mp_ping;
11584   u32 sw_if_index;
11585   u8 sw_if_index_set = 0;
11586   int ret;
11587
11588   /* Parse args required to build the message */
11589   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11590     {
11591       if (unformat (i, "sw_if_index %d", &sw_if_index))
11592         sw_if_index_set = 1;
11593       else
11594         break;
11595     }
11596
11597   if (sw_if_index_set == 0)
11598     {
11599       sw_if_index = ~0;
11600     }
11601
11602   if (!vam->json_output)
11603     {
11604       print (vam->ofp, "%11s%24s%24s%6s%14s",
11605              "sw_if_index", "src_address", "dst_address", "teb",
11606              "outer_fib_id");
11607     }
11608
11609   /* Get list of gre-tunnel interfaces */
11610   M (GRE_TUNNEL_DUMP, mp);
11611
11612   mp->sw_if_index = htonl (sw_if_index);
11613
11614   S (mp);
11615
11616   /* Use a control ping for synchronization */
11617   M (CONTROL_PING, mp_ping);
11618   S (mp_ping);
11619
11620   W (ret);
11621   return ret;
11622 }
11623
11624 static int
11625 api_l2_fib_clear_table (vat_main_t * vam)
11626 {
11627 //  unformat_input_t * i = vam->input;
11628   vl_api_l2_fib_clear_table_t *mp;
11629   int ret;
11630
11631   M (L2_FIB_CLEAR_TABLE, mp);
11632
11633   S (mp);
11634   W (ret);
11635   return ret;
11636 }
11637
11638 static int
11639 api_l2_interface_efp_filter (vat_main_t * vam)
11640 {
11641   unformat_input_t *i = vam->input;
11642   vl_api_l2_interface_efp_filter_t *mp;
11643   u32 sw_if_index;
11644   u8 enable = 1;
11645   u8 sw_if_index_set = 0;
11646   int ret;
11647
11648   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11649     {
11650       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11651         sw_if_index_set = 1;
11652       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11653         sw_if_index_set = 1;
11654       else if (unformat (i, "enable"))
11655         enable = 1;
11656       else if (unformat (i, "disable"))
11657         enable = 0;
11658       else
11659         {
11660           clib_warning ("parse error '%U'", format_unformat_error, i);
11661           return -99;
11662         }
11663     }
11664
11665   if (sw_if_index_set == 0)
11666     {
11667       errmsg ("missing sw_if_index");
11668       return -99;
11669     }
11670
11671   M (L2_INTERFACE_EFP_FILTER, mp);
11672
11673   mp->sw_if_index = ntohl (sw_if_index);
11674   mp->enable_disable = enable;
11675
11676   S (mp);
11677   W (ret);
11678   return ret;
11679 }
11680
11681 #define foreach_vtr_op                          \
11682 _("disable",  L2_VTR_DISABLED)                  \
11683 _("push-1",  L2_VTR_PUSH_1)                     \
11684 _("push-2",  L2_VTR_PUSH_2)                     \
11685 _("pop-1",  L2_VTR_POP_1)                       \
11686 _("pop-2",  L2_VTR_POP_2)                       \
11687 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
11688 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
11689 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
11690 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
11691
11692 static int
11693 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
11694 {
11695   unformat_input_t *i = vam->input;
11696   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
11697   u32 sw_if_index;
11698   u8 sw_if_index_set = 0;
11699   u8 vtr_op_set = 0;
11700   u32 vtr_op = 0;
11701   u32 push_dot1q = 1;
11702   u32 tag1 = ~0;
11703   u32 tag2 = ~0;
11704   int ret;
11705
11706   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11707     {
11708       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11709         sw_if_index_set = 1;
11710       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11711         sw_if_index_set = 1;
11712       else if (unformat (i, "vtr_op %d", &vtr_op))
11713         vtr_op_set = 1;
11714 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
11715       foreach_vtr_op
11716 #undef _
11717         else if (unformat (i, "push_dot1q %d", &push_dot1q))
11718         ;
11719       else if (unformat (i, "tag1 %d", &tag1))
11720         ;
11721       else if (unformat (i, "tag2 %d", &tag2))
11722         ;
11723       else
11724         {
11725           clib_warning ("parse error '%U'", format_unformat_error, i);
11726           return -99;
11727         }
11728     }
11729
11730   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
11731     {
11732       errmsg ("missing vtr operation or sw_if_index");
11733       return -99;
11734     }
11735
11736   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
11737   mp->sw_if_index = ntohl (sw_if_index);
11738   mp->vtr_op = ntohl (vtr_op);
11739   mp->push_dot1q = ntohl (push_dot1q);
11740   mp->tag1 = ntohl (tag1);
11741   mp->tag2 = ntohl (tag2);
11742
11743   S (mp);
11744   W (ret);
11745   return ret;
11746 }
11747
11748 static int
11749 api_create_vhost_user_if (vat_main_t * vam)
11750 {
11751   unformat_input_t *i = vam->input;
11752   vl_api_create_vhost_user_if_t *mp;
11753   u8 *file_name;
11754   u8 is_server = 0;
11755   u8 file_name_set = 0;
11756   u32 custom_dev_instance = ~0;
11757   u8 hwaddr[6];
11758   u8 use_custom_mac = 0;
11759   u8 *tag = 0;
11760   int ret;
11761
11762   /* Shut up coverity */
11763   memset (hwaddr, 0, sizeof (hwaddr));
11764
11765   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11766     {
11767       if (unformat (i, "socket %s", &file_name))
11768         {
11769           file_name_set = 1;
11770         }
11771       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
11772         ;
11773       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
11774         use_custom_mac = 1;
11775       else if (unformat (i, "server"))
11776         is_server = 1;
11777       else if (unformat (i, "tag %s", &tag))
11778         ;
11779       else
11780         break;
11781     }
11782
11783   if (file_name_set == 0)
11784     {
11785       errmsg ("missing socket file name");
11786       return -99;
11787     }
11788
11789   if (vec_len (file_name) > 255)
11790     {
11791       errmsg ("socket file name too long");
11792       return -99;
11793     }
11794   vec_add1 (file_name, 0);
11795
11796   M (CREATE_VHOST_USER_IF, mp);
11797
11798   mp->is_server = is_server;
11799   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
11800   vec_free (file_name);
11801   if (custom_dev_instance != ~0)
11802     {
11803       mp->renumber = 1;
11804       mp->custom_dev_instance = ntohl (custom_dev_instance);
11805     }
11806   mp->use_custom_mac = use_custom_mac;
11807   clib_memcpy (mp->mac_address, hwaddr, 6);
11808   if (tag)
11809     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
11810   vec_free (tag);
11811
11812   S (mp);
11813   W (ret);
11814   return ret;
11815 }
11816
11817 static int
11818 api_modify_vhost_user_if (vat_main_t * vam)
11819 {
11820   unformat_input_t *i = vam->input;
11821   vl_api_modify_vhost_user_if_t *mp;
11822   u8 *file_name;
11823   u8 is_server = 0;
11824   u8 file_name_set = 0;
11825   u32 custom_dev_instance = ~0;
11826   u8 sw_if_index_set = 0;
11827   u32 sw_if_index = (u32) ~ 0;
11828   int ret;
11829
11830   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11831     {
11832       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11833         sw_if_index_set = 1;
11834       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11835         sw_if_index_set = 1;
11836       else if (unformat (i, "socket %s", &file_name))
11837         {
11838           file_name_set = 1;
11839         }
11840       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
11841         ;
11842       else if (unformat (i, "server"))
11843         is_server = 1;
11844       else
11845         break;
11846     }
11847
11848   if (sw_if_index_set == 0)
11849     {
11850       errmsg ("missing sw_if_index or interface name");
11851       return -99;
11852     }
11853
11854   if (file_name_set == 0)
11855     {
11856       errmsg ("missing socket file name");
11857       return -99;
11858     }
11859
11860   if (vec_len (file_name) > 255)
11861     {
11862       errmsg ("socket file name too long");
11863       return -99;
11864     }
11865   vec_add1 (file_name, 0);
11866
11867   M (MODIFY_VHOST_USER_IF, mp);
11868
11869   mp->sw_if_index = ntohl (sw_if_index);
11870   mp->is_server = is_server;
11871   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
11872   vec_free (file_name);
11873   if (custom_dev_instance != ~0)
11874     {
11875       mp->renumber = 1;
11876       mp->custom_dev_instance = ntohl (custom_dev_instance);
11877     }
11878
11879   S (mp);
11880   W (ret);
11881   return ret;
11882 }
11883
11884 static int
11885 api_delete_vhost_user_if (vat_main_t * vam)
11886 {
11887   unformat_input_t *i = vam->input;
11888   vl_api_delete_vhost_user_if_t *mp;
11889   u32 sw_if_index = ~0;
11890   u8 sw_if_index_set = 0;
11891   int ret;
11892
11893   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11894     {
11895       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11896         sw_if_index_set = 1;
11897       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11898         sw_if_index_set = 1;
11899       else
11900         break;
11901     }
11902
11903   if (sw_if_index_set == 0)
11904     {
11905       errmsg ("missing sw_if_index or interface name");
11906       return -99;
11907     }
11908
11909
11910   M (DELETE_VHOST_USER_IF, mp);
11911
11912   mp->sw_if_index = ntohl (sw_if_index);
11913
11914   S (mp);
11915   W (ret);
11916   return ret;
11917 }
11918
11919 static void vl_api_sw_interface_vhost_user_details_t_handler
11920   (vl_api_sw_interface_vhost_user_details_t * mp)
11921 {
11922   vat_main_t *vam = &vat_main;
11923
11924   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
11925          (char *) mp->interface_name,
11926          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
11927          clib_net_to_host_u64 (mp->features), mp->is_server,
11928          ntohl (mp->num_regions), (char *) mp->sock_filename);
11929   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
11930 }
11931
11932 static void vl_api_sw_interface_vhost_user_details_t_handler_json
11933   (vl_api_sw_interface_vhost_user_details_t * mp)
11934 {
11935   vat_main_t *vam = &vat_main;
11936   vat_json_node_t *node = NULL;
11937
11938   if (VAT_JSON_ARRAY != vam->json_tree.type)
11939     {
11940       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11941       vat_json_init_array (&vam->json_tree);
11942     }
11943   node = vat_json_array_add (&vam->json_tree);
11944
11945   vat_json_init_object (node);
11946   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11947   vat_json_object_add_string_copy (node, "interface_name",
11948                                    mp->interface_name);
11949   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
11950                             ntohl (mp->virtio_net_hdr_sz));
11951   vat_json_object_add_uint (node, "features",
11952                             clib_net_to_host_u64 (mp->features));
11953   vat_json_object_add_uint (node, "is_server", mp->is_server);
11954   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
11955   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
11956   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
11957 }
11958
11959 static int
11960 api_sw_interface_vhost_user_dump (vat_main_t * vam)
11961 {
11962   vl_api_sw_interface_vhost_user_dump_t *mp;
11963   vl_api_control_ping_t *mp_ping;
11964   int ret;
11965   print (vam->ofp,
11966          "Interface name            idx hdr_sz features server regions filename");
11967
11968   /* Get list of vhost-user interfaces */
11969   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
11970   S (mp);
11971
11972   /* Use a control ping for synchronization */
11973   M (CONTROL_PING, mp_ping);
11974   S (mp_ping);
11975
11976   W (ret);
11977   return ret;
11978 }
11979
11980 static int
11981 api_show_version (vat_main_t * vam)
11982 {
11983   vl_api_show_version_t *mp;
11984   int ret;
11985
11986   M (SHOW_VERSION, mp);
11987
11988   S (mp);
11989   W (ret);
11990   return ret;
11991 }
11992
11993
11994 static int
11995 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
11996 {
11997   unformat_input_t *line_input = vam->input;
11998   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
11999   ip4_address_t local4, remote4;
12000   ip6_address_t local6, remote6;
12001   u8 is_add = 1;
12002   u8 ipv4_set = 0, ipv6_set = 0;
12003   u8 local_set = 0;
12004   u8 remote_set = 0;
12005   u32 encap_vrf_id = 0;
12006   u32 decap_vrf_id = 0;
12007   u8 protocol = ~0;
12008   u32 vni;
12009   u8 vni_set = 0;
12010   int ret;
12011
12012   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12013     {
12014       if (unformat (line_input, "del"))
12015         is_add = 0;
12016       else if (unformat (line_input, "local %U",
12017                          unformat_ip4_address, &local4))
12018         {
12019           local_set = 1;
12020           ipv4_set = 1;
12021         }
12022       else if (unformat (line_input, "remote %U",
12023                          unformat_ip4_address, &remote4))
12024         {
12025           remote_set = 1;
12026           ipv4_set = 1;
12027         }
12028       else if (unformat (line_input, "local %U",
12029                          unformat_ip6_address, &local6))
12030         {
12031           local_set = 1;
12032           ipv6_set = 1;
12033         }
12034       else if (unformat (line_input, "remote %U",
12035                          unformat_ip6_address, &remote6))
12036         {
12037           remote_set = 1;
12038           ipv6_set = 1;
12039         }
12040       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12041         ;
12042       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
12043         ;
12044       else if (unformat (line_input, "vni %d", &vni))
12045         vni_set = 1;
12046       else if (unformat (line_input, "next-ip4"))
12047         protocol = 1;
12048       else if (unformat (line_input, "next-ip6"))
12049         protocol = 2;
12050       else if (unformat (line_input, "next-ethernet"))
12051         protocol = 3;
12052       else if (unformat (line_input, "next-nsh"))
12053         protocol = 4;
12054       else
12055         {
12056           errmsg ("parse error '%U'", format_unformat_error, line_input);
12057           return -99;
12058         }
12059     }
12060
12061   if (local_set == 0)
12062     {
12063       errmsg ("tunnel local address not specified");
12064       return -99;
12065     }
12066   if (remote_set == 0)
12067     {
12068       errmsg ("tunnel remote address not specified");
12069       return -99;
12070     }
12071   if (ipv4_set && ipv6_set)
12072     {
12073       errmsg ("both IPv4 and IPv6 addresses specified");
12074       return -99;
12075     }
12076
12077   if (vni_set == 0)
12078     {
12079       errmsg ("vni not specified");
12080       return -99;
12081     }
12082
12083   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
12084
12085
12086   if (ipv6_set)
12087     {
12088       clib_memcpy (&mp->local, &local6, sizeof (local6));
12089       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
12090     }
12091   else
12092     {
12093       clib_memcpy (&mp->local, &local4, sizeof (local4));
12094       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
12095     }
12096
12097   mp->encap_vrf_id = ntohl (encap_vrf_id);
12098   mp->decap_vrf_id = ntohl (decap_vrf_id);
12099   mp->protocol = protocol;
12100   mp->vni = ntohl (vni);
12101   mp->is_add = is_add;
12102   mp->is_ipv6 = ipv6_set;
12103
12104   S (mp);
12105   W (ret);
12106   return ret;
12107 }
12108
12109 static void vl_api_vxlan_gpe_tunnel_details_t_handler
12110   (vl_api_vxlan_gpe_tunnel_details_t * mp)
12111 {
12112   vat_main_t *vam = &vat_main;
12113
12114   print (vam->ofp, "%11d%24U%24U%13d%12d%14d%14d",
12115          ntohl (mp->sw_if_index),
12116          format_ip46_address, &(mp->local[0]),
12117          format_ip46_address, &(mp->remote[0]),
12118          ntohl (mp->vni),
12119          ntohl (mp->protocol),
12120          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
12121 }
12122
12123 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
12124   (vl_api_vxlan_gpe_tunnel_details_t * mp)
12125 {
12126   vat_main_t *vam = &vat_main;
12127   vat_json_node_t *node = NULL;
12128   struct in_addr ip4;
12129   struct in6_addr ip6;
12130
12131   if (VAT_JSON_ARRAY != vam->json_tree.type)
12132     {
12133       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12134       vat_json_init_array (&vam->json_tree);
12135     }
12136   node = vat_json_array_add (&vam->json_tree);
12137
12138   vat_json_init_object (node);
12139   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12140   if (mp->is_ipv6)
12141     {
12142       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
12143       vat_json_object_add_ip6 (node, "local", ip6);
12144       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
12145       vat_json_object_add_ip6 (node, "remote", ip6);
12146     }
12147   else
12148     {
12149       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
12150       vat_json_object_add_ip4 (node, "local", ip4);
12151       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
12152       vat_json_object_add_ip4 (node, "remote", ip4);
12153     }
12154   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12155   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
12156   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12157   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
12158   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12159 }
12160
12161 static int
12162 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
12163 {
12164   unformat_input_t *i = vam->input;
12165   vl_api_vxlan_gpe_tunnel_dump_t *mp;
12166   vl_api_control_ping_t *mp_ping;
12167   u32 sw_if_index;
12168   u8 sw_if_index_set = 0;
12169   int ret;
12170
12171   /* Parse args required to build the message */
12172   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12173     {
12174       if (unformat (i, "sw_if_index %d", &sw_if_index))
12175         sw_if_index_set = 1;
12176       else
12177         break;
12178     }
12179
12180   if (sw_if_index_set == 0)
12181     {
12182       sw_if_index = ~0;
12183     }
12184
12185   if (!vam->json_output)
12186     {
12187       print (vam->ofp, "%11s%24s%24s%13s%15s%14s%14s",
12188              "sw_if_index", "local", "remote", "vni",
12189              "protocol", "encap_vrf_id", "decap_vrf_id");
12190     }
12191
12192   /* Get list of vxlan-tunnel interfaces */
12193   M (VXLAN_GPE_TUNNEL_DUMP, mp);
12194
12195   mp->sw_if_index = htonl (sw_if_index);
12196
12197   S (mp);
12198
12199   /* Use a control ping for synchronization */
12200   M (CONTROL_PING, mp_ping);
12201   S (mp_ping);
12202
12203   W (ret);
12204   return ret;
12205 }
12206
12207 u8 *
12208 format_l2_fib_mac_address (u8 * s, va_list * args)
12209 {
12210   u8 *a = va_arg (*args, u8 *);
12211
12212   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
12213                  a[2], a[3], a[4], a[5], a[6], a[7]);
12214 }
12215
12216 static void vl_api_l2_fib_table_details_t_handler
12217   (vl_api_l2_fib_table_details_t * mp)
12218 {
12219   vat_main_t *vam = &vat_main;
12220
12221   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
12222          "       %d       %d     %d",
12223          ntohl (mp->bd_id), format_l2_fib_mac_address, &mp->mac,
12224          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
12225          mp->bvi_mac);
12226 }
12227
12228 static void vl_api_l2_fib_table_details_t_handler_json
12229   (vl_api_l2_fib_table_details_t * mp)
12230 {
12231   vat_main_t *vam = &vat_main;
12232   vat_json_node_t *node = NULL;
12233
12234   if (VAT_JSON_ARRAY != vam->json_tree.type)
12235     {
12236       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12237       vat_json_init_array (&vam->json_tree);
12238     }
12239   node = vat_json_array_add (&vam->json_tree);
12240
12241   vat_json_init_object (node);
12242   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
12243   vat_json_object_add_uint (node, "mac", clib_net_to_host_u64 (mp->mac));
12244   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12245   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
12246   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
12247   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
12248 }
12249
12250 static int
12251 api_l2_fib_table_dump (vat_main_t * vam)
12252 {
12253   unformat_input_t *i = vam->input;
12254   vl_api_l2_fib_table_dump_t *mp;
12255   vl_api_control_ping_t *mp_ping;
12256   u32 bd_id;
12257   u8 bd_id_set = 0;
12258   int ret;
12259
12260   /* Parse args required to build the message */
12261   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12262     {
12263       if (unformat (i, "bd_id %d", &bd_id))
12264         bd_id_set = 1;
12265       else
12266         break;
12267     }
12268
12269   if (bd_id_set == 0)
12270     {
12271       errmsg ("missing bridge domain");
12272       return -99;
12273     }
12274
12275   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
12276
12277   /* Get list of l2 fib entries */
12278   M (L2_FIB_TABLE_DUMP, mp);
12279
12280   mp->bd_id = ntohl (bd_id);
12281   S (mp);
12282
12283   /* Use a control ping for synchronization */
12284   M (CONTROL_PING, mp_ping);
12285   S (mp_ping);
12286
12287   W (ret);
12288   return ret;
12289 }
12290
12291
12292 static int
12293 api_interface_name_renumber (vat_main_t * vam)
12294 {
12295   unformat_input_t *line_input = vam->input;
12296   vl_api_interface_name_renumber_t *mp;
12297   u32 sw_if_index = ~0;
12298   u32 new_show_dev_instance = ~0;
12299   int ret;
12300
12301   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12302     {
12303       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
12304                     &sw_if_index))
12305         ;
12306       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
12307         ;
12308       else if (unformat (line_input, "new_show_dev_instance %d",
12309                          &new_show_dev_instance))
12310         ;
12311       else
12312         break;
12313     }
12314
12315   if (sw_if_index == ~0)
12316     {
12317       errmsg ("missing interface name or sw_if_index");
12318       return -99;
12319     }
12320
12321   if (new_show_dev_instance == ~0)
12322     {
12323       errmsg ("missing new_show_dev_instance");
12324       return -99;
12325     }
12326
12327   M (INTERFACE_NAME_RENUMBER, mp);
12328
12329   mp->sw_if_index = ntohl (sw_if_index);
12330   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
12331
12332   S (mp);
12333   W (ret);
12334   return ret;
12335 }
12336
12337 static int
12338 api_want_ip4_arp_events (vat_main_t * vam)
12339 {
12340   unformat_input_t *line_input = vam->input;
12341   vl_api_want_ip4_arp_events_t *mp;
12342   ip4_address_t address;
12343   int address_set = 0;
12344   u32 enable_disable = 1;
12345   int ret;
12346
12347   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12348     {
12349       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
12350         address_set = 1;
12351       else if (unformat (line_input, "del"))
12352         enable_disable = 0;
12353       else
12354         break;
12355     }
12356
12357   if (address_set == 0)
12358     {
12359       errmsg ("missing addresses");
12360       return -99;
12361     }
12362
12363   M (WANT_IP4_ARP_EVENTS, mp);
12364   mp->enable_disable = enable_disable;
12365   mp->pid = htonl (getpid ());
12366   mp->address = address.as_u32;
12367
12368   S (mp);
12369   W (ret);
12370   return ret;
12371 }
12372
12373 static int
12374 api_want_ip6_nd_events (vat_main_t * vam)
12375 {
12376   unformat_input_t *line_input = vam->input;
12377   vl_api_want_ip6_nd_events_t *mp;
12378   ip6_address_t address;
12379   int address_set = 0;
12380   u32 enable_disable = 1;
12381   int ret;
12382
12383   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12384     {
12385       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
12386         address_set = 1;
12387       else if (unformat (line_input, "del"))
12388         enable_disable = 0;
12389       else
12390         break;
12391     }
12392
12393   if (address_set == 0)
12394     {
12395       errmsg ("missing addresses");
12396       return -99;
12397     }
12398
12399   M (WANT_IP6_ND_EVENTS, mp);
12400   mp->enable_disable = enable_disable;
12401   mp->pid = htonl (getpid ());
12402   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
12403
12404   S (mp);
12405   W (ret);
12406   return ret;
12407 }
12408
12409 static int
12410 api_input_acl_set_interface (vat_main_t * vam)
12411 {
12412   unformat_input_t *i = vam->input;
12413   vl_api_input_acl_set_interface_t *mp;
12414   u32 sw_if_index;
12415   int sw_if_index_set;
12416   u32 ip4_table_index = ~0;
12417   u32 ip6_table_index = ~0;
12418   u32 l2_table_index = ~0;
12419   u8 is_add = 1;
12420   int ret;
12421
12422   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12423     {
12424       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12425         sw_if_index_set = 1;
12426       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12427         sw_if_index_set = 1;
12428       else if (unformat (i, "del"))
12429         is_add = 0;
12430       else if (unformat (i, "ip4-table %d", &ip4_table_index))
12431         ;
12432       else if (unformat (i, "ip6-table %d", &ip6_table_index))
12433         ;
12434       else if (unformat (i, "l2-table %d", &l2_table_index))
12435         ;
12436       else
12437         {
12438           clib_warning ("parse error '%U'", format_unformat_error, i);
12439           return -99;
12440         }
12441     }
12442
12443   if (sw_if_index_set == 0)
12444     {
12445       errmsg ("missing interface name or sw_if_index");
12446       return -99;
12447     }
12448
12449   M (INPUT_ACL_SET_INTERFACE, mp);
12450
12451   mp->sw_if_index = ntohl (sw_if_index);
12452   mp->ip4_table_index = ntohl (ip4_table_index);
12453   mp->ip6_table_index = ntohl (ip6_table_index);
12454   mp->l2_table_index = ntohl (l2_table_index);
12455   mp->is_add = is_add;
12456
12457   S (mp);
12458   W (ret);
12459   return ret;
12460 }
12461
12462 static int
12463 api_ip_address_dump (vat_main_t * vam)
12464 {
12465   unformat_input_t *i = vam->input;
12466   vl_api_ip_address_dump_t *mp;
12467   vl_api_control_ping_t *mp_ping;
12468   u32 sw_if_index = ~0;
12469   u8 sw_if_index_set = 0;
12470   u8 ipv4_set = 0;
12471   u8 ipv6_set = 0;
12472   int ret;
12473
12474   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12475     {
12476       if (unformat (i, "sw_if_index %d", &sw_if_index))
12477         sw_if_index_set = 1;
12478       else
12479         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12480         sw_if_index_set = 1;
12481       else if (unformat (i, "ipv4"))
12482         ipv4_set = 1;
12483       else if (unformat (i, "ipv6"))
12484         ipv6_set = 1;
12485       else
12486         break;
12487     }
12488
12489   if (ipv4_set && ipv6_set)
12490     {
12491       errmsg ("ipv4 and ipv6 flags cannot be both set");
12492       return -99;
12493     }
12494
12495   if ((!ipv4_set) && (!ipv6_set))
12496     {
12497       errmsg ("no ipv4 nor ipv6 flag set");
12498       return -99;
12499     }
12500
12501   if (sw_if_index_set == 0)
12502     {
12503       errmsg ("missing interface name or sw_if_index");
12504       return -99;
12505     }
12506
12507   vam->current_sw_if_index = sw_if_index;
12508   vam->is_ipv6 = ipv6_set;
12509
12510   M (IP_ADDRESS_DUMP, mp);
12511   mp->sw_if_index = ntohl (sw_if_index);
12512   mp->is_ipv6 = ipv6_set;
12513   S (mp);
12514
12515   /* Use a control ping for synchronization */
12516   M (CONTROL_PING, mp_ping);
12517   S (mp_ping);
12518
12519   W (ret);
12520   return ret;
12521 }
12522
12523 static int
12524 api_ip_dump (vat_main_t * vam)
12525 {
12526   vl_api_ip_dump_t *mp;
12527   vl_api_control_ping_t *mp_ping;
12528   unformat_input_t *in = vam->input;
12529   int ipv4_set = 0;
12530   int ipv6_set = 0;
12531   int is_ipv6;
12532   int i;
12533   int ret;
12534
12535   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
12536     {
12537       if (unformat (in, "ipv4"))
12538         ipv4_set = 1;
12539       else if (unformat (in, "ipv6"))
12540         ipv6_set = 1;
12541       else
12542         break;
12543     }
12544
12545   if (ipv4_set && ipv6_set)
12546     {
12547       errmsg ("ipv4 and ipv6 flags cannot be both set");
12548       return -99;
12549     }
12550
12551   if ((!ipv4_set) && (!ipv6_set))
12552     {
12553       errmsg ("no ipv4 nor ipv6 flag set");
12554       return -99;
12555     }
12556
12557   is_ipv6 = ipv6_set;
12558   vam->is_ipv6 = is_ipv6;
12559
12560   /* free old data */
12561   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
12562     {
12563       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
12564     }
12565   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
12566
12567   M (IP_DUMP, mp);
12568   mp->is_ipv6 = ipv6_set;
12569   S (mp);
12570
12571   /* Use a control ping for synchronization */
12572   M (CONTROL_PING, mp_ping);
12573   S (mp_ping);
12574
12575   W (ret);
12576   return ret;
12577 }
12578
12579 static int
12580 api_ipsec_spd_add_del (vat_main_t * vam)
12581 {
12582   unformat_input_t *i = vam->input;
12583   vl_api_ipsec_spd_add_del_t *mp;
12584   u32 spd_id = ~0;
12585   u8 is_add = 1;
12586   int ret;
12587
12588   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12589     {
12590       if (unformat (i, "spd_id %d", &spd_id))
12591         ;
12592       else if (unformat (i, "del"))
12593         is_add = 0;
12594       else
12595         {
12596           clib_warning ("parse error '%U'", format_unformat_error, i);
12597           return -99;
12598         }
12599     }
12600   if (spd_id == ~0)
12601     {
12602       errmsg ("spd_id must be set");
12603       return -99;
12604     }
12605
12606   M (IPSEC_SPD_ADD_DEL, mp);
12607
12608   mp->spd_id = ntohl (spd_id);
12609   mp->is_add = is_add;
12610
12611   S (mp);
12612   W (ret);
12613   return ret;
12614 }
12615
12616 static int
12617 api_ipsec_interface_add_del_spd (vat_main_t * vam)
12618 {
12619   unformat_input_t *i = vam->input;
12620   vl_api_ipsec_interface_add_del_spd_t *mp;
12621   u32 sw_if_index;
12622   u8 sw_if_index_set = 0;
12623   u32 spd_id = (u32) ~ 0;
12624   u8 is_add = 1;
12625   int ret;
12626
12627   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12628     {
12629       if (unformat (i, "del"))
12630         is_add = 0;
12631       else if (unformat (i, "spd_id %d", &spd_id))
12632         ;
12633       else
12634         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12635         sw_if_index_set = 1;
12636       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12637         sw_if_index_set = 1;
12638       else
12639         {
12640           clib_warning ("parse error '%U'", format_unformat_error, i);
12641           return -99;
12642         }
12643
12644     }
12645
12646   if (spd_id == (u32) ~ 0)
12647     {
12648       errmsg ("spd_id must be set");
12649       return -99;
12650     }
12651
12652   if (sw_if_index_set == 0)
12653     {
12654       errmsg ("missing interface name or sw_if_index");
12655       return -99;
12656     }
12657
12658   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
12659
12660   mp->spd_id = ntohl (spd_id);
12661   mp->sw_if_index = ntohl (sw_if_index);
12662   mp->is_add = is_add;
12663
12664   S (mp);
12665   W (ret);
12666   return ret;
12667 }
12668
12669 static int
12670 api_ipsec_spd_add_del_entry (vat_main_t * vam)
12671 {
12672   unformat_input_t *i = vam->input;
12673   vl_api_ipsec_spd_add_del_entry_t *mp;
12674   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
12675   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
12676   i32 priority = 0;
12677   u32 rport_start = 0, rport_stop = (u32) ~ 0;
12678   u32 lport_start = 0, lport_stop = (u32) ~ 0;
12679   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
12680   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
12681   int ret;
12682
12683   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
12684   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
12685   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
12686   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
12687   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
12688   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
12689
12690   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12691     {
12692       if (unformat (i, "del"))
12693         is_add = 0;
12694       if (unformat (i, "outbound"))
12695         is_outbound = 1;
12696       if (unformat (i, "inbound"))
12697         is_outbound = 0;
12698       else if (unformat (i, "spd_id %d", &spd_id))
12699         ;
12700       else if (unformat (i, "sa_id %d", &sa_id))
12701         ;
12702       else if (unformat (i, "priority %d", &priority))
12703         ;
12704       else if (unformat (i, "protocol %d", &protocol))
12705         ;
12706       else if (unformat (i, "lport_start %d", &lport_start))
12707         ;
12708       else if (unformat (i, "lport_stop %d", &lport_stop))
12709         ;
12710       else if (unformat (i, "rport_start %d", &rport_start))
12711         ;
12712       else if (unformat (i, "rport_stop %d", &rport_stop))
12713         ;
12714       else
12715         if (unformat
12716             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
12717         {
12718           is_ipv6 = 0;
12719           is_ip_any = 0;
12720         }
12721       else
12722         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
12723         {
12724           is_ipv6 = 0;
12725           is_ip_any = 0;
12726         }
12727       else
12728         if (unformat
12729             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
12730         {
12731           is_ipv6 = 0;
12732           is_ip_any = 0;
12733         }
12734       else
12735         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
12736         {
12737           is_ipv6 = 0;
12738           is_ip_any = 0;
12739         }
12740       else
12741         if (unformat
12742             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
12743         {
12744           is_ipv6 = 1;
12745           is_ip_any = 0;
12746         }
12747       else
12748         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
12749         {
12750           is_ipv6 = 1;
12751           is_ip_any = 0;
12752         }
12753       else
12754         if (unformat
12755             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
12756         {
12757           is_ipv6 = 1;
12758           is_ip_any = 0;
12759         }
12760       else
12761         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
12762         {
12763           is_ipv6 = 1;
12764           is_ip_any = 0;
12765         }
12766       else
12767         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
12768         {
12769           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
12770             {
12771               clib_warning ("unsupported action: 'resolve'");
12772               return -99;
12773             }
12774         }
12775       else
12776         {
12777           clib_warning ("parse error '%U'", format_unformat_error, i);
12778           return -99;
12779         }
12780
12781     }
12782
12783   M (IPSEC_SPD_ADD_DEL_ENTRY, mp);
12784
12785   mp->spd_id = ntohl (spd_id);
12786   mp->priority = ntohl (priority);
12787   mp->is_outbound = is_outbound;
12788
12789   mp->is_ipv6 = is_ipv6;
12790   if (is_ipv6 || is_ip_any)
12791     {
12792       clib_memcpy (mp->remote_address_start, &raddr6_start,
12793                    sizeof (ip6_address_t));
12794       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
12795                    sizeof (ip6_address_t));
12796       clib_memcpy (mp->local_address_start, &laddr6_start,
12797                    sizeof (ip6_address_t));
12798       clib_memcpy (mp->local_address_stop, &laddr6_stop,
12799                    sizeof (ip6_address_t));
12800     }
12801   else
12802     {
12803       clib_memcpy (mp->remote_address_start, &raddr4_start,
12804                    sizeof (ip4_address_t));
12805       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
12806                    sizeof (ip4_address_t));
12807       clib_memcpy (mp->local_address_start, &laddr4_start,
12808                    sizeof (ip4_address_t));
12809       clib_memcpy (mp->local_address_stop, &laddr4_stop,
12810                    sizeof (ip4_address_t));
12811     }
12812   mp->protocol = (u8) protocol;
12813   mp->local_port_start = ntohs ((u16) lport_start);
12814   mp->local_port_stop = ntohs ((u16) lport_stop);
12815   mp->remote_port_start = ntohs ((u16) rport_start);
12816   mp->remote_port_stop = ntohs ((u16) rport_stop);
12817   mp->policy = (u8) policy;
12818   mp->sa_id = ntohl (sa_id);
12819   mp->is_add = is_add;
12820   mp->is_ip_any = is_ip_any;
12821   S (mp);
12822   W (ret);
12823   return ret;
12824 }
12825
12826 static int
12827 api_ipsec_sad_add_del_entry (vat_main_t * vam)
12828 {
12829   unformat_input_t *i = vam->input;
12830   vl_api_ipsec_sad_add_del_entry_t *mp;
12831   u32 sad_id = 0, spi = 0;
12832   u8 *ck = 0, *ik = 0;
12833   u8 is_add = 1;
12834
12835   u8 protocol = IPSEC_PROTOCOL_AH;
12836   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
12837   u32 crypto_alg = 0, integ_alg = 0;
12838   ip4_address_t tun_src4;
12839   ip4_address_t tun_dst4;
12840   ip6_address_t tun_src6;
12841   ip6_address_t tun_dst6;
12842   int ret;
12843
12844   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12845     {
12846       if (unformat (i, "del"))
12847         is_add = 0;
12848       else if (unformat (i, "sad_id %d", &sad_id))
12849         ;
12850       else if (unformat (i, "spi %d", &spi))
12851         ;
12852       else if (unformat (i, "esp"))
12853         protocol = IPSEC_PROTOCOL_ESP;
12854       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
12855         {
12856           is_tunnel = 1;
12857           is_tunnel_ipv6 = 0;
12858         }
12859       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
12860         {
12861           is_tunnel = 1;
12862           is_tunnel_ipv6 = 0;
12863         }
12864       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
12865         {
12866           is_tunnel = 1;
12867           is_tunnel_ipv6 = 1;
12868         }
12869       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
12870         {
12871           is_tunnel = 1;
12872           is_tunnel_ipv6 = 1;
12873         }
12874       else
12875         if (unformat
12876             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
12877         {
12878           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
12879               crypto_alg >= IPSEC_CRYPTO_N_ALG)
12880             {
12881               clib_warning ("unsupported crypto-alg: '%U'",
12882                             format_ipsec_crypto_alg, crypto_alg);
12883               return -99;
12884             }
12885         }
12886       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
12887         ;
12888       else
12889         if (unformat
12890             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
12891         {
12892           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
12893               integ_alg >= IPSEC_INTEG_N_ALG)
12894             {
12895               clib_warning ("unsupported integ-alg: '%U'",
12896                             format_ipsec_integ_alg, integ_alg);
12897               return -99;
12898             }
12899         }
12900       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
12901         ;
12902       else
12903         {
12904           clib_warning ("parse error '%U'", format_unformat_error, i);
12905           return -99;
12906         }
12907
12908     }
12909
12910   M (IPSEC_SAD_ADD_DEL_ENTRY, mp);
12911
12912   mp->sad_id = ntohl (sad_id);
12913   mp->is_add = is_add;
12914   mp->protocol = protocol;
12915   mp->spi = ntohl (spi);
12916   mp->is_tunnel = is_tunnel;
12917   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
12918   mp->crypto_algorithm = crypto_alg;
12919   mp->integrity_algorithm = integ_alg;
12920   mp->crypto_key_length = vec_len (ck);
12921   mp->integrity_key_length = vec_len (ik);
12922
12923   if (mp->crypto_key_length > sizeof (mp->crypto_key))
12924     mp->crypto_key_length = sizeof (mp->crypto_key);
12925
12926   if (mp->integrity_key_length > sizeof (mp->integrity_key))
12927     mp->integrity_key_length = sizeof (mp->integrity_key);
12928
12929   if (ck)
12930     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
12931   if (ik)
12932     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
12933
12934   if (is_tunnel)
12935     {
12936       if (is_tunnel_ipv6)
12937         {
12938           clib_memcpy (mp->tunnel_src_address, &tun_src6,
12939                        sizeof (ip6_address_t));
12940           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
12941                        sizeof (ip6_address_t));
12942         }
12943       else
12944         {
12945           clib_memcpy (mp->tunnel_src_address, &tun_src4,
12946                        sizeof (ip4_address_t));
12947           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
12948                        sizeof (ip4_address_t));
12949         }
12950     }
12951
12952   S (mp);
12953   W (ret);
12954   return ret;
12955 }
12956
12957 static int
12958 api_ipsec_sa_set_key (vat_main_t * vam)
12959 {
12960   unformat_input_t *i = vam->input;
12961   vl_api_ipsec_sa_set_key_t *mp;
12962   u32 sa_id;
12963   u8 *ck = 0, *ik = 0;
12964   int ret;
12965
12966   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12967     {
12968       if (unformat (i, "sa_id %d", &sa_id))
12969         ;
12970       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
12971         ;
12972       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
12973         ;
12974       else
12975         {
12976           clib_warning ("parse error '%U'", format_unformat_error, i);
12977           return -99;
12978         }
12979     }
12980
12981   M (IPSEC_SA_SET_KEY, mp);
12982
12983   mp->sa_id = ntohl (sa_id);
12984   mp->crypto_key_length = vec_len (ck);
12985   mp->integrity_key_length = vec_len (ik);
12986
12987   if (mp->crypto_key_length > sizeof (mp->crypto_key))
12988     mp->crypto_key_length = sizeof (mp->crypto_key);
12989
12990   if (mp->integrity_key_length > sizeof (mp->integrity_key))
12991     mp->integrity_key_length = sizeof (mp->integrity_key);
12992
12993   if (ck)
12994     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
12995   if (ik)
12996     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
12997
12998   S (mp);
12999   W (ret);
13000   return ret;
13001 }
13002
13003 static int
13004 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
13005 {
13006   unformat_input_t *i = vam->input;
13007   vl_api_ipsec_tunnel_if_add_del_t *mp;
13008   u32 local_spi = 0, remote_spi = 0;
13009   u32 crypto_alg = 0, integ_alg = 0;
13010   u8 *lck = NULL, *rck = NULL;
13011   u8 *lik = NULL, *rik = NULL;
13012   ip4_address_t local_ip = { {0} };
13013   ip4_address_t remote_ip = { {0} };
13014   u8 is_add = 1;
13015   u8 esn = 0;
13016   u8 anti_replay = 0;
13017   int ret;
13018
13019   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13020     {
13021       if (unformat (i, "del"))
13022         is_add = 0;
13023       else if (unformat (i, "esn"))
13024         esn = 1;
13025       else if (unformat (i, "anti_replay"))
13026         anti_replay = 1;
13027       else if (unformat (i, "local_spi %d", &local_spi))
13028         ;
13029       else if (unformat (i, "remote_spi %d", &remote_spi))
13030         ;
13031       else if (unformat (i, "local_ip %U", unformat_ip4_address, &local_ip))
13032         ;
13033       else if (unformat (i, "remote_ip %U", unformat_ip4_address, &remote_ip))
13034         ;
13035       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
13036         ;
13037       else
13038         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
13039         ;
13040       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
13041         ;
13042       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
13043         ;
13044       else
13045         if (unformat
13046             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
13047         {
13048           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
13049               crypto_alg >= IPSEC_CRYPTO_N_ALG)
13050             {
13051               errmsg ("unsupported crypto-alg: '%U'\n",
13052                       format_ipsec_crypto_alg, crypto_alg);
13053               return -99;
13054             }
13055         }
13056       else
13057         if (unformat
13058             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
13059         {
13060           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
13061               integ_alg >= IPSEC_INTEG_N_ALG)
13062             {
13063               errmsg ("unsupported integ-alg: '%U'\n",
13064                       format_ipsec_integ_alg, integ_alg);
13065               return -99;
13066             }
13067         }
13068       else
13069         {
13070           errmsg ("parse error '%U'\n", format_unformat_error, i);
13071           return -99;
13072         }
13073     }
13074
13075   M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
13076
13077   mp->is_add = is_add;
13078   mp->esn = esn;
13079   mp->anti_replay = anti_replay;
13080
13081   clib_memcpy (mp->local_ip, &local_ip, sizeof (ip4_address_t));
13082   clib_memcpy (mp->remote_ip, &remote_ip, sizeof (ip4_address_t));
13083
13084   mp->local_spi = htonl (local_spi);
13085   mp->remote_spi = htonl (remote_spi);
13086   mp->crypto_alg = (u8) crypto_alg;
13087
13088   mp->local_crypto_key_len = 0;
13089   if (lck)
13090     {
13091       mp->local_crypto_key_len = vec_len (lck);
13092       if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
13093         mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
13094       clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
13095     }
13096
13097   mp->remote_crypto_key_len = 0;
13098   if (rck)
13099     {
13100       mp->remote_crypto_key_len = vec_len (rck);
13101       if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
13102         mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
13103       clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
13104     }
13105
13106   mp->integ_alg = (u8) integ_alg;
13107
13108   mp->local_integ_key_len = 0;
13109   if (lik)
13110     {
13111       mp->local_integ_key_len = vec_len (lik);
13112       if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
13113         mp->local_integ_key_len = sizeof (mp->local_integ_key);
13114       clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
13115     }
13116
13117   mp->remote_integ_key_len = 0;
13118   if (rik)
13119     {
13120       mp->remote_integ_key_len = vec_len (rik);
13121       if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
13122         mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
13123       clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
13124     }
13125
13126   S (mp);
13127   W (ret);
13128   return ret;
13129 }
13130
13131 static int
13132 api_ikev2_profile_add_del (vat_main_t * vam)
13133 {
13134   unformat_input_t *i = vam->input;
13135   vl_api_ikev2_profile_add_del_t *mp;
13136   u8 is_add = 1;
13137   u8 *name = 0;
13138   int ret;
13139
13140   const char *valid_chars = "a-zA-Z0-9_";
13141
13142   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13143     {
13144       if (unformat (i, "del"))
13145         is_add = 0;
13146       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
13147         vec_add1 (name, 0);
13148       else
13149         {
13150           errmsg ("parse error '%U'", format_unformat_error, i);
13151           return -99;
13152         }
13153     }
13154
13155   if (!vec_len (name))
13156     {
13157       errmsg ("profile name must be specified");
13158       return -99;
13159     }
13160
13161   if (vec_len (name) > 64)
13162     {
13163       errmsg ("profile name too long");
13164       return -99;
13165     }
13166
13167   M (IKEV2_PROFILE_ADD_DEL, mp);
13168
13169   clib_memcpy (mp->name, name, vec_len (name));
13170   mp->is_add = is_add;
13171   vec_free (name);
13172
13173   S (mp);
13174   W (ret);
13175   return ret;
13176 }
13177
13178 static int
13179 api_ikev2_profile_set_auth (vat_main_t * vam)
13180 {
13181   unformat_input_t *i = vam->input;
13182   vl_api_ikev2_profile_set_auth_t *mp;
13183   u8 *name = 0;
13184   u8 *data = 0;
13185   u32 auth_method = 0;
13186   u8 is_hex = 0;
13187   int ret;
13188
13189   const char *valid_chars = "a-zA-Z0-9_";
13190
13191   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13192     {
13193       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
13194         vec_add1 (name, 0);
13195       else if (unformat (i, "auth_method %U",
13196                          unformat_ikev2_auth_method, &auth_method))
13197         ;
13198       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
13199         is_hex = 1;
13200       else if (unformat (i, "auth_data %v", &data))
13201         ;
13202       else
13203         {
13204           errmsg ("parse error '%U'", format_unformat_error, i);
13205           return -99;
13206         }
13207     }
13208
13209   if (!vec_len (name))
13210     {
13211       errmsg ("profile name must be specified");
13212       return -99;
13213     }
13214
13215   if (vec_len (name) > 64)
13216     {
13217       errmsg ("profile name too long");
13218       return -99;
13219     }
13220
13221   if (!vec_len (data))
13222     {
13223       errmsg ("auth_data must be specified");
13224       return -99;
13225     }
13226
13227   if (!auth_method)
13228     {
13229       errmsg ("auth_method must be specified");
13230       return -99;
13231     }
13232
13233   M (IKEV2_PROFILE_SET_AUTH, mp);
13234
13235   mp->is_hex = is_hex;
13236   mp->auth_method = (u8) auth_method;
13237   mp->data_len = vec_len (data);
13238   clib_memcpy (mp->name, name, vec_len (name));
13239   clib_memcpy (mp->data, data, vec_len (data));
13240   vec_free (name);
13241   vec_free (data);
13242
13243   S (mp);
13244   W (ret);
13245   return ret;
13246 }
13247
13248 static int
13249 api_ikev2_profile_set_id (vat_main_t * vam)
13250 {
13251   unformat_input_t *i = vam->input;
13252   vl_api_ikev2_profile_set_id_t *mp;
13253   u8 *name = 0;
13254   u8 *data = 0;
13255   u8 is_local = 0;
13256   u32 id_type = 0;
13257   ip4_address_t ip4;
13258   int ret;
13259
13260   const char *valid_chars = "a-zA-Z0-9_";
13261
13262   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13263     {
13264       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
13265         vec_add1 (name, 0);
13266       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
13267         ;
13268       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
13269         {
13270           data = vec_new (u8, 4);
13271           clib_memcpy (data, ip4.as_u8, 4);
13272         }
13273       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
13274         ;
13275       else if (unformat (i, "id_data %v", &data))
13276         ;
13277       else if (unformat (i, "local"))
13278         is_local = 1;
13279       else if (unformat (i, "remote"))
13280         is_local = 0;
13281       else
13282         {
13283           errmsg ("parse error '%U'", format_unformat_error, i);
13284           return -99;
13285         }
13286     }
13287
13288   if (!vec_len (name))
13289     {
13290       errmsg ("profile name must be specified");
13291       return -99;
13292     }
13293
13294   if (vec_len (name) > 64)
13295     {
13296       errmsg ("profile name too long");
13297       return -99;
13298     }
13299
13300   if (!vec_len (data))
13301     {
13302       errmsg ("id_data must be specified");
13303       return -99;
13304     }
13305
13306   if (!id_type)
13307     {
13308       errmsg ("id_type must be specified");
13309       return -99;
13310     }
13311
13312   M (IKEV2_PROFILE_SET_ID, mp);
13313
13314   mp->is_local = is_local;
13315   mp->id_type = (u8) id_type;
13316   mp->data_len = vec_len (data);
13317   clib_memcpy (mp->name, name, vec_len (name));
13318   clib_memcpy (mp->data, data, vec_len (data));
13319   vec_free (name);
13320   vec_free (data);
13321
13322   S (mp);
13323   W (ret);
13324   return ret;
13325 }
13326
13327 static int
13328 api_ikev2_profile_set_ts (vat_main_t * vam)
13329 {
13330   unformat_input_t *i = vam->input;
13331   vl_api_ikev2_profile_set_ts_t *mp;
13332   u8 *name = 0;
13333   u8 is_local = 0;
13334   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
13335   ip4_address_t start_addr, end_addr;
13336
13337   const char *valid_chars = "a-zA-Z0-9_";
13338   int ret;
13339
13340   start_addr.as_u32 = 0;
13341   end_addr.as_u32 = (u32) ~ 0;
13342
13343   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13344     {
13345       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
13346         vec_add1 (name, 0);
13347       else if (unformat (i, "protocol %d", &proto))
13348         ;
13349       else if (unformat (i, "start_port %d", &start_port))
13350         ;
13351       else if (unformat (i, "end_port %d", &end_port))
13352         ;
13353       else
13354         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
13355         ;
13356       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
13357         ;
13358       else if (unformat (i, "local"))
13359         is_local = 1;
13360       else if (unformat (i, "remote"))
13361         is_local = 0;
13362       else
13363         {
13364           errmsg ("parse error '%U'", format_unformat_error, i);
13365           return -99;
13366         }
13367     }
13368
13369   if (!vec_len (name))
13370     {
13371       errmsg ("profile name must be specified");
13372       return -99;
13373     }
13374
13375   if (vec_len (name) > 64)
13376     {
13377       errmsg ("profile name too long");
13378       return -99;
13379     }
13380
13381   M (IKEV2_PROFILE_SET_TS, mp);
13382
13383   mp->is_local = is_local;
13384   mp->proto = (u8) proto;
13385   mp->start_port = (u16) start_port;
13386   mp->end_port = (u16) end_port;
13387   mp->start_addr = start_addr.as_u32;
13388   mp->end_addr = end_addr.as_u32;
13389   clib_memcpy (mp->name, name, vec_len (name));
13390   vec_free (name);
13391
13392   S (mp);
13393   W (ret);
13394   return ret;
13395 }
13396
13397 static int
13398 api_ikev2_set_local_key (vat_main_t * vam)
13399 {
13400   unformat_input_t *i = vam->input;
13401   vl_api_ikev2_set_local_key_t *mp;
13402   u8 *file = 0;
13403   int ret;
13404
13405   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13406     {
13407       if (unformat (i, "file %v", &file))
13408         vec_add1 (file, 0);
13409       else
13410         {
13411           errmsg ("parse error '%U'", format_unformat_error, i);
13412           return -99;
13413         }
13414     }
13415
13416   if (!vec_len (file))
13417     {
13418       errmsg ("RSA key file must be specified");
13419       return -99;
13420     }
13421
13422   if (vec_len (file) > 256)
13423     {
13424       errmsg ("file name too long");
13425       return -99;
13426     }
13427
13428   M (IKEV2_SET_LOCAL_KEY, mp);
13429
13430   clib_memcpy (mp->key_file, file, vec_len (file));
13431   vec_free (file);
13432
13433   S (mp);
13434   W (ret);
13435   return ret;
13436 }
13437
13438 static int
13439 api_ikev2_set_responder (vat_main_t * vam)
13440 {
13441   unformat_input_t *i = vam->input;
13442   vl_api_ikev2_set_responder_t *mp;
13443   int ret;
13444   u8 *name = 0;
13445   u32 sw_if_index = ~0;
13446   ip4_address_t address;
13447
13448   const char *valid_chars = "a-zA-Z0-9_";
13449
13450   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13451     {
13452       if (unformat
13453           (i, "%U interface %d address %U", unformat_token, valid_chars,
13454            &name, &sw_if_index, unformat_ip4_address, &address))
13455         vec_add1 (name, 0);
13456       else
13457         {
13458           errmsg ("parse error '%U'", format_unformat_error, i);
13459           return -99;
13460         }
13461     }
13462
13463   if (!vec_len (name))
13464     {
13465       errmsg ("profile name must be specified");
13466       return -99;
13467     }
13468
13469   if (vec_len (name) > 64)
13470     {
13471       errmsg ("profile name too long");
13472       return -99;
13473     }
13474
13475   M (IKEV2_SET_RESPONDER, mp);
13476
13477   clib_memcpy (mp->name, name, vec_len (name));
13478   vec_free (name);
13479
13480   mp->sw_if_index = sw_if_index;
13481   clib_memcpy (mp->address, &address, sizeof (address));
13482
13483   S (mp);
13484   W (ret);
13485   return ret;
13486 }
13487
13488 static int
13489 api_ikev2_set_ike_transforms (vat_main_t * vam)
13490 {
13491   unformat_input_t *i = vam->input;
13492   vl_api_ikev2_set_ike_transforms_t *mp;
13493   int ret;
13494   u8 *name = 0;
13495   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
13496
13497   const char *valid_chars = "a-zA-Z0-9_";
13498
13499   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13500     {
13501       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
13502                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
13503         vec_add1 (name, 0);
13504       else
13505         {
13506           errmsg ("parse error '%U'", format_unformat_error, i);
13507           return -99;
13508         }
13509     }
13510
13511   if (!vec_len (name))
13512     {
13513       errmsg ("profile name must be specified");
13514       return -99;
13515     }
13516
13517   if (vec_len (name) > 64)
13518     {
13519       errmsg ("profile name too long");
13520       return -99;
13521     }
13522
13523   M (IKEV2_SET_IKE_TRANSFORMS, mp);
13524
13525   clib_memcpy (mp->name, name, vec_len (name));
13526   vec_free (name);
13527   mp->crypto_alg = crypto_alg;
13528   mp->crypto_key_size = crypto_key_size;
13529   mp->integ_alg = integ_alg;
13530   mp->dh_group = dh_group;
13531
13532   S (mp);
13533   W (ret);
13534   return ret;
13535 }
13536
13537
13538 static int
13539 api_ikev2_set_esp_transforms (vat_main_t * vam)
13540 {
13541   unformat_input_t *i = vam->input;
13542   vl_api_ikev2_set_esp_transforms_t *mp;
13543   int ret;
13544   u8 *name = 0;
13545   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
13546
13547   const char *valid_chars = "a-zA-Z0-9_";
13548
13549   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13550     {
13551       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
13552                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
13553         vec_add1 (name, 0);
13554       else
13555         {
13556           errmsg ("parse error '%U'", format_unformat_error, i);
13557           return -99;
13558         }
13559     }
13560
13561   if (!vec_len (name))
13562     {
13563       errmsg ("profile name must be specified");
13564       return -99;
13565     }
13566
13567   if (vec_len (name) > 64)
13568     {
13569       errmsg ("profile name too long");
13570       return -99;
13571     }
13572
13573   M (IKEV2_SET_ESP_TRANSFORMS, mp);
13574
13575   clib_memcpy (mp->name, name, vec_len (name));
13576   vec_free (name);
13577   mp->crypto_alg = crypto_alg;
13578   mp->crypto_key_size = crypto_key_size;
13579   mp->integ_alg = integ_alg;
13580   mp->dh_group = dh_group;
13581
13582   S (mp);
13583   W (ret);
13584   return ret;
13585 }
13586
13587 static int
13588 api_ikev2_set_sa_lifetime (vat_main_t * vam)
13589 {
13590   unformat_input_t *i = vam->input;
13591   vl_api_ikev2_set_sa_lifetime_t *mp;
13592   int ret;
13593   u8 *name = 0;
13594   u64 lifetime, lifetime_maxdata;
13595   u32 lifetime_jitter, handover;
13596
13597   const char *valid_chars = "a-zA-Z0-9_";
13598
13599   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13600     {
13601       if (unformat (i, "%U %lu %u %u %lu", unformat_token, valid_chars, &name,
13602                     &lifetime, &lifetime_jitter, &handover,
13603                     &lifetime_maxdata))
13604         vec_add1 (name, 0);
13605       else
13606         {
13607           errmsg ("parse error '%U'", format_unformat_error, i);
13608           return -99;
13609         }
13610     }
13611
13612   if (!vec_len (name))
13613     {
13614       errmsg ("profile name must be specified");
13615       return -99;
13616     }
13617
13618   if (vec_len (name) > 64)
13619     {
13620       errmsg ("profile name too long");
13621       return -99;
13622     }
13623
13624   M (IKEV2_SET_SA_LIFETIME, mp);
13625
13626   clib_memcpy (mp->name, name, vec_len (name));
13627   vec_free (name);
13628   mp->lifetime = lifetime;
13629   mp->lifetime_jitter = lifetime_jitter;
13630   mp->handover = handover;
13631   mp->lifetime_maxdata = lifetime_maxdata;
13632
13633   S (mp);
13634   W (ret);
13635   return ret;
13636 }
13637
13638 static int
13639 api_ikev2_initiate_sa_init (vat_main_t * vam)
13640 {
13641   unformat_input_t *i = vam->input;
13642   vl_api_ikev2_initiate_sa_init_t *mp;
13643   int ret;
13644   u8 *name = 0;
13645
13646   const char *valid_chars = "a-zA-Z0-9_";
13647
13648   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13649     {
13650       if (unformat (i, "%U", unformat_token, valid_chars, &name))
13651         vec_add1 (name, 0);
13652       else
13653         {
13654           errmsg ("parse error '%U'", format_unformat_error, i);
13655           return -99;
13656         }
13657     }
13658
13659   if (!vec_len (name))
13660     {
13661       errmsg ("profile name must be specified");
13662       return -99;
13663     }
13664
13665   if (vec_len (name) > 64)
13666     {
13667       errmsg ("profile name too long");
13668       return -99;
13669     }
13670
13671   M (IKEV2_INITIATE_SA_INIT, mp);
13672
13673   clib_memcpy (mp->name, name, vec_len (name));
13674   vec_free (name);
13675
13676   S (mp);
13677   W (ret);
13678   return ret;
13679 }
13680
13681 static int
13682 api_ikev2_initiate_del_ike_sa (vat_main_t * vam)
13683 {
13684   unformat_input_t *i = vam->input;
13685   vl_api_ikev2_initiate_del_ike_sa_t *mp;
13686   int ret;
13687   u64 ispi;
13688
13689
13690   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13691     {
13692       if (unformat (i, "%lx", &ispi))
13693         ;
13694       else
13695         {
13696           errmsg ("parse error '%U'", format_unformat_error, i);
13697           return -99;
13698         }
13699     }
13700
13701   M (IKEV2_INITIATE_DEL_IKE_SA, mp);
13702
13703   mp->ispi = ispi;
13704
13705   S (mp);
13706   W (ret);
13707   return ret;
13708 }
13709
13710 static int
13711 api_ikev2_initiate_del_child_sa (vat_main_t * vam)
13712 {
13713   unformat_input_t *i = vam->input;
13714   vl_api_ikev2_initiate_del_child_sa_t *mp;
13715   int ret;
13716   u32 ispi;
13717
13718
13719   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13720     {
13721       if (unformat (i, "%x", &ispi))
13722         ;
13723       else
13724         {
13725           errmsg ("parse error '%U'", format_unformat_error, i);
13726           return -99;
13727         }
13728     }
13729
13730   M (IKEV2_INITIATE_DEL_CHILD_SA, mp);
13731
13732   mp->ispi = ispi;
13733
13734   S (mp);
13735   W (ret);
13736   return ret;
13737 }
13738
13739 static int
13740 api_ikev2_initiate_rekey_child_sa (vat_main_t * vam)
13741 {
13742   unformat_input_t *i = vam->input;
13743   vl_api_ikev2_initiate_rekey_child_sa_t *mp;
13744   int ret;
13745   u32 ispi;
13746
13747
13748   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13749     {
13750       if (unformat (i, "%x", &ispi))
13751         ;
13752       else
13753         {
13754           errmsg ("parse error '%U'", format_unformat_error, i);
13755           return -99;
13756         }
13757     }
13758
13759   M (IKEV2_INITIATE_REKEY_CHILD_SA, mp);
13760
13761   mp->ispi = ispi;
13762
13763   S (mp);
13764   W (ret);
13765   return ret;
13766 }
13767
13768 /*
13769  * MAP
13770  */
13771 static int
13772 api_map_add_domain (vat_main_t * vam)
13773 {
13774   unformat_input_t *i = vam->input;
13775   vl_api_map_add_domain_t *mp;
13776
13777   ip4_address_t ip4_prefix;
13778   ip6_address_t ip6_prefix;
13779   ip6_address_t ip6_src;
13780   u32 num_m_args = 0;
13781   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
13782     0, psid_length = 0;
13783   u8 is_translation = 0;
13784   u32 mtu = 0;
13785   u32 ip6_src_len = 128;
13786   int ret;
13787
13788   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13789     {
13790       if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
13791                     &ip4_prefix, &ip4_prefix_len))
13792         num_m_args++;
13793       else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
13794                          &ip6_prefix, &ip6_prefix_len))
13795         num_m_args++;
13796       else
13797         if (unformat
13798             (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
13799              &ip6_src_len))
13800         num_m_args++;
13801       else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
13802         num_m_args++;
13803       else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
13804         num_m_args++;
13805       else if (unformat (i, "psid-offset %d", &psid_offset))
13806         num_m_args++;
13807       else if (unformat (i, "psid-len %d", &psid_length))
13808         num_m_args++;
13809       else if (unformat (i, "mtu %d", &mtu))
13810         num_m_args++;
13811       else if (unformat (i, "map-t"))
13812         is_translation = 1;
13813       else
13814         {
13815           clib_warning ("parse error '%U'", format_unformat_error, i);
13816           return -99;
13817         }
13818     }
13819
13820   if (num_m_args < 3)
13821     {
13822       errmsg ("mandatory argument(s) missing");
13823       return -99;
13824     }
13825
13826   /* Construct the API message */
13827   M (MAP_ADD_DOMAIN, mp);
13828
13829   clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
13830   mp->ip4_prefix_len = ip4_prefix_len;
13831
13832   clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
13833   mp->ip6_prefix_len = ip6_prefix_len;
13834
13835   clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
13836   mp->ip6_src_prefix_len = ip6_src_len;
13837
13838   mp->ea_bits_len = ea_bits_len;
13839   mp->psid_offset = psid_offset;
13840   mp->psid_length = psid_length;
13841   mp->is_translation = is_translation;
13842   mp->mtu = htons (mtu);
13843
13844   /* send it... */
13845   S (mp);
13846
13847   /* Wait for a reply, return good/bad news  */
13848   W (ret);
13849   return ret;
13850 }
13851
13852 static int
13853 api_map_del_domain (vat_main_t * vam)
13854 {
13855   unformat_input_t *i = vam->input;
13856   vl_api_map_del_domain_t *mp;
13857
13858   u32 num_m_args = 0;
13859   u32 index;
13860   int ret;
13861
13862   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13863     {
13864       if (unformat (i, "index %d", &index))
13865         num_m_args++;
13866       else
13867         {
13868           clib_warning ("parse error '%U'", format_unformat_error, i);
13869           return -99;
13870         }
13871     }
13872
13873   if (num_m_args != 1)
13874     {
13875       errmsg ("mandatory argument(s) missing");
13876       return -99;
13877     }
13878
13879   /* Construct the API message */
13880   M (MAP_DEL_DOMAIN, mp);
13881
13882   mp->index = ntohl (index);
13883
13884   /* send it... */
13885   S (mp);
13886
13887   /* Wait for a reply, return good/bad news  */
13888   W (ret);
13889   return ret;
13890 }
13891
13892 static int
13893 api_map_add_del_rule (vat_main_t * vam)
13894 {
13895   unformat_input_t *i = vam->input;
13896   vl_api_map_add_del_rule_t *mp;
13897   u8 is_add = 1;
13898   ip6_address_t ip6_dst;
13899   u32 num_m_args = 0, index, psid = 0;
13900   int ret;
13901
13902   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13903     {
13904       if (unformat (i, "index %d", &index))
13905         num_m_args++;
13906       else if (unformat (i, "psid %d", &psid))
13907         num_m_args++;
13908       else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
13909         num_m_args++;
13910       else if (unformat (i, "del"))
13911         {
13912           is_add = 0;
13913         }
13914       else
13915         {
13916           clib_warning ("parse error '%U'", format_unformat_error, i);
13917           return -99;
13918         }
13919     }
13920
13921   /* Construct the API message */
13922   M (MAP_ADD_DEL_RULE, mp);
13923
13924   mp->index = ntohl (index);
13925   mp->is_add = is_add;
13926   clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
13927   mp->psid = ntohs (psid);
13928
13929   /* send it... */
13930   S (mp);
13931
13932   /* Wait for a reply, return good/bad news  */
13933   W (ret);
13934   return ret;
13935 }
13936
13937 static int
13938 api_map_domain_dump (vat_main_t * vam)
13939 {
13940   vl_api_map_domain_dump_t *mp;
13941   vl_api_control_ping_t *mp_ping;
13942   int ret;
13943
13944   /* Construct the API message */
13945   M (MAP_DOMAIN_DUMP, mp);
13946
13947   /* send it... */
13948   S (mp);
13949
13950   /* Use a control ping for synchronization */
13951   M (CONTROL_PING, mp_ping);
13952   S (mp_ping);
13953
13954   W (ret);
13955   return ret;
13956 }
13957
13958 static int
13959 api_map_rule_dump (vat_main_t * vam)
13960 {
13961   unformat_input_t *i = vam->input;
13962   vl_api_map_rule_dump_t *mp;
13963   vl_api_control_ping_t *mp_ping;
13964   u32 domain_index = ~0;
13965   int ret;
13966
13967   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13968     {
13969       if (unformat (i, "index %u", &domain_index))
13970         ;
13971       else
13972         break;
13973     }
13974
13975   if (domain_index == ~0)
13976     {
13977       clib_warning ("parse error: domain index expected");
13978       return -99;
13979     }
13980
13981   /* Construct the API message */
13982   M (MAP_RULE_DUMP, mp);
13983
13984   mp->domain_index = htonl (domain_index);
13985
13986   /* send it... */
13987   S (mp);
13988
13989   /* Use a control ping for synchronization */
13990   M (CONTROL_PING, mp_ping);
13991   S (mp_ping);
13992
13993   W (ret);
13994   return ret;
13995 }
13996
13997 static void vl_api_map_add_domain_reply_t_handler
13998   (vl_api_map_add_domain_reply_t * mp)
13999 {
14000   vat_main_t *vam = &vat_main;
14001   i32 retval = ntohl (mp->retval);
14002
14003   if (vam->async_mode)
14004     {
14005       vam->async_errors += (retval < 0);
14006     }
14007   else
14008     {
14009       vam->retval = retval;
14010       vam->result_ready = 1;
14011     }
14012 }
14013
14014 static void vl_api_map_add_domain_reply_t_handler_json
14015   (vl_api_map_add_domain_reply_t * mp)
14016 {
14017   vat_main_t *vam = &vat_main;
14018   vat_json_node_t node;
14019
14020   vat_json_init_object (&node);
14021   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
14022   vat_json_object_add_uint (&node, "index", ntohl (mp->index));
14023
14024   vat_json_print (vam->ofp, &node);
14025   vat_json_free (&node);
14026
14027   vam->retval = ntohl (mp->retval);
14028   vam->result_ready = 1;
14029 }
14030
14031 static int
14032 api_get_first_msg_id (vat_main_t * vam)
14033 {
14034   vl_api_get_first_msg_id_t *mp;
14035   unformat_input_t *i = vam->input;
14036   u8 *name;
14037   u8 name_set = 0;
14038   int ret;
14039
14040   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14041     {
14042       if (unformat (i, "client %s", &name))
14043         name_set = 1;
14044       else
14045         break;
14046     }
14047
14048   if (name_set == 0)
14049     {
14050       errmsg ("missing client name");
14051       return -99;
14052     }
14053   vec_add1 (name, 0);
14054
14055   if (vec_len (name) > 63)
14056     {
14057       errmsg ("client name too long");
14058       return -99;
14059     }
14060
14061   M (GET_FIRST_MSG_ID, mp);
14062   clib_memcpy (mp->name, name, vec_len (name));
14063   S (mp);
14064   W (ret);
14065   return ret;
14066 }
14067
14068 static int
14069 api_cop_interface_enable_disable (vat_main_t * vam)
14070 {
14071   unformat_input_t *line_input = vam->input;
14072   vl_api_cop_interface_enable_disable_t *mp;
14073   u32 sw_if_index = ~0;
14074   u8 enable_disable = 1;
14075   int ret;
14076
14077   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14078     {
14079       if (unformat (line_input, "disable"))
14080         enable_disable = 0;
14081       if (unformat (line_input, "enable"))
14082         enable_disable = 1;
14083       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
14084                          vam, &sw_if_index))
14085         ;
14086       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14087         ;
14088       else
14089         break;
14090     }
14091
14092   if (sw_if_index == ~0)
14093     {
14094       errmsg ("missing interface name or sw_if_index");
14095       return -99;
14096     }
14097
14098   /* Construct the API message */
14099   M (COP_INTERFACE_ENABLE_DISABLE, mp);
14100   mp->sw_if_index = ntohl (sw_if_index);
14101   mp->enable_disable = enable_disable;
14102
14103   /* send it... */
14104   S (mp);
14105   /* Wait for the reply */
14106   W (ret);
14107   return ret;
14108 }
14109
14110 static int
14111 api_cop_whitelist_enable_disable (vat_main_t * vam)
14112 {
14113   unformat_input_t *line_input = vam->input;
14114   vl_api_cop_whitelist_enable_disable_t *mp;
14115   u32 sw_if_index = ~0;
14116   u8 ip4 = 0, ip6 = 0, default_cop = 0;
14117   u32 fib_id = 0;
14118   int ret;
14119
14120   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14121     {
14122       if (unformat (line_input, "ip4"))
14123         ip4 = 1;
14124       else if (unformat (line_input, "ip6"))
14125         ip6 = 1;
14126       else if (unformat (line_input, "default"))
14127         default_cop = 1;
14128       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
14129                          vam, &sw_if_index))
14130         ;
14131       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14132         ;
14133       else if (unformat (line_input, "fib-id %d", &fib_id))
14134         ;
14135       else
14136         break;
14137     }
14138
14139   if (sw_if_index == ~0)
14140     {
14141       errmsg ("missing interface name or sw_if_index");
14142       return -99;
14143     }
14144
14145   /* Construct the API message */
14146   M (COP_WHITELIST_ENABLE_DISABLE, mp);
14147   mp->sw_if_index = ntohl (sw_if_index);
14148   mp->fib_id = ntohl (fib_id);
14149   mp->ip4 = ip4;
14150   mp->ip6 = ip6;
14151   mp->default_cop = default_cop;
14152
14153   /* send it... */
14154   S (mp);
14155   /* Wait for the reply */
14156   W (ret);
14157   return ret;
14158 }
14159
14160 static int
14161 api_get_node_graph (vat_main_t * vam)
14162 {
14163   vl_api_get_node_graph_t *mp;
14164   int ret;
14165
14166   M (GET_NODE_GRAPH, mp);
14167
14168   /* send it... */
14169   S (mp);
14170   /* Wait for the reply */
14171   W (ret);
14172   return ret;
14173 }
14174
14175 /* *INDENT-OFF* */
14176 /** Used for parsing LISP eids */
14177 typedef CLIB_PACKED(struct{
14178   u8 addr[16];   /**< eid address */
14179   u32 len;       /**< prefix length if IP */
14180   u8 type;      /**< type of eid */
14181 }) lisp_eid_vat_t;
14182 /* *INDENT-ON* */
14183
14184 static uword
14185 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
14186 {
14187   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
14188
14189   memset (a, 0, sizeof (a[0]));
14190
14191   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
14192     {
14193       a->type = 0;              /* ipv4 type */
14194     }
14195   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
14196     {
14197       a->type = 1;              /* ipv6 type */
14198     }
14199   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
14200     {
14201       a->type = 2;              /* mac type */
14202     }
14203   else if (unformat (input, "%U", unformat_nsh_address, a->addr))
14204     {
14205       a->type = 3;              /* NSH type */
14206       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) a->addr;
14207       nsh->spi = clib_host_to_net_u32 (nsh->spi);
14208     }
14209   else
14210     {
14211       return 0;
14212     }
14213
14214   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
14215     {
14216       return 0;
14217     }
14218
14219   return 1;
14220 }
14221
14222 static int
14223 lisp_eid_size_vat (u8 type)
14224 {
14225   switch (type)
14226     {
14227     case 0:
14228       return 4;
14229     case 1:
14230       return 16;
14231     case 2:
14232       return 6;
14233     case 3:
14234       return 5;
14235     }
14236   return 0;
14237 }
14238
14239 static void
14240 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
14241 {
14242   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
14243 }
14244
14245 static int
14246 api_one_add_del_locator_set (vat_main_t * vam)
14247 {
14248   unformat_input_t *input = vam->input;
14249   vl_api_one_add_del_locator_set_t *mp;
14250   u8 is_add = 1;
14251   u8 *locator_set_name = NULL;
14252   u8 locator_set_name_set = 0;
14253   vl_api_local_locator_t locator, *locators = 0;
14254   u32 sw_if_index, priority, weight;
14255   u32 data_len = 0;
14256
14257   int ret;
14258   /* Parse args required to build the message */
14259   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14260     {
14261       if (unformat (input, "del"))
14262         {
14263           is_add = 0;
14264         }
14265       else if (unformat (input, "locator-set %s", &locator_set_name))
14266         {
14267           locator_set_name_set = 1;
14268         }
14269       else if (unformat (input, "sw_if_index %u p %u w %u",
14270                          &sw_if_index, &priority, &weight))
14271         {
14272           locator.sw_if_index = htonl (sw_if_index);
14273           locator.priority = priority;
14274           locator.weight = weight;
14275           vec_add1 (locators, locator);
14276         }
14277       else
14278         if (unformat
14279             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
14280              &sw_if_index, &priority, &weight))
14281         {
14282           locator.sw_if_index = htonl (sw_if_index);
14283           locator.priority = priority;
14284           locator.weight = weight;
14285           vec_add1 (locators, locator);
14286         }
14287       else
14288         break;
14289     }
14290
14291   if (locator_set_name_set == 0)
14292     {
14293       errmsg ("missing locator-set name");
14294       vec_free (locators);
14295       return -99;
14296     }
14297
14298   if (vec_len (locator_set_name) > 64)
14299     {
14300       errmsg ("locator-set name too long");
14301       vec_free (locator_set_name);
14302       vec_free (locators);
14303       return -99;
14304     }
14305   vec_add1 (locator_set_name, 0);
14306
14307   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
14308
14309   /* Construct the API message */
14310   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
14311
14312   mp->is_add = is_add;
14313   clib_memcpy (mp->locator_set_name, locator_set_name,
14314                vec_len (locator_set_name));
14315   vec_free (locator_set_name);
14316
14317   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
14318   if (locators)
14319     clib_memcpy (mp->locators, locators, data_len);
14320   vec_free (locators);
14321
14322   /* send it... */
14323   S (mp);
14324
14325   /* Wait for a reply... */
14326   W (ret);
14327   return ret;
14328 }
14329
14330 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
14331
14332 static int
14333 api_one_add_del_locator (vat_main_t * vam)
14334 {
14335   unformat_input_t *input = vam->input;
14336   vl_api_one_add_del_locator_t *mp;
14337   u32 tmp_if_index = ~0;
14338   u32 sw_if_index = ~0;
14339   u8 sw_if_index_set = 0;
14340   u8 sw_if_index_if_name_set = 0;
14341   u32 priority = ~0;
14342   u8 priority_set = 0;
14343   u32 weight = ~0;
14344   u8 weight_set = 0;
14345   u8 is_add = 1;
14346   u8 *locator_set_name = NULL;
14347   u8 locator_set_name_set = 0;
14348   int ret;
14349
14350   /* Parse args required to build the message */
14351   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14352     {
14353       if (unformat (input, "del"))
14354         {
14355           is_add = 0;
14356         }
14357       else if (unformat (input, "locator-set %s", &locator_set_name))
14358         {
14359           locator_set_name_set = 1;
14360         }
14361       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
14362                          &tmp_if_index))
14363         {
14364           sw_if_index_if_name_set = 1;
14365           sw_if_index = tmp_if_index;
14366         }
14367       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
14368         {
14369           sw_if_index_set = 1;
14370           sw_if_index = tmp_if_index;
14371         }
14372       else if (unformat (input, "p %d", &priority))
14373         {
14374           priority_set = 1;
14375         }
14376       else if (unformat (input, "w %d", &weight))
14377         {
14378           weight_set = 1;
14379         }
14380       else
14381         break;
14382     }
14383
14384   if (locator_set_name_set == 0)
14385     {
14386       errmsg ("missing locator-set name");
14387       return -99;
14388     }
14389
14390   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
14391     {
14392       errmsg ("missing sw_if_index");
14393       vec_free (locator_set_name);
14394       return -99;
14395     }
14396
14397   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
14398     {
14399       errmsg ("cannot use both params interface name and sw_if_index");
14400       vec_free (locator_set_name);
14401       return -99;
14402     }
14403
14404   if (priority_set == 0)
14405     {
14406       errmsg ("missing locator-set priority");
14407       vec_free (locator_set_name);
14408       return -99;
14409     }
14410
14411   if (weight_set == 0)
14412     {
14413       errmsg ("missing locator-set weight");
14414       vec_free (locator_set_name);
14415       return -99;
14416     }
14417
14418   if (vec_len (locator_set_name) > 64)
14419     {
14420       errmsg ("locator-set name too long");
14421       vec_free (locator_set_name);
14422       return -99;
14423     }
14424   vec_add1 (locator_set_name, 0);
14425
14426   /* Construct the API message */
14427   M (ONE_ADD_DEL_LOCATOR, mp);
14428
14429   mp->is_add = is_add;
14430   mp->sw_if_index = ntohl (sw_if_index);
14431   mp->priority = priority;
14432   mp->weight = weight;
14433   clib_memcpy (mp->locator_set_name, locator_set_name,
14434                vec_len (locator_set_name));
14435   vec_free (locator_set_name);
14436
14437   /* send it... */
14438   S (mp);
14439
14440   /* Wait for a reply... */
14441   W (ret);
14442   return ret;
14443 }
14444
14445 #define api_lisp_add_del_locator api_one_add_del_locator
14446
14447 uword
14448 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
14449 {
14450   u32 *key_id = va_arg (*args, u32 *);
14451   u8 *s = 0;
14452
14453   if (unformat (input, "%s", &s))
14454     {
14455       if (!strcmp ((char *) s, "sha1"))
14456         key_id[0] = HMAC_SHA_1_96;
14457       else if (!strcmp ((char *) s, "sha256"))
14458         key_id[0] = HMAC_SHA_256_128;
14459       else
14460         {
14461           clib_warning ("invalid key_id: '%s'", s);
14462           key_id[0] = HMAC_NO_KEY;
14463         }
14464     }
14465   else
14466     return 0;
14467
14468   vec_free (s);
14469   return 1;
14470 }
14471
14472 static int
14473 api_one_add_del_local_eid (vat_main_t * vam)
14474 {
14475   unformat_input_t *input = vam->input;
14476   vl_api_one_add_del_local_eid_t *mp;
14477   u8 is_add = 1;
14478   u8 eid_set = 0;
14479   lisp_eid_vat_t _eid, *eid = &_eid;
14480   u8 *locator_set_name = 0;
14481   u8 locator_set_name_set = 0;
14482   u32 vni = 0;
14483   u16 key_id = 0;
14484   u8 *key = 0;
14485   int ret;
14486
14487   /* Parse args required to build the message */
14488   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14489     {
14490       if (unformat (input, "del"))
14491         {
14492           is_add = 0;
14493         }
14494       else if (unformat (input, "vni %d", &vni))
14495         {
14496           ;
14497         }
14498       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
14499         {
14500           eid_set = 1;
14501         }
14502       else if (unformat (input, "locator-set %s", &locator_set_name))
14503         {
14504           locator_set_name_set = 1;
14505         }
14506       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
14507         ;
14508       else if (unformat (input, "secret-key %_%v%_", &key))
14509         ;
14510       else
14511         break;
14512     }
14513
14514   if (locator_set_name_set == 0)
14515     {
14516       errmsg ("missing locator-set name");
14517       return -99;
14518     }
14519
14520   if (0 == eid_set)
14521     {
14522       errmsg ("EID address not set!");
14523       vec_free (locator_set_name);
14524       return -99;
14525     }
14526
14527   if (key && (0 == key_id))
14528     {
14529       errmsg ("invalid key_id!");
14530       return -99;
14531     }
14532
14533   if (vec_len (key) > 64)
14534     {
14535       errmsg ("key too long");
14536       vec_free (key);
14537       return -99;
14538     }
14539
14540   if (vec_len (locator_set_name) > 64)
14541     {
14542       errmsg ("locator-set name too long");
14543       vec_free (locator_set_name);
14544       return -99;
14545     }
14546   vec_add1 (locator_set_name, 0);
14547
14548   /* Construct the API message */
14549   M (ONE_ADD_DEL_LOCAL_EID, mp);
14550
14551   mp->is_add = is_add;
14552   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
14553   mp->eid_type = eid->type;
14554   mp->prefix_len = eid->len;
14555   mp->vni = clib_host_to_net_u32 (vni);
14556   mp->key_id = clib_host_to_net_u16 (key_id);
14557   clib_memcpy (mp->locator_set_name, locator_set_name,
14558                vec_len (locator_set_name));
14559   clib_memcpy (mp->key, key, vec_len (key));
14560
14561   vec_free (locator_set_name);
14562   vec_free (key);
14563
14564   /* send it... */
14565   S (mp);
14566
14567   /* Wait for a reply... */
14568   W (ret);
14569   return ret;
14570 }
14571
14572 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
14573
14574 static int
14575 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
14576 {
14577   u32 dp_table = 0, vni = 0;;
14578   unformat_input_t *input = vam->input;
14579   vl_api_gpe_add_del_fwd_entry_t *mp;
14580   u8 is_add = 1;
14581   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
14582   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
14583   u8 rmt_eid_set = 0, lcl_eid_set = 0;
14584   u32 action = ~0, w;
14585   ip4_address_t rmt_rloc4, lcl_rloc4;
14586   ip6_address_t rmt_rloc6, lcl_rloc6;
14587   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
14588   int ret;
14589
14590   memset (&rloc, 0, sizeof (rloc));
14591
14592   /* Parse args required to build the message */
14593   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14594     {
14595       if (unformat (input, "del"))
14596         is_add = 0;
14597       else if (unformat (input, "add"))
14598         is_add = 1;
14599       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
14600         {
14601           rmt_eid_set = 1;
14602         }
14603       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
14604         {
14605           lcl_eid_set = 1;
14606         }
14607       else if (unformat (input, "vrf %d", &dp_table))
14608         ;
14609       else if (unformat (input, "bd %d", &dp_table))
14610         ;
14611       else if (unformat (input, "vni %d", &vni))
14612         ;
14613       else if (unformat (input, "w %d", &w))
14614         {
14615           if (!curr_rloc)
14616             {
14617               errmsg ("No RLOC configured for setting priority/weight!");
14618               return -99;
14619             }
14620           curr_rloc->weight = w;
14621         }
14622       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
14623                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
14624         {
14625           rloc.is_ip4 = 1;
14626
14627           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
14628           rloc.weight = 0;
14629           vec_add1 (lcl_locs, rloc);
14630
14631           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
14632           vec_add1 (rmt_locs, rloc);
14633           /* weight saved in rmt loc */
14634           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
14635         }
14636       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
14637                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
14638         {
14639           rloc.is_ip4 = 0;
14640           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
14641           rloc.weight = 0;
14642           vec_add1 (lcl_locs, rloc);
14643
14644           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
14645           vec_add1 (rmt_locs, rloc);
14646           /* weight saved in rmt loc */
14647           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
14648         }
14649       else if (unformat (input, "action %d", &action))
14650         {
14651           ;
14652         }
14653       else
14654         {
14655           clib_warning ("parse error '%U'", format_unformat_error, input);
14656           return -99;
14657         }
14658     }
14659
14660   if (!rmt_eid_set)
14661     {
14662       errmsg ("remote eid addresses not set");
14663       return -99;
14664     }
14665
14666   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
14667     {
14668       errmsg ("eid types don't match");
14669       return -99;
14670     }
14671
14672   if (0 == rmt_locs && (u32) ~ 0 == action)
14673     {
14674       errmsg ("action not set for negative mapping");
14675       return -99;
14676     }
14677
14678   /* Construct the API message */
14679   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
14680       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
14681
14682   mp->is_add = is_add;
14683   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
14684   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
14685   mp->eid_type = rmt_eid->type;
14686   mp->dp_table = clib_host_to_net_u32 (dp_table);
14687   mp->vni = clib_host_to_net_u32 (vni);
14688   mp->rmt_len = rmt_eid->len;
14689   mp->lcl_len = lcl_eid->len;
14690   mp->action = action;
14691
14692   if (0 != rmt_locs && 0 != lcl_locs)
14693     {
14694       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
14695       clib_memcpy (mp->locs, lcl_locs,
14696                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
14697
14698       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
14699       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
14700                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
14701     }
14702   vec_free (lcl_locs);
14703   vec_free (rmt_locs);
14704
14705   /* send it... */
14706   S (mp);
14707
14708   /* Wait for a reply... */
14709   W (ret);
14710   return ret;
14711 }
14712
14713 static int
14714 api_one_add_del_map_server (vat_main_t * vam)
14715 {
14716   unformat_input_t *input = vam->input;
14717   vl_api_one_add_del_map_server_t *mp;
14718   u8 is_add = 1;
14719   u8 ipv4_set = 0;
14720   u8 ipv6_set = 0;
14721   ip4_address_t ipv4;
14722   ip6_address_t ipv6;
14723   int ret;
14724
14725   /* Parse args required to build the message */
14726   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14727     {
14728       if (unformat (input, "del"))
14729         {
14730           is_add = 0;
14731         }
14732       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
14733         {
14734           ipv4_set = 1;
14735         }
14736       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
14737         {
14738           ipv6_set = 1;
14739         }
14740       else
14741         break;
14742     }
14743
14744   if (ipv4_set && ipv6_set)
14745     {
14746       errmsg ("both eid v4 and v6 addresses set");
14747       return -99;
14748     }
14749
14750   if (!ipv4_set && !ipv6_set)
14751     {
14752       errmsg ("eid addresses not set");
14753       return -99;
14754     }
14755
14756   /* Construct the API message */
14757   M (ONE_ADD_DEL_MAP_SERVER, mp);
14758
14759   mp->is_add = is_add;
14760   if (ipv6_set)
14761     {
14762       mp->is_ipv6 = 1;
14763       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
14764     }
14765   else
14766     {
14767       mp->is_ipv6 = 0;
14768       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
14769     }
14770
14771   /* send it... */
14772   S (mp);
14773
14774   /* Wait for a reply... */
14775   W (ret);
14776   return ret;
14777 }
14778
14779 #define api_lisp_add_del_map_server api_one_add_del_map_server
14780
14781 static int
14782 api_one_add_del_map_resolver (vat_main_t * vam)
14783 {
14784   unformat_input_t *input = vam->input;
14785   vl_api_one_add_del_map_resolver_t *mp;
14786   u8 is_add = 1;
14787   u8 ipv4_set = 0;
14788   u8 ipv6_set = 0;
14789   ip4_address_t ipv4;
14790   ip6_address_t ipv6;
14791   int ret;
14792
14793   /* Parse args required to build the message */
14794   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14795     {
14796       if (unformat (input, "del"))
14797         {
14798           is_add = 0;
14799         }
14800       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
14801         {
14802           ipv4_set = 1;
14803         }
14804       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
14805         {
14806           ipv6_set = 1;
14807         }
14808       else
14809         break;
14810     }
14811
14812   if (ipv4_set && ipv6_set)
14813     {
14814       errmsg ("both eid v4 and v6 addresses set");
14815       return -99;
14816     }
14817
14818   if (!ipv4_set && !ipv6_set)
14819     {
14820       errmsg ("eid addresses not set");
14821       return -99;
14822     }
14823
14824   /* Construct the API message */
14825   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
14826
14827   mp->is_add = is_add;
14828   if (ipv6_set)
14829     {
14830       mp->is_ipv6 = 1;
14831       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
14832     }
14833   else
14834     {
14835       mp->is_ipv6 = 0;
14836       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
14837     }
14838
14839   /* send it... */
14840   S (mp);
14841
14842   /* Wait for a reply... */
14843   W (ret);
14844   return ret;
14845 }
14846
14847 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
14848
14849 static int
14850 api_lisp_gpe_enable_disable (vat_main_t * vam)
14851 {
14852   unformat_input_t *input = vam->input;
14853   vl_api_gpe_enable_disable_t *mp;
14854   u8 is_set = 0;
14855   u8 is_en = 1;
14856   int ret;
14857
14858   /* Parse args required to build the message */
14859   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14860     {
14861       if (unformat (input, "enable"))
14862         {
14863           is_set = 1;
14864           is_en = 1;
14865         }
14866       else if (unformat (input, "disable"))
14867         {
14868           is_set = 1;
14869           is_en = 0;
14870         }
14871       else
14872         break;
14873     }
14874
14875   if (is_set == 0)
14876     {
14877       errmsg ("Value not set");
14878       return -99;
14879     }
14880
14881   /* Construct the API message */
14882   M (GPE_ENABLE_DISABLE, mp);
14883
14884   mp->is_en = is_en;
14885
14886   /* send it... */
14887   S (mp);
14888
14889   /* Wait for a reply... */
14890   W (ret);
14891   return ret;
14892 }
14893
14894 static int
14895 api_one_rloc_probe_enable_disable (vat_main_t * vam)
14896 {
14897   unformat_input_t *input = vam->input;
14898   vl_api_one_rloc_probe_enable_disable_t *mp;
14899   u8 is_set = 0;
14900   u8 is_en = 0;
14901   int ret;
14902
14903   /* Parse args required to build the message */
14904   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14905     {
14906       if (unformat (input, "enable"))
14907         {
14908           is_set = 1;
14909           is_en = 1;
14910         }
14911       else if (unformat (input, "disable"))
14912         is_set = 1;
14913       else
14914         break;
14915     }
14916
14917   if (!is_set)
14918     {
14919       errmsg ("Value not set");
14920       return -99;
14921     }
14922
14923   /* Construct the API message */
14924   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
14925
14926   mp->is_enabled = is_en;
14927
14928   /* send it... */
14929   S (mp);
14930
14931   /* Wait for a reply... */
14932   W (ret);
14933   return ret;
14934 }
14935
14936 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
14937
14938 static int
14939 api_one_map_register_enable_disable (vat_main_t * vam)
14940 {
14941   unformat_input_t *input = vam->input;
14942   vl_api_one_map_register_enable_disable_t *mp;
14943   u8 is_set = 0;
14944   u8 is_en = 0;
14945   int ret;
14946
14947   /* Parse args required to build the message */
14948   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14949     {
14950       if (unformat (input, "enable"))
14951         {
14952           is_set = 1;
14953           is_en = 1;
14954         }
14955       else if (unformat (input, "disable"))
14956         is_set = 1;
14957       else
14958         break;
14959     }
14960
14961   if (!is_set)
14962     {
14963       errmsg ("Value not set");
14964       return -99;
14965     }
14966
14967   /* Construct the API message */
14968   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
14969
14970   mp->is_enabled = is_en;
14971
14972   /* send it... */
14973   S (mp);
14974
14975   /* Wait for a reply... */
14976   W (ret);
14977   return ret;
14978 }
14979
14980 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
14981
14982 static int
14983 api_one_enable_disable (vat_main_t * vam)
14984 {
14985   unformat_input_t *input = vam->input;
14986   vl_api_one_enable_disable_t *mp;
14987   u8 is_set = 0;
14988   u8 is_en = 0;
14989   int ret;
14990
14991   /* Parse args required to build the message */
14992   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14993     {
14994       if (unformat (input, "enable"))
14995         {
14996           is_set = 1;
14997           is_en = 1;
14998         }
14999       else if (unformat (input, "disable"))
15000         {
15001           is_set = 1;
15002         }
15003       else
15004         break;
15005     }
15006
15007   if (!is_set)
15008     {
15009       errmsg ("Value not set");
15010       return -99;
15011     }
15012
15013   /* Construct the API message */
15014   M (ONE_ENABLE_DISABLE, mp);
15015
15016   mp->is_en = is_en;
15017
15018   /* send it... */
15019   S (mp);
15020
15021   /* Wait for a reply... */
15022   W (ret);
15023   return ret;
15024 }
15025
15026 #define api_lisp_enable_disable api_one_enable_disable
15027
15028 static int
15029 api_show_one_map_register_state (vat_main_t * vam)
15030 {
15031   vl_api_show_one_map_register_state_t *mp;
15032   int ret;
15033
15034   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
15035
15036   /* send */
15037   S (mp);
15038
15039   /* wait for reply */
15040   W (ret);
15041   return ret;
15042 }
15043
15044 #define api_show_lisp_map_register_state api_show_one_map_register_state
15045
15046 static int
15047 api_show_one_rloc_probe_state (vat_main_t * vam)
15048 {
15049   vl_api_show_one_rloc_probe_state_t *mp;
15050   int ret;
15051
15052   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
15053
15054   /* send */
15055   S (mp);
15056
15057   /* wait for reply */
15058   W (ret);
15059   return ret;
15060 }
15061
15062 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
15063
15064 static int
15065 api_one_add_del_l2_arp_entry (vat_main_t * vam)
15066 {
15067   vl_api_one_add_del_l2_arp_entry_t *mp;
15068   unformat_input_t *input = vam->input;
15069   u8 is_add = 1;
15070   u8 mac_set = 0;
15071   u8 bd_set = 0;
15072   u8 ip_set = 0;
15073   u8 mac[6] = { 0, };
15074   u32 ip4 = 0, bd = ~0;
15075   int ret;
15076
15077   /* Parse args required to build the message */
15078   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15079     {
15080       if (unformat (input, "del"))
15081         is_add = 0;
15082       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
15083         mac_set = 1;
15084       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
15085         ip_set = 1;
15086       else if (unformat (input, "bd %d", &bd))
15087         bd_set = 1;
15088       else
15089         {
15090           errmsg ("parse error '%U'", format_unformat_error, input);
15091           return -99;
15092         }
15093     }
15094
15095   if (!bd_set || !ip_set || (!mac_set && is_add))
15096     {
15097       errmsg ("Missing BD, IP or MAC!");
15098       return -99;
15099     }
15100
15101   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
15102   mp->is_add = is_add;
15103   clib_memcpy (mp->mac, mac, 6);
15104   mp->bd = clib_host_to_net_u32 (bd);
15105   mp->ip4 = ip4;
15106
15107   /* send */
15108   S (mp);
15109
15110   /* wait for reply */
15111   W (ret);
15112   return ret;
15113 }
15114
15115 static int
15116 api_one_l2_arp_bd_get (vat_main_t * vam)
15117 {
15118   vl_api_one_l2_arp_bd_get_t *mp;
15119   int ret;
15120
15121   M (ONE_L2_ARP_BD_GET, mp);
15122
15123   /* send */
15124   S (mp);
15125
15126   /* wait for reply */
15127   W (ret);
15128   return ret;
15129 }
15130
15131 static int
15132 api_one_l2_arp_entries_get (vat_main_t * vam)
15133 {
15134   vl_api_one_l2_arp_entries_get_t *mp;
15135   unformat_input_t *input = vam->input;
15136   u8 bd_set = 0;
15137   u32 bd = ~0;
15138   int ret;
15139
15140   /* Parse args required to build the message */
15141   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15142     {
15143       if (unformat (input, "bd %d", &bd))
15144         bd_set = 1;
15145       else
15146         {
15147           errmsg ("parse error '%U'", format_unformat_error, input);
15148           return -99;
15149         }
15150     }
15151
15152   if (!bd_set)
15153     {
15154       errmsg ("Expected bridge domain!");
15155       return -99;
15156     }
15157
15158   M (ONE_L2_ARP_ENTRIES_GET, mp);
15159   mp->bd = clib_host_to_net_u32 (bd);
15160
15161   /* send */
15162   S (mp);
15163
15164   /* wait for reply */
15165   W (ret);
15166   return ret;
15167 }
15168
15169 static int
15170 api_one_stats_enable_disable (vat_main_t * vam)
15171 {
15172   vl_api_one_stats_enable_disable_t *mp;
15173   unformat_input_t *input = vam->input;
15174   u8 is_set = 0;
15175   u8 is_en = 0;
15176   int ret;
15177
15178   /* Parse args required to build the message */
15179   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15180     {
15181       if (unformat (input, "enable"))
15182         {
15183           is_set = 1;
15184           is_en = 1;
15185         }
15186       else if (unformat (input, "disable"))
15187         {
15188           is_set = 1;
15189         }
15190       else
15191         break;
15192     }
15193
15194   if (!is_set)
15195     {
15196       errmsg ("Value not set");
15197       return -99;
15198     }
15199
15200   M (ONE_STATS_ENABLE_DISABLE, mp);
15201   mp->is_en = is_en;
15202
15203   /* send */
15204   S (mp);
15205
15206   /* wait for reply */
15207   W (ret);
15208   return ret;
15209 }
15210
15211 static int
15212 api_show_one_stats_enable_disable (vat_main_t * vam)
15213 {
15214   vl_api_show_one_stats_enable_disable_t *mp;
15215   int ret;
15216
15217   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
15218
15219   /* send */
15220   S (mp);
15221
15222   /* wait for reply */
15223   W (ret);
15224   return ret;
15225 }
15226
15227 static int
15228 api_show_one_map_request_mode (vat_main_t * vam)
15229 {
15230   vl_api_show_one_map_request_mode_t *mp;
15231   int ret;
15232
15233   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
15234
15235   /* send */
15236   S (mp);
15237
15238   /* wait for reply */
15239   W (ret);
15240   return ret;
15241 }
15242
15243 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
15244
15245 static int
15246 api_one_map_request_mode (vat_main_t * vam)
15247 {
15248   unformat_input_t *input = vam->input;
15249   vl_api_one_map_request_mode_t *mp;
15250   u8 mode = 0;
15251   int ret;
15252
15253   /* Parse args required to build the message */
15254   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15255     {
15256       if (unformat (input, "dst-only"))
15257         mode = 0;
15258       else if (unformat (input, "src-dst"))
15259         mode = 1;
15260       else
15261         {
15262           errmsg ("parse error '%U'", format_unformat_error, input);
15263           return -99;
15264         }
15265     }
15266
15267   M (ONE_MAP_REQUEST_MODE, mp);
15268
15269   mp->mode = mode;
15270
15271   /* send */
15272   S (mp);
15273
15274   /* wait for reply */
15275   W (ret);
15276   return ret;
15277 }
15278
15279 #define api_lisp_map_request_mode api_one_map_request_mode
15280
15281 /**
15282  * Enable/disable ONE proxy ITR.
15283  *
15284  * @param vam vpp API test context
15285  * @return return code
15286  */
15287 static int
15288 api_one_pitr_set_locator_set (vat_main_t * vam)
15289 {
15290   u8 ls_name_set = 0;
15291   unformat_input_t *input = vam->input;
15292   vl_api_one_pitr_set_locator_set_t *mp;
15293   u8 is_add = 1;
15294   u8 *ls_name = 0;
15295   int ret;
15296
15297   /* Parse args required to build the message */
15298   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15299     {
15300       if (unformat (input, "del"))
15301         is_add = 0;
15302       else if (unformat (input, "locator-set %s", &ls_name))
15303         ls_name_set = 1;
15304       else
15305         {
15306           errmsg ("parse error '%U'", format_unformat_error, input);
15307           return -99;
15308         }
15309     }
15310
15311   if (!ls_name_set)
15312     {
15313       errmsg ("locator-set name not set!");
15314       return -99;
15315     }
15316
15317   M (ONE_PITR_SET_LOCATOR_SET, mp);
15318
15319   mp->is_add = is_add;
15320   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
15321   vec_free (ls_name);
15322
15323   /* send */
15324   S (mp);
15325
15326   /* wait for reply */
15327   W (ret);
15328   return ret;
15329 }
15330
15331 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
15332
15333 static int
15334 api_one_nsh_set_locator_set (vat_main_t * vam)
15335 {
15336   u8 ls_name_set = 0;
15337   unformat_input_t *input = vam->input;
15338   vl_api_one_nsh_set_locator_set_t *mp;
15339   u8 is_add = 1;
15340   u8 *ls_name = 0;
15341   int ret;
15342
15343   /* Parse args required to build the message */
15344   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15345     {
15346       if (unformat (input, "del"))
15347         is_add = 0;
15348       else if (unformat (input, "ls %s", &ls_name))
15349         ls_name_set = 1;
15350       else
15351         {
15352           errmsg ("parse error '%U'", format_unformat_error, input);
15353           return -99;
15354         }
15355     }
15356
15357   if (!ls_name_set && is_add)
15358     {
15359       errmsg ("locator-set name not set!");
15360       return -99;
15361     }
15362
15363   M (ONE_NSH_SET_LOCATOR_SET, mp);
15364
15365   mp->is_add = is_add;
15366   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
15367   vec_free (ls_name);
15368
15369   /* send */
15370   S (mp);
15371
15372   /* wait for reply */
15373   W (ret);
15374   return ret;
15375 }
15376
15377 static int
15378 api_show_one_pitr (vat_main_t * vam)
15379 {
15380   vl_api_show_one_pitr_t *mp;
15381   int ret;
15382
15383   if (!vam->json_output)
15384     {
15385       print (vam->ofp, "%=20s", "lisp status:");
15386     }
15387
15388   M (SHOW_ONE_PITR, mp);
15389   /* send it... */
15390   S (mp);
15391
15392   /* Wait for a reply... */
15393   W (ret);
15394   return ret;
15395 }
15396
15397 #define api_show_lisp_pitr api_show_one_pitr
15398
15399 static int
15400 api_one_use_petr (vat_main_t * vam)
15401 {
15402   unformat_input_t *input = vam->input;
15403   vl_api_one_use_petr_t *mp;
15404   u8 is_add = 0;
15405   ip_address_t ip;
15406   int ret;
15407
15408   memset (&ip, 0, sizeof (ip));
15409
15410   /* Parse args required to build the message */
15411   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15412     {
15413       if (unformat (input, "disable"))
15414         is_add = 0;
15415       else
15416         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
15417         {
15418           is_add = 1;
15419           ip_addr_version (&ip) = IP4;
15420         }
15421       else
15422         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
15423         {
15424           is_add = 1;
15425           ip_addr_version (&ip) = IP6;
15426         }
15427       else
15428         {
15429           errmsg ("parse error '%U'", format_unformat_error, input);
15430           return -99;
15431         }
15432     }
15433
15434   M (ONE_USE_PETR, mp);
15435
15436   mp->is_add = is_add;
15437   if (is_add)
15438     {
15439       mp->is_ip4 = ip_addr_version (&ip) == IP4 ? 1 : 0;
15440       if (mp->is_ip4)
15441         clib_memcpy (mp->address, &ip, 4);
15442       else
15443         clib_memcpy (mp->address, &ip, 16);
15444     }
15445
15446   /* send */
15447   S (mp);
15448
15449   /* wait for reply */
15450   W (ret);
15451   return ret;
15452 }
15453
15454 #define api_lisp_use_petr api_one_use_petr
15455
15456 static int
15457 api_show_one_nsh_mapping (vat_main_t * vam)
15458 {
15459   vl_api_show_one_use_petr_t *mp;
15460   int ret;
15461
15462   if (!vam->json_output)
15463     {
15464       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
15465     }
15466
15467   M (SHOW_ONE_NSH_MAPPING, mp);
15468   /* send it... */
15469   S (mp);
15470
15471   /* Wait for a reply... */
15472   W (ret);
15473   return ret;
15474 }
15475
15476 static int
15477 api_show_one_use_petr (vat_main_t * vam)
15478 {
15479   vl_api_show_one_use_petr_t *mp;
15480   int ret;
15481
15482   if (!vam->json_output)
15483     {
15484       print (vam->ofp, "%=20s", "Proxy-ETR status:");
15485     }
15486
15487   M (SHOW_ONE_USE_PETR, mp);
15488   /* send it... */
15489   S (mp);
15490
15491   /* Wait for a reply... */
15492   W (ret);
15493   return ret;
15494 }
15495
15496 #define api_show_lisp_use_petr api_show_one_use_petr
15497
15498 /**
15499  * Add/delete mapping between vni and vrf
15500  */
15501 static int
15502 api_one_eid_table_add_del_map (vat_main_t * vam)
15503 {
15504   unformat_input_t *input = vam->input;
15505   vl_api_one_eid_table_add_del_map_t *mp;
15506   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
15507   u32 vni, vrf, bd_index;
15508   int ret;
15509
15510   /* Parse args required to build the message */
15511   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15512     {
15513       if (unformat (input, "del"))
15514         is_add = 0;
15515       else if (unformat (input, "vrf %d", &vrf))
15516         vrf_set = 1;
15517       else if (unformat (input, "bd_index %d", &bd_index))
15518         bd_index_set = 1;
15519       else if (unformat (input, "vni %d", &vni))
15520         vni_set = 1;
15521       else
15522         break;
15523     }
15524
15525   if (!vni_set || (!vrf_set && !bd_index_set))
15526     {
15527       errmsg ("missing arguments!");
15528       return -99;
15529     }
15530
15531   if (vrf_set && bd_index_set)
15532     {
15533       errmsg ("error: both vrf and bd entered!");
15534       return -99;
15535     }
15536
15537   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
15538
15539   mp->is_add = is_add;
15540   mp->vni = htonl (vni);
15541   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
15542   mp->is_l2 = bd_index_set;
15543
15544   /* send */
15545   S (mp);
15546
15547   /* wait for reply */
15548   W (ret);
15549   return ret;
15550 }
15551
15552 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
15553
15554 uword
15555 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
15556 {
15557   u32 *action = va_arg (*args, u32 *);
15558   u8 *s = 0;
15559
15560   if (unformat (input, "%s", &s))
15561     {
15562       if (!strcmp ((char *) s, "no-action"))
15563         action[0] = 0;
15564       else if (!strcmp ((char *) s, "natively-forward"))
15565         action[0] = 1;
15566       else if (!strcmp ((char *) s, "send-map-request"))
15567         action[0] = 2;
15568       else if (!strcmp ((char *) s, "drop"))
15569         action[0] = 3;
15570       else
15571         {
15572           clib_warning ("invalid action: '%s'", s);
15573           action[0] = 3;
15574         }
15575     }
15576   else
15577     return 0;
15578
15579   vec_free (s);
15580   return 1;
15581 }
15582
15583 /**
15584  * Add/del remote mapping to/from ONE control plane
15585  *
15586  * @param vam vpp API test context
15587  * @return return code
15588  */
15589 static int
15590 api_one_add_del_remote_mapping (vat_main_t * vam)
15591 {
15592   unformat_input_t *input = vam->input;
15593   vl_api_one_add_del_remote_mapping_t *mp;
15594   u32 vni = 0;
15595   lisp_eid_vat_t _eid, *eid = &_eid;
15596   lisp_eid_vat_t _seid, *seid = &_seid;
15597   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
15598   u32 action = ~0, p, w, data_len;
15599   ip4_address_t rloc4;
15600   ip6_address_t rloc6;
15601   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
15602   int ret;
15603
15604   memset (&rloc, 0, sizeof (rloc));
15605
15606   /* Parse args required to build the message */
15607   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15608     {
15609       if (unformat (input, "del-all"))
15610         {
15611           del_all = 1;
15612         }
15613       else if (unformat (input, "del"))
15614         {
15615           is_add = 0;
15616         }
15617       else if (unformat (input, "add"))
15618         {
15619           is_add = 1;
15620         }
15621       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
15622         {
15623           eid_set = 1;
15624         }
15625       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
15626         {
15627           seid_set = 1;
15628         }
15629       else if (unformat (input, "vni %d", &vni))
15630         {
15631           ;
15632         }
15633       else if (unformat (input, "p %d w %d", &p, &w))
15634         {
15635           if (!curr_rloc)
15636             {
15637               errmsg ("No RLOC configured for setting priority/weight!");
15638               return -99;
15639             }
15640           curr_rloc->priority = p;
15641           curr_rloc->weight = w;
15642         }
15643       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
15644         {
15645           rloc.is_ip4 = 1;
15646           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
15647           vec_add1 (rlocs, rloc);
15648           curr_rloc = &rlocs[vec_len (rlocs) - 1];
15649         }
15650       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
15651         {
15652           rloc.is_ip4 = 0;
15653           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
15654           vec_add1 (rlocs, rloc);
15655           curr_rloc = &rlocs[vec_len (rlocs) - 1];
15656         }
15657       else if (unformat (input, "action %U",
15658                          unformat_negative_mapping_action, &action))
15659         {
15660           ;
15661         }
15662       else
15663         {
15664           clib_warning ("parse error '%U'", format_unformat_error, input);
15665           return -99;
15666         }
15667     }
15668
15669   if (0 == eid_set)
15670     {
15671       errmsg ("missing params!");
15672       return -99;
15673     }
15674
15675   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
15676     {
15677       errmsg ("no action set for negative map-reply!");
15678       return -99;
15679     }
15680
15681   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
15682
15683   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
15684   mp->is_add = is_add;
15685   mp->vni = htonl (vni);
15686   mp->action = (u8) action;
15687   mp->is_src_dst = seid_set;
15688   mp->eid_len = eid->len;
15689   mp->seid_len = seid->len;
15690   mp->del_all = del_all;
15691   mp->eid_type = eid->type;
15692   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
15693   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
15694
15695   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
15696   clib_memcpy (mp->rlocs, rlocs, data_len);
15697   vec_free (rlocs);
15698
15699   /* send it... */
15700   S (mp);
15701
15702   /* Wait for a reply... */
15703   W (ret);
15704   return ret;
15705 }
15706
15707 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
15708
15709 /**
15710  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
15711  * forwarding entries in data-plane accordingly.
15712  *
15713  * @param vam vpp API test context
15714  * @return return code
15715  */
15716 static int
15717 api_one_add_del_adjacency (vat_main_t * vam)
15718 {
15719   unformat_input_t *input = vam->input;
15720   vl_api_one_add_del_adjacency_t *mp;
15721   u32 vni = 0;
15722   ip4_address_t leid4, reid4;
15723   ip6_address_t leid6, reid6;
15724   u8 reid_mac[6] = { 0 };
15725   u8 leid_mac[6] = { 0 };
15726   u8 reid_type, leid_type;
15727   u32 leid_len = 0, reid_len = 0, len;
15728   u8 is_add = 1;
15729   int ret;
15730
15731   leid_type = reid_type = (u8) ~ 0;
15732
15733   /* Parse args required to build the message */
15734   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15735     {
15736       if (unformat (input, "del"))
15737         {
15738           is_add = 0;
15739         }
15740       else if (unformat (input, "add"))
15741         {
15742           is_add = 1;
15743         }
15744       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
15745                          &reid4, &len))
15746         {
15747           reid_type = 0;        /* ipv4 */
15748           reid_len = len;
15749         }
15750       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
15751                          &reid6, &len))
15752         {
15753           reid_type = 1;        /* ipv6 */
15754           reid_len = len;
15755         }
15756       else if (unformat (input, "reid %U", unformat_ethernet_address,
15757                          reid_mac))
15758         {
15759           reid_type = 2;        /* mac */
15760         }
15761       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
15762                          &leid4, &len))
15763         {
15764           leid_type = 0;        /* ipv4 */
15765           leid_len = len;
15766         }
15767       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
15768                          &leid6, &len))
15769         {
15770           leid_type = 1;        /* ipv6 */
15771           leid_len = len;
15772         }
15773       else if (unformat (input, "leid %U", unformat_ethernet_address,
15774                          leid_mac))
15775         {
15776           leid_type = 2;        /* mac */
15777         }
15778       else if (unformat (input, "vni %d", &vni))
15779         {
15780           ;
15781         }
15782       else
15783         {
15784           errmsg ("parse error '%U'", format_unformat_error, input);
15785           return -99;
15786         }
15787     }
15788
15789   if ((u8) ~ 0 == reid_type)
15790     {
15791       errmsg ("missing params!");
15792       return -99;
15793     }
15794
15795   if (leid_type != reid_type)
15796     {
15797       errmsg ("remote and local EIDs are of different types!");
15798       return -99;
15799     }
15800
15801   M (ONE_ADD_DEL_ADJACENCY, mp);
15802   mp->is_add = is_add;
15803   mp->vni = htonl (vni);
15804   mp->leid_len = leid_len;
15805   mp->reid_len = reid_len;
15806   mp->eid_type = reid_type;
15807
15808   switch (mp->eid_type)
15809     {
15810     case 0:
15811       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
15812       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
15813       break;
15814     case 1:
15815       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
15816       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
15817       break;
15818     case 2:
15819       clib_memcpy (mp->leid, leid_mac, 6);
15820       clib_memcpy (mp->reid, reid_mac, 6);
15821       break;
15822     default:
15823       errmsg ("unknown EID type %d!", mp->eid_type);
15824       return 0;
15825     }
15826
15827   /* send it... */
15828   S (mp);
15829
15830   /* Wait for a reply... */
15831   W (ret);
15832   return ret;
15833 }
15834
15835 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
15836
15837 uword
15838 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
15839 {
15840   u32 *mode = va_arg (*args, u32 *);
15841
15842   if (unformat (input, "lisp"))
15843     *mode = 0;
15844   else if (unformat (input, "vxlan"))
15845     *mode = 1;
15846   else
15847     return 0;
15848
15849   return 1;
15850 }
15851
15852 static int
15853 api_gpe_get_encap_mode (vat_main_t * vam)
15854 {
15855   vl_api_gpe_get_encap_mode_t *mp;
15856   int ret;
15857
15858   /* Construct the API message */
15859   M (GPE_GET_ENCAP_MODE, mp);
15860
15861   /* send it... */
15862   S (mp);
15863
15864   /* Wait for a reply... */
15865   W (ret);
15866   return ret;
15867 }
15868
15869 static int
15870 api_gpe_set_encap_mode (vat_main_t * vam)
15871 {
15872   unformat_input_t *input = vam->input;
15873   vl_api_gpe_set_encap_mode_t *mp;
15874   int ret;
15875   u32 mode = 0;
15876
15877   /* Parse args required to build the message */
15878   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15879     {
15880       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
15881         ;
15882       else
15883         break;
15884     }
15885
15886   /* Construct the API message */
15887   M (GPE_SET_ENCAP_MODE, mp);
15888
15889   mp->mode = mode;
15890
15891   /* send it... */
15892   S (mp);
15893
15894   /* Wait for a reply... */
15895   W (ret);
15896   return ret;
15897 }
15898
15899 static int
15900 api_lisp_gpe_add_del_iface (vat_main_t * vam)
15901 {
15902   unformat_input_t *input = vam->input;
15903   vl_api_gpe_add_del_iface_t *mp;
15904   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
15905   u32 dp_table = 0, vni = 0;
15906   int ret;
15907
15908   /* Parse args required to build the message */
15909   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15910     {
15911       if (unformat (input, "up"))
15912         {
15913           action_set = 1;
15914           is_add = 1;
15915         }
15916       else if (unformat (input, "down"))
15917         {
15918           action_set = 1;
15919           is_add = 0;
15920         }
15921       else if (unformat (input, "table_id %d", &dp_table))
15922         {
15923           dp_table_set = 1;
15924         }
15925       else if (unformat (input, "bd_id %d", &dp_table))
15926         {
15927           dp_table_set = 1;
15928           is_l2 = 1;
15929         }
15930       else if (unformat (input, "vni %d", &vni))
15931         {
15932           vni_set = 1;
15933         }
15934       else
15935         break;
15936     }
15937
15938   if (action_set == 0)
15939     {
15940       errmsg ("Action not set");
15941       return -99;
15942     }
15943   if (dp_table_set == 0 || vni_set == 0)
15944     {
15945       errmsg ("vni and dp_table must be set");
15946       return -99;
15947     }
15948
15949   /* Construct the API message */
15950   M (GPE_ADD_DEL_IFACE, mp);
15951
15952   mp->is_add = is_add;
15953   mp->dp_table = dp_table;
15954   mp->is_l2 = is_l2;
15955   mp->vni = vni;
15956
15957   /* send it... */
15958   S (mp);
15959
15960   /* Wait for a reply... */
15961   W (ret);
15962   return ret;
15963 }
15964
15965 /**
15966  * Add/del map request itr rlocs from ONE control plane and updates
15967  *
15968  * @param vam vpp API test context
15969  * @return return code
15970  */
15971 static int
15972 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
15973 {
15974   unformat_input_t *input = vam->input;
15975   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
15976   u8 *locator_set_name = 0;
15977   u8 locator_set_name_set = 0;
15978   u8 is_add = 1;
15979   int ret;
15980
15981   /* Parse args required to build the message */
15982   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15983     {
15984       if (unformat (input, "del"))
15985         {
15986           is_add = 0;
15987         }
15988       else if (unformat (input, "%_%v%_", &locator_set_name))
15989         {
15990           locator_set_name_set = 1;
15991         }
15992       else
15993         {
15994           clib_warning ("parse error '%U'", format_unformat_error, input);
15995           return -99;
15996         }
15997     }
15998
15999   if (is_add && !locator_set_name_set)
16000     {
16001       errmsg ("itr-rloc is not set!");
16002       return -99;
16003     }
16004
16005   if (is_add && vec_len (locator_set_name) > 64)
16006     {
16007       errmsg ("itr-rloc locator-set name too long");
16008       vec_free (locator_set_name);
16009       return -99;
16010     }
16011
16012   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
16013   mp->is_add = is_add;
16014   if (is_add)
16015     {
16016       clib_memcpy (mp->locator_set_name, locator_set_name,
16017                    vec_len (locator_set_name));
16018     }
16019   else
16020     {
16021       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
16022     }
16023   vec_free (locator_set_name);
16024
16025   /* send it... */
16026   S (mp);
16027
16028   /* Wait for a reply... */
16029   W (ret);
16030   return ret;
16031 }
16032
16033 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
16034
16035 static int
16036 api_one_locator_dump (vat_main_t * vam)
16037 {
16038   unformat_input_t *input = vam->input;
16039   vl_api_one_locator_dump_t *mp;
16040   vl_api_control_ping_t *mp_ping;
16041   u8 is_index_set = 0, is_name_set = 0;
16042   u8 *ls_name = 0;
16043   u32 ls_index = ~0;
16044   int ret;
16045
16046   /* Parse args required to build the message */
16047   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16048     {
16049       if (unformat (input, "ls_name %_%v%_", &ls_name))
16050         {
16051           is_name_set = 1;
16052         }
16053       else if (unformat (input, "ls_index %d", &ls_index))
16054         {
16055           is_index_set = 1;
16056         }
16057       else
16058         {
16059           errmsg ("parse error '%U'", format_unformat_error, input);
16060           return -99;
16061         }
16062     }
16063
16064   if (!is_index_set && !is_name_set)
16065     {
16066       errmsg ("error: expected one of index or name!");
16067       return -99;
16068     }
16069
16070   if (is_index_set && is_name_set)
16071     {
16072       errmsg ("error: only one param expected!");
16073       return -99;
16074     }
16075
16076   if (vec_len (ls_name) > 62)
16077     {
16078       errmsg ("error: locator set name too long!");
16079       return -99;
16080     }
16081
16082   if (!vam->json_output)
16083     {
16084       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
16085     }
16086
16087   M (ONE_LOCATOR_DUMP, mp);
16088   mp->is_index_set = is_index_set;
16089
16090   if (is_index_set)
16091     mp->ls_index = clib_host_to_net_u32 (ls_index);
16092   else
16093     {
16094       vec_add1 (ls_name, 0);
16095       strncpy ((char *) mp->ls_name, (char *) ls_name,
16096                sizeof (mp->ls_name) - 1);
16097     }
16098
16099   /* send it... */
16100   S (mp);
16101
16102   /* Use a control ping for synchronization */
16103   M (CONTROL_PING, mp_ping);
16104   S (mp_ping);
16105
16106   /* Wait for a reply... */
16107   W (ret);
16108   return ret;
16109 }
16110
16111 #define api_lisp_locator_dump api_one_locator_dump
16112
16113 static int
16114 api_one_locator_set_dump (vat_main_t * vam)
16115 {
16116   vl_api_one_locator_set_dump_t *mp;
16117   vl_api_control_ping_t *mp_ping;
16118   unformat_input_t *input = vam->input;
16119   u8 filter = 0;
16120   int ret;
16121
16122   /* Parse args required to build the message */
16123   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16124     {
16125       if (unformat (input, "local"))
16126         {
16127           filter = 1;
16128         }
16129       else if (unformat (input, "remote"))
16130         {
16131           filter = 2;
16132         }
16133       else
16134         {
16135           errmsg ("parse error '%U'", format_unformat_error, input);
16136           return -99;
16137         }
16138     }
16139
16140   if (!vam->json_output)
16141     {
16142       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
16143     }
16144
16145   M (ONE_LOCATOR_SET_DUMP, mp);
16146
16147   mp->filter = filter;
16148
16149   /* send it... */
16150   S (mp);
16151
16152   /* Use a control ping for synchronization */
16153   M (CONTROL_PING, mp_ping);
16154   S (mp_ping);
16155
16156   /* Wait for a reply... */
16157   W (ret);
16158   return ret;
16159 }
16160
16161 #define api_lisp_locator_set_dump api_one_locator_set_dump
16162
16163 static int
16164 api_one_eid_table_map_dump (vat_main_t * vam)
16165 {
16166   u8 is_l2 = 0;
16167   u8 mode_set = 0;
16168   unformat_input_t *input = vam->input;
16169   vl_api_one_eid_table_map_dump_t *mp;
16170   vl_api_control_ping_t *mp_ping;
16171   int ret;
16172
16173   /* Parse args required to build the message */
16174   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16175     {
16176       if (unformat (input, "l2"))
16177         {
16178           is_l2 = 1;
16179           mode_set = 1;
16180         }
16181       else if (unformat (input, "l3"))
16182         {
16183           is_l2 = 0;
16184           mode_set = 1;
16185         }
16186       else
16187         {
16188           errmsg ("parse error '%U'", format_unformat_error, input);
16189           return -99;
16190         }
16191     }
16192
16193   if (!mode_set)
16194     {
16195       errmsg ("expected one of 'l2' or 'l3' parameter!");
16196       return -99;
16197     }
16198
16199   if (!vam->json_output)
16200     {
16201       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
16202     }
16203
16204   M (ONE_EID_TABLE_MAP_DUMP, mp);
16205   mp->is_l2 = is_l2;
16206
16207   /* send it... */
16208   S (mp);
16209
16210   /* Use a control ping for synchronization */
16211   M (CONTROL_PING, mp_ping);
16212   S (mp_ping);
16213
16214   /* Wait for a reply... */
16215   W (ret);
16216   return ret;
16217 }
16218
16219 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
16220
16221 static int
16222 api_one_eid_table_vni_dump (vat_main_t * vam)
16223 {
16224   vl_api_one_eid_table_vni_dump_t *mp;
16225   vl_api_control_ping_t *mp_ping;
16226   int ret;
16227
16228   if (!vam->json_output)
16229     {
16230       print (vam->ofp, "VNI");
16231     }
16232
16233   M (ONE_EID_TABLE_VNI_DUMP, mp);
16234
16235   /* send it... */
16236   S (mp);
16237
16238   /* Use a control ping for synchronization */
16239   M (CONTROL_PING, mp_ping);
16240   S (mp_ping);
16241
16242   /* Wait for a reply... */
16243   W (ret);
16244   return ret;
16245 }
16246
16247 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
16248
16249 static int
16250 api_one_eid_table_dump (vat_main_t * vam)
16251 {
16252   unformat_input_t *i = vam->input;
16253   vl_api_one_eid_table_dump_t *mp;
16254   vl_api_control_ping_t *mp_ping;
16255   struct in_addr ip4;
16256   struct in6_addr ip6;
16257   u8 mac[6];
16258   u8 eid_type = ~0, eid_set = 0;
16259   u32 prefix_length = ~0, t, vni = 0;
16260   u8 filter = 0;
16261   int ret;
16262   lisp_nsh_api_t nsh;
16263
16264   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16265     {
16266       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
16267         {
16268           eid_set = 1;
16269           eid_type = 0;
16270           prefix_length = t;
16271         }
16272       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
16273         {
16274           eid_set = 1;
16275           eid_type = 1;
16276           prefix_length = t;
16277         }
16278       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
16279         {
16280           eid_set = 1;
16281           eid_type = 2;
16282         }
16283       else if (unformat (i, "eid %U", unformat_nsh_address, &nsh))
16284         {
16285           eid_set = 1;
16286           eid_type = 3;
16287         }
16288       else if (unformat (i, "vni %d", &t))
16289         {
16290           vni = t;
16291         }
16292       else if (unformat (i, "local"))
16293         {
16294           filter = 1;
16295         }
16296       else if (unformat (i, "remote"))
16297         {
16298           filter = 2;
16299         }
16300       else
16301         {
16302           errmsg ("parse error '%U'", format_unformat_error, i);
16303           return -99;
16304         }
16305     }
16306
16307   if (!vam->json_output)
16308     {
16309       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
16310              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
16311     }
16312
16313   M (ONE_EID_TABLE_DUMP, mp);
16314
16315   mp->filter = filter;
16316   if (eid_set)
16317     {
16318       mp->eid_set = 1;
16319       mp->vni = htonl (vni);
16320       mp->eid_type = eid_type;
16321       switch (eid_type)
16322         {
16323         case 0:
16324           mp->prefix_length = prefix_length;
16325           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
16326           break;
16327         case 1:
16328           mp->prefix_length = prefix_length;
16329           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
16330           break;
16331         case 2:
16332           clib_memcpy (mp->eid, mac, sizeof (mac));
16333           break;
16334         case 3:
16335           clib_memcpy (mp->eid, &nsh, sizeof (nsh));
16336           break;
16337         default:
16338           errmsg ("unknown EID type %d!", eid_type);
16339           return -99;
16340         }
16341     }
16342
16343   /* send it... */
16344   S (mp);
16345
16346   /* Use a control ping for synchronization */
16347   M (CONTROL_PING, mp_ping);
16348   S (mp_ping);
16349
16350   /* Wait for a reply... */
16351   W (ret);
16352   return ret;
16353 }
16354
16355 #define api_lisp_eid_table_dump api_one_eid_table_dump
16356
16357 static int
16358 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
16359 {
16360   unformat_input_t *i = vam->input;
16361   vl_api_gpe_fwd_entries_get_t *mp;
16362   u8 vni_set = 0;
16363   u32 vni = ~0;
16364   int ret;
16365
16366   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16367     {
16368       if (unformat (i, "vni %d", &vni))
16369         {
16370           vni_set = 1;
16371         }
16372       else
16373         {
16374           errmsg ("parse error '%U'", format_unformat_error, i);
16375           return -99;
16376         }
16377     }
16378
16379   if (!vni_set)
16380     {
16381       errmsg ("vni not set!");
16382       return -99;
16383     }
16384
16385   if (!vam->json_output)
16386     {
16387       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
16388              "leid", "reid");
16389     }
16390
16391   M (GPE_FWD_ENTRIES_GET, mp);
16392   mp->vni = clib_host_to_net_u32 (vni);
16393
16394   /* send it... */
16395   S (mp);
16396
16397   /* Wait for a reply... */
16398   W (ret);
16399   return ret;
16400 }
16401
16402 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
16403 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
16404 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
16405 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
16406 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
16407 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
16408 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
16409 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
16410
16411 static int
16412 api_one_adjacencies_get (vat_main_t * vam)
16413 {
16414   unformat_input_t *i = vam->input;
16415   vl_api_one_adjacencies_get_t *mp;
16416   u8 vni_set = 0;
16417   u32 vni = ~0;
16418   int ret;
16419
16420   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16421     {
16422       if (unformat (i, "vni %d", &vni))
16423         {
16424           vni_set = 1;
16425         }
16426       else
16427         {
16428           errmsg ("parse error '%U'", format_unformat_error, i);
16429           return -99;
16430         }
16431     }
16432
16433   if (!vni_set)
16434     {
16435       errmsg ("vni not set!");
16436       return -99;
16437     }
16438
16439   if (!vam->json_output)
16440     {
16441       print (vam->ofp, "%s %40s", "leid", "reid");
16442     }
16443
16444   M (ONE_ADJACENCIES_GET, mp);
16445   mp->vni = clib_host_to_net_u32 (vni);
16446
16447   /* send it... */
16448   S (mp);
16449
16450   /* Wait for a reply... */
16451   W (ret);
16452   return ret;
16453 }
16454
16455 #define api_lisp_adjacencies_get api_one_adjacencies_get
16456
16457 static int
16458 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
16459 {
16460   unformat_input_t *i = vam->input;
16461   vl_api_gpe_native_fwd_rpaths_get_t *mp;
16462   int ret;
16463   u8 ip_family_set = 0, is_ip4 = 1;
16464
16465   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16466     {
16467       if (unformat (i, "ip4"))
16468         {
16469           ip_family_set = 1;
16470           is_ip4 = 1;
16471         }
16472       else if (unformat (i, "ip6"))
16473         {
16474           ip_family_set = 1;
16475           is_ip4 = 0;
16476         }
16477       else
16478         {
16479           errmsg ("parse error '%U'", format_unformat_error, i);
16480           return -99;
16481         }
16482     }
16483
16484   if (!ip_family_set)
16485     {
16486       errmsg ("ip family not set!");
16487       return -99;
16488     }
16489
16490   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
16491   mp->is_ip4 = is_ip4;
16492
16493   /* send it... */
16494   S (mp);
16495
16496   /* Wait for a reply... */
16497   W (ret);
16498   return ret;
16499 }
16500
16501 static int
16502 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
16503 {
16504   vl_api_gpe_fwd_entry_vnis_get_t *mp;
16505   int ret;
16506
16507   if (!vam->json_output)
16508     {
16509       print (vam->ofp, "VNIs");
16510     }
16511
16512   M (GPE_FWD_ENTRY_VNIS_GET, mp);
16513
16514   /* send it... */
16515   S (mp);
16516
16517   /* Wait for a reply... */
16518   W (ret);
16519   return ret;
16520 }
16521
16522 static int
16523 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
16524 {
16525   unformat_input_t *i = vam->input;
16526   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
16527   int ret = 0;
16528   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
16529   struct in_addr ip4;
16530   struct in6_addr ip6;
16531   u32 table_id = 0, nh_sw_if_index = ~0;
16532
16533   memset (&ip4, 0, sizeof (ip4));
16534   memset (&ip6, 0, sizeof (ip6));
16535
16536   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16537     {
16538       if (unformat (i, "del"))
16539         is_add = 0;
16540       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
16541                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
16542         {
16543           ip_set = 1;
16544           is_ip4 = 1;
16545         }
16546       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
16547                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
16548         {
16549           ip_set = 1;
16550           is_ip4 = 0;
16551         }
16552       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
16553         {
16554           ip_set = 1;
16555           is_ip4 = 1;
16556           nh_sw_if_index = ~0;
16557         }
16558       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
16559         {
16560           ip_set = 1;
16561           is_ip4 = 0;
16562           nh_sw_if_index = ~0;
16563         }
16564       else if (unformat (i, "table %d", &table_id))
16565         ;
16566       else
16567         {
16568           errmsg ("parse error '%U'", format_unformat_error, i);
16569           return -99;
16570         }
16571     }
16572
16573   if (!ip_set)
16574     {
16575       errmsg ("nh addr not set!");
16576       return -99;
16577     }
16578
16579   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
16580   mp->is_add = is_add;
16581   mp->table_id = clib_host_to_net_u32 (table_id);
16582   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
16583   mp->is_ip4 = is_ip4;
16584   if (is_ip4)
16585     clib_memcpy (mp->nh_addr, &ip4, sizeof (ip4));
16586   else
16587     clib_memcpy (mp->nh_addr, &ip6, sizeof (ip6));
16588
16589   /* send it... */
16590   S (mp);
16591
16592   /* Wait for a reply... */
16593   W (ret);
16594   return ret;
16595 }
16596
16597 static int
16598 api_one_map_server_dump (vat_main_t * vam)
16599 {
16600   vl_api_one_map_server_dump_t *mp;
16601   vl_api_control_ping_t *mp_ping;
16602   int ret;
16603
16604   if (!vam->json_output)
16605     {
16606       print (vam->ofp, "%=20s", "Map server");
16607     }
16608
16609   M (ONE_MAP_SERVER_DUMP, mp);
16610   /* send it... */
16611   S (mp);
16612
16613   /* Use a control ping for synchronization */
16614   M (CONTROL_PING, mp_ping);
16615   S (mp_ping);
16616
16617   /* Wait for a reply... */
16618   W (ret);
16619   return ret;
16620 }
16621
16622 #define api_lisp_map_server_dump api_one_map_server_dump
16623
16624 static int
16625 api_one_map_resolver_dump (vat_main_t * vam)
16626 {
16627   vl_api_one_map_resolver_dump_t *mp;
16628   vl_api_control_ping_t *mp_ping;
16629   int ret;
16630
16631   if (!vam->json_output)
16632     {
16633       print (vam->ofp, "%=20s", "Map resolver");
16634     }
16635
16636   M (ONE_MAP_RESOLVER_DUMP, mp);
16637   /* send it... */
16638   S (mp);
16639
16640   /* Use a control ping for synchronization */
16641   M (CONTROL_PING, mp_ping);
16642   S (mp_ping);
16643
16644   /* Wait for a reply... */
16645   W (ret);
16646   return ret;
16647 }
16648
16649 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
16650
16651 static int
16652 api_one_stats_flush (vat_main_t * vam)
16653 {
16654   vl_api_one_stats_flush_t *mp;
16655   int ret = 0;
16656
16657   M (ONE_STATS_FLUSH, mp);
16658   S (mp);
16659   W (ret);
16660   return ret;
16661 }
16662
16663 static int
16664 api_one_stats_dump (vat_main_t * vam)
16665 {
16666   vl_api_one_stats_dump_t *mp;
16667   vl_api_control_ping_t *mp_ping;
16668   int ret;
16669
16670   M (ONE_STATS_DUMP, mp);
16671   /* send it... */
16672   S (mp);
16673
16674   /* Use a control ping for synchronization */
16675   M (CONTROL_PING, mp_ping);
16676   S (mp_ping);
16677
16678   /* Wait for a reply... */
16679   W (ret);
16680   return ret;
16681 }
16682
16683 static int
16684 api_show_one_status (vat_main_t * vam)
16685 {
16686   vl_api_show_one_status_t *mp;
16687   int ret;
16688
16689   if (!vam->json_output)
16690     {
16691       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
16692     }
16693
16694   M (SHOW_ONE_STATUS, mp);
16695   /* send it... */
16696   S (mp);
16697   /* Wait for a reply... */
16698   W (ret);
16699   return ret;
16700 }
16701
16702 #define api_show_lisp_status api_show_one_status
16703
16704 static int
16705 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
16706 {
16707   vl_api_gpe_fwd_entry_path_dump_t *mp;
16708   vl_api_control_ping_t *mp_ping;
16709   unformat_input_t *i = vam->input;
16710   u32 fwd_entry_index = ~0;
16711   int ret;
16712
16713   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16714     {
16715       if (unformat (i, "index %d", &fwd_entry_index))
16716         ;
16717       else
16718         break;
16719     }
16720
16721   if (~0 == fwd_entry_index)
16722     {
16723       errmsg ("no index specified!");
16724       return -99;
16725     }
16726
16727   if (!vam->json_output)
16728     {
16729       print (vam->ofp, "first line");
16730     }
16731
16732   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
16733
16734   /* send it... */
16735   S (mp);
16736   /* Use a control ping for synchronization */
16737   M (CONTROL_PING, mp_ping);
16738   S (mp_ping);
16739
16740   /* Wait for a reply... */
16741   W (ret);
16742   return ret;
16743 }
16744
16745 static int
16746 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
16747 {
16748   vl_api_one_get_map_request_itr_rlocs_t *mp;
16749   int ret;
16750
16751   if (!vam->json_output)
16752     {
16753       print (vam->ofp, "%=20s", "itr-rlocs:");
16754     }
16755
16756   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
16757   /* send it... */
16758   S (mp);
16759   /* Wait for a reply... */
16760   W (ret);
16761   return ret;
16762 }
16763
16764 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
16765
16766 static int
16767 api_af_packet_create (vat_main_t * vam)
16768 {
16769   unformat_input_t *i = vam->input;
16770   vl_api_af_packet_create_t *mp;
16771   u8 *host_if_name = 0;
16772   u8 hw_addr[6];
16773   u8 random_hw_addr = 1;
16774   int ret;
16775
16776   memset (hw_addr, 0, sizeof (hw_addr));
16777
16778   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16779     {
16780       if (unformat (i, "name %s", &host_if_name))
16781         vec_add1 (host_if_name, 0);
16782       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
16783         random_hw_addr = 0;
16784       else
16785         break;
16786     }
16787
16788   if (!vec_len (host_if_name))
16789     {
16790       errmsg ("host-interface name must be specified");
16791       return -99;
16792     }
16793
16794   if (vec_len (host_if_name) > 64)
16795     {
16796       errmsg ("host-interface name too long");
16797       return -99;
16798     }
16799
16800   M (AF_PACKET_CREATE, mp);
16801
16802   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
16803   clib_memcpy (mp->hw_addr, hw_addr, 6);
16804   mp->use_random_hw_addr = random_hw_addr;
16805   vec_free (host_if_name);
16806
16807   S (mp);
16808
16809   /* *INDENT-OFF* */
16810   W2 (ret,
16811       ({
16812         if (ret == 0)
16813           fprintf (vam->ofp ? vam->ofp : stderr,
16814                    " new sw_if_index = %d\n", vam->sw_if_index);
16815       }));
16816   /* *INDENT-ON* */
16817   return ret;
16818 }
16819
16820 static int
16821 api_af_packet_delete (vat_main_t * vam)
16822 {
16823   unformat_input_t *i = vam->input;
16824   vl_api_af_packet_delete_t *mp;
16825   u8 *host_if_name = 0;
16826   int ret;
16827
16828   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16829     {
16830       if (unformat (i, "name %s", &host_if_name))
16831         vec_add1 (host_if_name, 0);
16832       else
16833         break;
16834     }
16835
16836   if (!vec_len (host_if_name))
16837     {
16838       errmsg ("host-interface name must be specified");
16839       return -99;
16840     }
16841
16842   if (vec_len (host_if_name) > 64)
16843     {
16844       errmsg ("host-interface name too long");
16845       return -99;
16846     }
16847
16848   M (AF_PACKET_DELETE, mp);
16849
16850   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
16851   vec_free (host_if_name);
16852
16853   S (mp);
16854   W (ret);
16855   return ret;
16856 }
16857
16858 static int
16859 api_policer_add_del (vat_main_t * vam)
16860 {
16861   unformat_input_t *i = vam->input;
16862   vl_api_policer_add_del_t *mp;
16863   u8 is_add = 1;
16864   u8 *name = 0;
16865   u32 cir = 0;
16866   u32 eir = 0;
16867   u64 cb = 0;
16868   u64 eb = 0;
16869   u8 rate_type = 0;
16870   u8 round_type = 0;
16871   u8 type = 0;
16872   u8 color_aware = 0;
16873   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
16874   int ret;
16875
16876   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
16877   conform_action.dscp = 0;
16878   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
16879   exceed_action.dscp = 0;
16880   violate_action.action_type = SSE2_QOS_ACTION_DROP;
16881   violate_action.dscp = 0;
16882
16883   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16884     {
16885       if (unformat (i, "del"))
16886         is_add = 0;
16887       else if (unformat (i, "name %s", &name))
16888         vec_add1 (name, 0);
16889       else if (unformat (i, "cir %u", &cir))
16890         ;
16891       else if (unformat (i, "eir %u", &eir))
16892         ;
16893       else if (unformat (i, "cb %u", &cb))
16894         ;
16895       else if (unformat (i, "eb %u", &eb))
16896         ;
16897       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
16898                          &rate_type))
16899         ;
16900       else if (unformat (i, "round_type %U", unformat_policer_round_type,
16901                          &round_type))
16902         ;
16903       else if (unformat (i, "type %U", unformat_policer_type, &type))
16904         ;
16905       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
16906                          &conform_action))
16907         ;
16908       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
16909                          &exceed_action))
16910         ;
16911       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
16912                          &violate_action))
16913         ;
16914       else if (unformat (i, "color-aware"))
16915         color_aware = 1;
16916       else
16917         break;
16918     }
16919
16920   if (!vec_len (name))
16921     {
16922       errmsg ("policer name must be specified");
16923       return -99;
16924     }
16925
16926   if (vec_len (name) > 64)
16927     {
16928       errmsg ("policer name too long");
16929       return -99;
16930     }
16931
16932   M (POLICER_ADD_DEL, mp);
16933
16934   clib_memcpy (mp->name, name, vec_len (name));
16935   vec_free (name);
16936   mp->is_add = is_add;
16937   mp->cir = cir;
16938   mp->eir = eir;
16939   mp->cb = cb;
16940   mp->eb = eb;
16941   mp->rate_type = rate_type;
16942   mp->round_type = round_type;
16943   mp->type = type;
16944   mp->conform_action_type = conform_action.action_type;
16945   mp->conform_dscp = conform_action.dscp;
16946   mp->exceed_action_type = exceed_action.action_type;
16947   mp->exceed_dscp = exceed_action.dscp;
16948   mp->violate_action_type = violate_action.action_type;
16949   mp->violate_dscp = violate_action.dscp;
16950   mp->color_aware = color_aware;
16951
16952   S (mp);
16953   W (ret);
16954   return ret;
16955 }
16956
16957 static int
16958 api_policer_dump (vat_main_t * vam)
16959 {
16960   unformat_input_t *i = vam->input;
16961   vl_api_policer_dump_t *mp;
16962   vl_api_control_ping_t *mp_ping;
16963   u8 *match_name = 0;
16964   u8 match_name_valid = 0;
16965   int ret;
16966
16967   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16968     {
16969       if (unformat (i, "name %s", &match_name))
16970         {
16971           vec_add1 (match_name, 0);
16972           match_name_valid = 1;
16973         }
16974       else
16975         break;
16976     }
16977
16978   M (POLICER_DUMP, mp);
16979   mp->match_name_valid = match_name_valid;
16980   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
16981   vec_free (match_name);
16982   /* send it... */
16983   S (mp);
16984
16985   /* Use a control ping for synchronization */
16986   M (CONTROL_PING, mp_ping);
16987   S (mp_ping);
16988
16989   /* Wait for a reply... */
16990   W (ret);
16991   return ret;
16992 }
16993
16994 static int
16995 api_policer_classify_set_interface (vat_main_t * vam)
16996 {
16997   unformat_input_t *i = vam->input;
16998   vl_api_policer_classify_set_interface_t *mp;
16999   u32 sw_if_index;
17000   int sw_if_index_set;
17001   u32 ip4_table_index = ~0;
17002   u32 ip6_table_index = ~0;
17003   u32 l2_table_index = ~0;
17004   u8 is_add = 1;
17005   int ret;
17006
17007   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17008     {
17009       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17010         sw_if_index_set = 1;
17011       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17012         sw_if_index_set = 1;
17013       else if (unformat (i, "del"))
17014         is_add = 0;
17015       else if (unformat (i, "ip4-table %d", &ip4_table_index))
17016         ;
17017       else if (unformat (i, "ip6-table %d", &ip6_table_index))
17018         ;
17019       else if (unformat (i, "l2-table %d", &l2_table_index))
17020         ;
17021       else
17022         {
17023           clib_warning ("parse error '%U'", format_unformat_error, i);
17024           return -99;
17025         }
17026     }
17027
17028   if (sw_if_index_set == 0)
17029     {
17030       errmsg ("missing interface name or sw_if_index");
17031       return -99;
17032     }
17033
17034   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
17035
17036   mp->sw_if_index = ntohl (sw_if_index);
17037   mp->ip4_table_index = ntohl (ip4_table_index);
17038   mp->ip6_table_index = ntohl (ip6_table_index);
17039   mp->l2_table_index = ntohl (l2_table_index);
17040   mp->is_add = is_add;
17041
17042   S (mp);
17043   W (ret);
17044   return ret;
17045 }
17046
17047 static int
17048 api_policer_classify_dump (vat_main_t * vam)
17049 {
17050   unformat_input_t *i = vam->input;
17051   vl_api_policer_classify_dump_t *mp;
17052   vl_api_control_ping_t *mp_ping;
17053   u8 type = POLICER_CLASSIFY_N_TABLES;
17054   int ret;
17055
17056   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
17057     ;
17058   else
17059     {
17060       errmsg ("classify table type must be specified");
17061       return -99;
17062     }
17063
17064   if (!vam->json_output)
17065     {
17066       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
17067     }
17068
17069   M (POLICER_CLASSIFY_DUMP, mp);
17070   mp->type = type;
17071   /* send it... */
17072   S (mp);
17073
17074   /* Use a control ping for synchronization */
17075   M (CONTROL_PING, mp_ping);
17076   S (mp_ping);
17077
17078   /* Wait for a reply... */
17079   W (ret);
17080   return ret;
17081 }
17082
17083 static int
17084 api_netmap_create (vat_main_t * vam)
17085 {
17086   unformat_input_t *i = vam->input;
17087   vl_api_netmap_create_t *mp;
17088   u8 *if_name = 0;
17089   u8 hw_addr[6];
17090   u8 random_hw_addr = 1;
17091   u8 is_pipe = 0;
17092   u8 is_master = 0;
17093   int ret;
17094
17095   memset (hw_addr, 0, sizeof (hw_addr));
17096
17097   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17098     {
17099       if (unformat (i, "name %s", &if_name))
17100         vec_add1 (if_name, 0);
17101       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
17102         random_hw_addr = 0;
17103       else if (unformat (i, "pipe"))
17104         is_pipe = 1;
17105       else if (unformat (i, "master"))
17106         is_master = 1;
17107       else if (unformat (i, "slave"))
17108         is_master = 0;
17109       else
17110         break;
17111     }
17112
17113   if (!vec_len (if_name))
17114     {
17115       errmsg ("interface name must be specified");
17116       return -99;
17117     }
17118
17119   if (vec_len (if_name) > 64)
17120     {
17121       errmsg ("interface name too long");
17122       return -99;
17123     }
17124
17125   M (NETMAP_CREATE, mp);
17126
17127   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
17128   clib_memcpy (mp->hw_addr, hw_addr, 6);
17129   mp->use_random_hw_addr = random_hw_addr;
17130   mp->is_pipe = is_pipe;
17131   mp->is_master = is_master;
17132   vec_free (if_name);
17133
17134   S (mp);
17135   W (ret);
17136   return ret;
17137 }
17138
17139 static int
17140 api_netmap_delete (vat_main_t * vam)
17141 {
17142   unformat_input_t *i = vam->input;
17143   vl_api_netmap_delete_t *mp;
17144   u8 *if_name = 0;
17145   int ret;
17146
17147   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17148     {
17149       if (unformat (i, "name %s", &if_name))
17150         vec_add1 (if_name, 0);
17151       else
17152         break;
17153     }
17154
17155   if (!vec_len (if_name))
17156     {
17157       errmsg ("interface name must be specified");
17158       return -99;
17159     }
17160
17161   if (vec_len (if_name) > 64)
17162     {
17163       errmsg ("interface name too long");
17164       return -99;
17165     }
17166
17167   M (NETMAP_DELETE, mp);
17168
17169   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
17170   vec_free (if_name);
17171
17172   S (mp);
17173   W (ret);
17174   return ret;
17175 }
17176
17177 static void
17178 vl_api_mpls_fib_path_print (vat_main_t * vam, vl_api_fib_path2_t * fp)
17179 {
17180   if (fp->afi == IP46_TYPE_IP6)
17181     print (vam->ofp,
17182            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
17183            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
17184            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
17185            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
17186            format_ip6_address, fp->next_hop);
17187   else if (fp->afi == IP46_TYPE_IP4)
17188     print (vam->ofp,
17189            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
17190            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
17191            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
17192            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
17193            format_ip4_address, fp->next_hop);
17194 }
17195
17196 static void
17197 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
17198                                  vl_api_fib_path2_t * fp)
17199 {
17200   struct in_addr ip4;
17201   struct in6_addr ip6;
17202
17203   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
17204   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
17205   vat_json_object_add_uint (node, "is_local", fp->is_local);
17206   vat_json_object_add_uint (node, "is_drop", fp->is_drop);
17207   vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
17208   vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
17209   vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
17210   if (fp->afi == IP46_TYPE_IP4)
17211     {
17212       clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
17213       vat_json_object_add_ip4 (node, "next_hop", ip4);
17214     }
17215   else if (fp->afi == IP46_TYPE_IP6)
17216     {
17217       clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
17218       vat_json_object_add_ip6 (node, "next_hop", ip6);
17219     }
17220 }
17221
17222 static void
17223 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
17224 {
17225   vat_main_t *vam = &vat_main;
17226   int count = ntohl (mp->mt_count);
17227   vl_api_fib_path2_t *fp;
17228   i32 i;
17229
17230   print (vam->ofp, "[%d]: sw_if_index %d via:",
17231          ntohl (mp->mt_tunnel_index), ntohl (mp->mt_sw_if_index));
17232   fp = mp->mt_paths;
17233   for (i = 0; i < count; i++)
17234     {
17235       vl_api_mpls_fib_path_print (vam, fp);
17236       fp++;
17237     }
17238
17239   print (vam->ofp, "");
17240 }
17241
17242 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
17243 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
17244
17245 static void
17246 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
17247 {
17248   vat_main_t *vam = &vat_main;
17249   vat_json_node_t *node = NULL;
17250   int count = ntohl (mp->mt_count);
17251   vl_api_fib_path2_t *fp;
17252   i32 i;
17253
17254   if (VAT_JSON_ARRAY != vam->json_tree.type)
17255     {
17256       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17257       vat_json_init_array (&vam->json_tree);
17258     }
17259   node = vat_json_array_add (&vam->json_tree);
17260
17261   vat_json_init_object (node);
17262   vat_json_object_add_uint (node, "tunnel_index",
17263                             ntohl (mp->mt_tunnel_index));
17264   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->mt_sw_if_index));
17265
17266   vat_json_object_add_uint (node, "l2_only", mp->mt_l2_only);
17267
17268   fp = mp->mt_paths;
17269   for (i = 0; i < count; i++)
17270     {
17271       vl_api_mpls_fib_path_json_print (node, fp);
17272       fp++;
17273     }
17274 }
17275
17276 static int
17277 api_mpls_tunnel_dump (vat_main_t * vam)
17278 {
17279   vl_api_mpls_tunnel_dump_t *mp;
17280   vl_api_control_ping_t *mp_ping;
17281   i32 index = -1;
17282   int ret;
17283
17284   /* Parse args required to build the message */
17285   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
17286     {
17287       if (!unformat (vam->input, "tunnel_index %d", &index))
17288         {
17289           index = -1;
17290           break;
17291         }
17292     }
17293
17294   print (vam->ofp, "  tunnel_index %d", index);
17295
17296   M (MPLS_TUNNEL_DUMP, mp);
17297   mp->tunnel_index = htonl (index);
17298   S (mp);
17299
17300   /* Use a control ping for synchronization */
17301   M (CONTROL_PING, mp_ping);
17302   S (mp_ping);
17303
17304   W (ret);
17305   return ret;
17306 }
17307
17308 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
17309 #define vl_api_mpls_fib_details_t_print vl_noop_handler
17310
17311
17312 static void
17313 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
17314 {
17315   vat_main_t *vam = &vat_main;
17316   int count = ntohl (mp->count);
17317   vl_api_fib_path2_t *fp;
17318   int i;
17319
17320   print (vam->ofp,
17321          "table-id %d, label %u, ess_bit %u",
17322          ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
17323   fp = mp->path;
17324   for (i = 0; i < count; i++)
17325     {
17326       vl_api_mpls_fib_path_print (vam, fp);
17327       fp++;
17328     }
17329 }
17330
17331 static void vl_api_mpls_fib_details_t_handler_json
17332   (vl_api_mpls_fib_details_t * mp)
17333 {
17334   vat_main_t *vam = &vat_main;
17335   int count = ntohl (mp->count);
17336   vat_json_node_t *node = NULL;
17337   vl_api_fib_path2_t *fp;
17338   int i;
17339
17340   if (VAT_JSON_ARRAY != vam->json_tree.type)
17341     {
17342       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17343       vat_json_init_array (&vam->json_tree);
17344     }
17345   node = vat_json_array_add (&vam->json_tree);
17346
17347   vat_json_init_object (node);
17348   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
17349   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
17350   vat_json_object_add_uint (node, "label", ntohl (mp->label));
17351   vat_json_object_add_uint (node, "path_count", count);
17352   fp = mp->path;
17353   for (i = 0; i < count; i++)
17354     {
17355       vl_api_mpls_fib_path_json_print (node, fp);
17356       fp++;
17357     }
17358 }
17359
17360 static int
17361 api_mpls_fib_dump (vat_main_t * vam)
17362 {
17363   vl_api_mpls_fib_dump_t *mp;
17364   vl_api_control_ping_t *mp_ping;
17365   int ret;
17366
17367   M (MPLS_FIB_DUMP, mp);
17368   S (mp);
17369
17370   /* Use a control ping for synchronization */
17371   M (CONTROL_PING, mp_ping);
17372   S (mp_ping);
17373
17374   W (ret);
17375   return ret;
17376 }
17377
17378 #define vl_api_ip_fib_details_t_endian vl_noop_handler
17379 #define vl_api_ip_fib_details_t_print vl_noop_handler
17380
17381 static void
17382 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
17383 {
17384   vat_main_t *vam = &vat_main;
17385   int count = ntohl (mp->count);
17386   vl_api_fib_path_t *fp;
17387   int i;
17388
17389   print (vam->ofp,
17390          "table-id %d, prefix %U/%d",
17391          ntohl (mp->table_id), format_ip4_address, mp->address,
17392          mp->address_length);
17393   fp = mp->path;
17394   for (i = 0; i < count; i++)
17395     {
17396       if (fp->afi == IP46_TYPE_IP6)
17397         print (vam->ofp,
17398                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
17399                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
17400                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
17401                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
17402                format_ip6_address, fp->next_hop);
17403       else if (fp->afi == IP46_TYPE_IP4)
17404         print (vam->ofp,
17405                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
17406                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
17407                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
17408                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
17409                format_ip4_address, fp->next_hop);
17410       fp++;
17411     }
17412 }
17413
17414 static void vl_api_ip_fib_details_t_handler_json
17415   (vl_api_ip_fib_details_t * mp)
17416 {
17417   vat_main_t *vam = &vat_main;
17418   int count = ntohl (mp->count);
17419   vat_json_node_t *node = NULL;
17420   struct in_addr ip4;
17421   struct in6_addr ip6;
17422   vl_api_fib_path_t *fp;
17423   int i;
17424
17425   if (VAT_JSON_ARRAY != vam->json_tree.type)
17426     {
17427       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17428       vat_json_init_array (&vam->json_tree);
17429     }
17430   node = vat_json_array_add (&vam->json_tree);
17431
17432   vat_json_init_object (node);
17433   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
17434   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
17435   vat_json_object_add_ip4 (node, "prefix", ip4);
17436   vat_json_object_add_uint (node, "mask_length", mp->address_length);
17437   vat_json_object_add_uint (node, "path_count", count);
17438   fp = mp->path;
17439   for (i = 0; i < count; i++)
17440     {
17441       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
17442       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
17443       vat_json_object_add_uint (node, "is_local", fp->is_local);
17444       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
17445       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
17446       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
17447       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
17448       if (fp->afi == IP46_TYPE_IP4)
17449         {
17450           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
17451           vat_json_object_add_ip4 (node, "next_hop", ip4);
17452         }
17453       else if (fp->afi == IP46_TYPE_IP6)
17454         {
17455           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
17456           vat_json_object_add_ip6 (node, "next_hop", ip6);
17457         }
17458     }
17459 }
17460
17461 static int
17462 api_ip_fib_dump (vat_main_t * vam)
17463 {
17464   vl_api_ip_fib_dump_t *mp;
17465   vl_api_control_ping_t *mp_ping;
17466   int ret;
17467
17468   M (IP_FIB_DUMP, mp);
17469   S (mp);
17470
17471   /* Use a control ping for synchronization */
17472   M (CONTROL_PING, mp_ping);
17473   S (mp_ping);
17474
17475   W (ret);
17476   return ret;
17477 }
17478
17479 static int
17480 api_ip_mfib_dump (vat_main_t * vam)
17481 {
17482   vl_api_ip_mfib_dump_t *mp;
17483   vl_api_control_ping_t *mp_ping;
17484   int ret;
17485
17486   M (IP_MFIB_DUMP, mp);
17487   S (mp);
17488
17489   /* Use a control ping for synchronization */
17490   M (CONTROL_PING, mp_ping);
17491   S (mp_ping);
17492
17493   W (ret);
17494   return ret;
17495 }
17496
17497 static void vl_api_ip_neighbor_details_t_handler
17498   (vl_api_ip_neighbor_details_t * mp)
17499 {
17500   vat_main_t *vam = &vat_main;
17501
17502   print (vam->ofp, "%c %U %U",
17503          (mp->is_static) ? 'S' : 'D',
17504          format_ethernet_address, &mp->mac_address,
17505          (mp->is_ipv6) ? format_ip6_address : format_ip4_address,
17506          &mp->ip_address);
17507 }
17508
17509 static void vl_api_ip_neighbor_details_t_handler_json
17510   (vl_api_ip_neighbor_details_t * mp)
17511 {
17512
17513   vat_main_t *vam = &vat_main;
17514   vat_json_node_t *node;
17515   struct in_addr ip4;
17516   struct in6_addr ip6;
17517
17518   if (VAT_JSON_ARRAY != vam->json_tree.type)
17519     {
17520       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17521       vat_json_init_array (&vam->json_tree);
17522     }
17523   node = vat_json_array_add (&vam->json_tree);
17524
17525   vat_json_init_object (node);
17526   vat_json_object_add_string_copy (node, "flag",
17527                                    (mp->is_static) ? (u8 *) "static" : (u8 *)
17528                                    "dynamic");
17529
17530   vat_json_object_add_string_copy (node, "link_layer",
17531                                    format (0, "%U", format_ethernet_address,
17532                                            &mp->mac_address));
17533
17534   if (mp->is_ipv6)
17535     {
17536       clib_memcpy (&ip6, &mp->ip_address, sizeof (ip6));
17537       vat_json_object_add_ip6 (node, "ip_address", ip6);
17538     }
17539   else
17540     {
17541       clib_memcpy (&ip4, &mp->ip_address, sizeof (ip4));
17542       vat_json_object_add_ip4 (node, "ip_address", ip4);
17543     }
17544 }
17545
17546 static int
17547 api_ip_neighbor_dump (vat_main_t * vam)
17548 {
17549   unformat_input_t *i = vam->input;
17550   vl_api_ip_neighbor_dump_t *mp;
17551   vl_api_control_ping_t *mp_ping;
17552   u8 is_ipv6 = 0;
17553   u32 sw_if_index = ~0;
17554   int ret;
17555
17556   /* Parse args required to build the message */
17557   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17558     {
17559       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17560         ;
17561       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17562         ;
17563       else if (unformat (i, "ip6"))
17564         is_ipv6 = 1;
17565       else
17566         break;
17567     }
17568
17569   if (sw_if_index == ~0)
17570     {
17571       errmsg ("missing interface name or sw_if_index");
17572       return -99;
17573     }
17574
17575   M (IP_NEIGHBOR_DUMP, mp);
17576   mp->is_ipv6 = (u8) is_ipv6;
17577   mp->sw_if_index = ntohl (sw_if_index);
17578   S (mp);
17579
17580   /* Use a control ping for synchronization */
17581   M (CONTROL_PING, mp_ping);
17582   S (mp_ping);
17583
17584   W (ret);
17585   return ret;
17586 }
17587
17588 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
17589 #define vl_api_ip6_fib_details_t_print vl_noop_handler
17590
17591 static void
17592 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
17593 {
17594   vat_main_t *vam = &vat_main;
17595   int count = ntohl (mp->count);
17596   vl_api_fib_path_t *fp;
17597   int i;
17598
17599   print (vam->ofp,
17600          "table-id %d, prefix %U/%d",
17601          ntohl (mp->table_id), format_ip6_address, mp->address,
17602          mp->address_length);
17603   fp = mp->path;
17604   for (i = 0; i < count; i++)
17605     {
17606       if (fp->afi == IP46_TYPE_IP6)
17607         print (vam->ofp,
17608                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
17609                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
17610                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
17611                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
17612                format_ip6_address, fp->next_hop);
17613       else if (fp->afi == IP46_TYPE_IP4)
17614         print (vam->ofp,
17615                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
17616                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
17617                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
17618                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
17619                format_ip4_address, fp->next_hop);
17620       fp++;
17621     }
17622 }
17623
17624 static void vl_api_ip6_fib_details_t_handler_json
17625   (vl_api_ip6_fib_details_t * mp)
17626 {
17627   vat_main_t *vam = &vat_main;
17628   int count = ntohl (mp->count);
17629   vat_json_node_t *node = NULL;
17630   struct in_addr ip4;
17631   struct in6_addr ip6;
17632   vl_api_fib_path_t *fp;
17633   int i;
17634
17635   if (VAT_JSON_ARRAY != vam->json_tree.type)
17636     {
17637       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17638       vat_json_init_array (&vam->json_tree);
17639     }
17640   node = vat_json_array_add (&vam->json_tree);
17641
17642   vat_json_init_object (node);
17643   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
17644   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
17645   vat_json_object_add_ip6 (node, "prefix", ip6);
17646   vat_json_object_add_uint (node, "mask_length", mp->address_length);
17647   vat_json_object_add_uint (node, "path_count", count);
17648   fp = mp->path;
17649   for (i = 0; i < count; i++)
17650     {
17651       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
17652       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
17653       vat_json_object_add_uint (node, "is_local", fp->is_local);
17654       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
17655       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
17656       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
17657       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
17658       if (fp->afi == IP46_TYPE_IP4)
17659         {
17660           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
17661           vat_json_object_add_ip4 (node, "next_hop", ip4);
17662         }
17663       else if (fp->afi == IP46_TYPE_IP6)
17664         {
17665           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
17666           vat_json_object_add_ip6 (node, "next_hop", ip6);
17667         }
17668     }
17669 }
17670
17671 static int
17672 api_ip6_fib_dump (vat_main_t * vam)
17673 {
17674   vl_api_ip6_fib_dump_t *mp;
17675   vl_api_control_ping_t *mp_ping;
17676   int ret;
17677
17678   M (IP6_FIB_DUMP, mp);
17679   S (mp);
17680
17681   /* Use a control ping for synchronization */
17682   M (CONTROL_PING, mp_ping);
17683   S (mp_ping);
17684
17685   W (ret);
17686   return ret;
17687 }
17688
17689 static int
17690 api_ip6_mfib_dump (vat_main_t * vam)
17691 {
17692   vl_api_ip6_mfib_dump_t *mp;
17693   vl_api_control_ping_t *mp_ping;
17694   int ret;
17695
17696   M (IP6_MFIB_DUMP, mp);
17697   S (mp);
17698
17699   /* Use a control ping for synchronization */
17700   M (CONTROL_PING, mp_ping);
17701   S (mp_ping);
17702
17703   W (ret);
17704   return ret;
17705 }
17706
17707 int
17708 api_classify_table_ids (vat_main_t * vam)
17709 {
17710   vl_api_classify_table_ids_t *mp;
17711   int ret;
17712
17713   /* Construct the API message */
17714   M (CLASSIFY_TABLE_IDS, mp);
17715   mp->context = 0;
17716
17717   S (mp);
17718   W (ret);
17719   return ret;
17720 }
17721
17722 int
17723 api_classify_table_by_interface (vat_main_t * vam)
17724 {
17725   unformat_input_t *input = vam->input;
17726   vl_api_classify_table_by_interface_t *mp;
17727
17728   u32 sw_if_index = ~0;
17729   int ret;
17730   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17731     {
17732       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17733         ;
17734       else if (unformat (input, "sw_if_index %d", &sw_if_index))
17735         ;
17736       else
17737         break;
17738     }
17739   if (sw_if_index == ~0)
17740     {
17741       errmsg ("missing interface name or sw_if_index");
17742       return -99;
17743     }
17744
17745   /* Construct the API message */
17746   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
17747   mp->context = 0;
17748   mp->sw_if_index = ntohl (sw_if_index);
17749
17750   S (mp);
17751   W (ret);
17752   return ret;
17753 }
17754
17755 int
17756 api_classify_table_info (vat_main_t * vam)
17757 {
17758   unformat_input_t *input = vam->input;
17759   vl_api_classify_table_info_t *mp;
17760
17761   u32 table_id = ~0;
17762   int ret;
17763   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17764     {
17765       if (unformat (input, "table_id %d", &table_id))
17766         ;
17767       else
17768         break;
17769     }
17770   if (table_id == ~0)
17771     {
17772       errmsg ("missing table id");
17773       return -99;
17774     }
17775
17776   /* Construct the API message */
17777   M (CLASSIFY_TABLE_INFO, mp);
17778   mp->context = 0;
17779   mp->table_id = ntohl (table_id);
17780
17781   S (mp);
17782   W (ret);
17783   return ret;
17784 }
17785
17786 int
17787 api_classify_session_dump (vat_main_t * vam)
17788 {
17789   unformat_input_t *input = vam->input;
17790   vl_api_classify_session_dump_t *mp;
17791   vl_api_control_ping_t *mp_ping;
17792
17793   u32 table_id = ~0;
17794   int ret;
17795   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17796     {
17797       if (unformat (input, "table_id %d", &table_id))
17798         ;
17799       else
17800         break;
17801     }
17802   if (table_id == ~0)
17803     {
17804       errmsg ("missing table id");
17805       return -99;
17806     }
17807
17808   /* Construct the API message */
17809   M (CLASSIFY_SESSION_DUMP, mp);
17810   mp->context = 0;
17811   mp->table_id = ntohl (table_id);
17812   S (mp);
17813
17814   /* Use a control ping for synchronization */
17815   M (CONTROL_PING, mp_ping);
17816   S (mp_ping);
17817
17818   W (ret);
17819   return ret;
17820 }
17821
17822 static void
17823 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
17824 {
17825   vat_main_t *vam = &vat_main;
17826
17827   print (vam->ofp, "collector_address %U, collector_port %d, "
17828          "src_address %U, vrf_id %d, path_mtu %u, "
17829          "template_interval %u, udp_checksum %d",
17830          format_ip4_address, mp->collector_address,
17831          ntohs (mp->collector_port),
17832          format_ip4_address, mp->src_address,
17833          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
17834          ntohl (mp->template_interval), mp->udp_checksum);
17835
17836   vam->retval = 0;
17837   vam->result_ready = 1;
17838 }
17839
17840 static void
17841   vl_api_ipfix_exporter_details_t_handler_json
17842   (vl_api_ipfix_exporter_details_t * mp)
17843 {
17844   vat_main_t *vam = &vat_main;
17845   vat_json_node_t node;
17846   struct in_addr collector_address;
17847   struct in_addr src_address;
17848
17849   vat_json_init_object (&node);
17850   clib_memcpy (&collector_address, &mp->collector_address,
17851                sizeof (collector_address));
17852   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
17853   vat_json_object_add_uint (&node, "collector_port",
17854                             ntohs (mp->collector_port));
17855   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
17856   vat_json_object_add_ip4 (&node, "src_address", src_address);
17857   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
17858   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
17859   vat_json_object_add_uint (&node, "template_interval",
17860                             ntohl (mp->template_interval));
17861   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
17862
17863   vat_json_print (vam->ofp, &node);
17864   vat_json_free (&node);
17865   vam->retval = 0;
17866   vam->result_ready = 1;
17867 }
17868
17869 int
17870 api_ipfix_exporter_dump (vat_main_t * vam)
17871 {
17872   vl_api_ipfix_exporter_dump_t *mp;
17873   int ret;
17874
17875   /* Construct the API message */
17876   M (IPFIX_EXPORTER_DUMP, mp);
17877   mp->context = 0;
17878
17879   S (mp);
17880   W (ret);
17881   return ret;
17882 }
17883
17884 static int
17885 api_ipfix_classify_stream_dump (vat_main_t * vam)
17886 {
17887   vl_api_ipfix_classify_stream_dump_t *mp;
17888   int ret;
17889
17890   /* Construct the API message */
17891   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
17892   mp->context = 0;
17893
17894   S (mp);
17895   W (ret);
17896   return ret;
17897   /* NOTREACHED */
17898   return 0;
17899 }
17900
17901 static void
17902   vl_api_ipfix_classify_stream_details_t_handler
17903   (vl_api_ipfix_classify_stream_details_t * mp)
17904 {
17905   vat_main_t *vam = &vat_main;
17906   print (vam->ofp, "domain_id %d, src_port %d",
17907          ntohl (mp->domain_id), ntohs (mp->src_port));
17908   vam->retval = 0;
17909   vam->result_ready = 1;
17910 }
17911
17912 static void
17913   vl_api_ipfix_classify_stream_details_t_handler_json
17914   (vl_api_ipfix_classify_stream_details_t * mp)
17915 {
17916   vat_main_t *vam = &vat_main;
17917   vat_json_node_t node;
17918
17919   vat_json_init_object (&node);
17920   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
17921   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
17922
17923   vat_json_print (vam->ofp, &node);
17924   vat_json_free (&node);
17925   vam->retval = 0;
17926   vam->result_ready = 1;
17927 }
17928
17929 static int
17930 api_ipfix_classify_table_dump (vat_main_t * vam)
17931 {
17932   vl_api_ipfix_classify_table_dump_t *mp;
17933   vl_api_control_ping_t *mp_ping;
17934   int ret;
17935
17936   if (!vam->json_output)
17937     {
17938       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
17939              "transport_protocol");
17940     }
17941
17942   /* Construct the API message */
17943   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
17944
17945   /* send it... */
17946   S (mp);
17947
17948   /* Use a control ping for synchronization */
17949   M (CONTROL_PING, mp_ping);
17950   S (mp_ping);
17951
17952   W (ret);
17953   return ret;
17954 }
17955
17956 static void
17957   vl_api_ipfix_classify_table_details_t_handler
17958   (vl_api_ipfix_classify_table_details_t * mp)
17959 {
17960   vat_main_t *vam = &vat_main;
17961   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
17962          mp->transport_protocol);
17963 }
17964
17965 static void
17966   vl_api_ipfix_classify_table_details_t_handler_json
17967   (vl_api_ipfix_classify_table_details_t * mp)
17968 {
17969   vat_json_node_t *node = NULL;
17970   vat_main_t *vam = &vat_main;
17971
17972   if (VAT_JSON_ARRAY != vam->json_tree.type)
17973     {
17974       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17975       vat_json_init_array (&vam->json_tree);
17976     }
17977
17978   node = vat_json_array_add (&vam->json_tree);
17979   vat_json_init_object (node);
17980
17981   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
17982   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
17983   vat_json_object_add_uint (node, "transport_protocol",
17984                             mp->transport_protocol);
17985 }
17986
17987 static int
17988 api_sw_interface_span_enable_disable (vat_main_t * vam)
17989 {
17990   unformat_input_t *i = vam->input;
17991   vl_api_sw_interface_span_enable_disable_t *mp;
17992   u32 src_sw_if_index = ~0;
17993   u32 dst_sw_if_index = ~0;
17994   u8 state = 3;
17995   int ret;
17996
17997   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17998     {
17999       if (unformat
18000           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
18001         ;
18002       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
18003         ;
18004       else
18005         if (unformat
18006             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
18007         ;
18008       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
18009         ;
18010       else if (unformat (i, "disable"))
18011         state = 0;
18012       else if (unformat (i, "rx"))
18013         state = 1;
18014       else if (unformat (i, "tx"))
18015         state = 2;
18016       else if (unformat (i, "both"))
18017         state = 3;
18018       else
18019         break;
18020     }
18021
18022   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
18023
18024   mp->sw_if_index_from = htonl (src_sw_if_index);
18025   mp->sw_if_index_to = htonl (dst_sw_if_index);
18026   mp->state = state;
18027
18028   S (mp);
18029   W (ret);
18030   return ret;
18031 }
18032
18033 static void
18034 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
18035                                             * mp)
18036 {
18037   vat_main_t *vam = &vat_main;
18038   u8 *sw_if_from_name = 0;
18039   u8 *sw_if_to_name = 0;
18040   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
18041   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
18042   char *states[] = { "none", "rx", "tx", "both" };
18043   hash_pair_t *p;
18044
18045   /* *INDENT-OFF* */
18046   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
18047   ({
18048     if ((u32) p->value[0] == sw_if_index_from)
18049       {
18050         sw_if_from_name = (u8 *)(p->key);
18051         if (sw_if_to_name)
18052           break;
18053       }
18054     if ((u32) p->value[0] == sw_if_index_to)
18055       {
18056         sw_if_to_name = (u8 *)(p->key);
18057         if (sw_if_from_name)
18058           break;
18059       }
18060   }));
18061   /* *INDENT-ON* */
18062   print (vam->ofp, "%20s => %20s (%s)",
18063          sw_if_from_name, sw_if_to_name, states[mp->state]);
18064 }
18065
18066 static void
18067   vl_api_sw_interface_span_details_t_handler_json
18068   (vl_api_sw_interface_span_details_t * mp)
18069 {
18070   vat_main_t *vam = &vat_main;
18071   vat_json_node_t *node = NULL;
18072   u8 *sw_if_from_name = 0;
18073   u8 *sw_if_to_name = 0;
18074   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
18075   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
18076   hash_pair_t *p;
18077
18078   /* *INDENT-OFF* */
18079   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
18080   ({
18081     if ((u32) p->value[0] == sw_if_index_from)
18082       {
18083         sw_if_from_name = (u8 *)(p->key);
18084         if (sw_if_to_name)
18085           break;
18086       }
18087     if ((u32) p->value[0] == sw_if_index_to)
18088       {
18089         sw_if_to_name = (u8 *)(p->key);
18090         if (sw_if_from_name)
18091           break;
18092       }
18093   }));
18094   /* *INDENT-ON* */
18095
18096   if (VAT_JSON_ARRAY != vam->json_tree.type)
18097     {
18098       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18099       vat_json_init_array (&vam->json_tree);
18100     }
18101   node = vat_json_array_add (&vam->json_tree);
18102
18103   vat_json_init_object (node);
18104   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
18105   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
18106   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
18107   if (0 != sw_if_to_name)
18108     {
18109       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
18110     }
18111   vat_json_object_add_uint (node, "state", mp->state);
18112 }
18113
18114 static int
18115 api_sw_interface_span_dump (vat_main_t * vam)
18116 {
18117   vl_api_sw_interface_span_dump_t *mp;
18118   vl_api_control_ping_t *mp_ping;
18119   int ret;
18120
18121   M (SW_INTERFACE_SPAN_DUMP, mp);
18122   S (mp);
18123
18124   /* Use a control ping for synchronization */
18125   M (CONTROL_PING, mp_ping);
18126   S (mp_ping);
18127
18128   W (ret);
18129   return ret;
18130 }
18131
18132 int
18133 api_pg_create_interface (vat_main_t * vam)
18134 {
18135   unformat_input_t *input = vam->input;
18136   vl_api_pg_create_interface_t *mp;
18137
18138   u32 if_id = ~0;
18139   int ret;
18140   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18141     {
18142       if (unformat (input, "if_id %d", &if_id))
18143         ;
18144       else
18145         break;
18146     }
18147   if (if_id == ~0)
18148     {
18149       errmsg ("missing pg interface index");
18150       return -99;
18151     }
18152
18153   /* Construct the API message */
18154   M (PG_CREATE_INTERFACE, mp);
18155   mp->context = 0;
18156   mp->interface_id = ntohl (if_id);
18157
18158   S (mp);
18159   W (ret);
18160   return ret;
18161 }
18162
18163 int
18164 api_pg_capture (vat_main_t * vam)
18165 {
18166   unformat_input_t *input = vam->input;
18167   vl_api_pg_capture_t *mp;
18168
18169   u32 if_id = ~0;
18170   u8 enable = 1;
18171   u32 count = 1;
18172   u8 pcap_file_set = 0;
18173   u8 *pcap_file = 0;
18174   int ret;
18175   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18176     {
18177       if (unformat (input, "if_id %d", &if_id))
18178         ;
18179       else if (unformat (input, "pcap %s", &pcap_file))
18180         pcap_file_set = 1;
18181       else if (unformat (input, "count %d", &count))
18182         ;
18183       else if (unformat (input, "disable"))
18184         enable = 0;
18185       else
18186         break;
18187     }
18188   if (if_id == ~0)
18189     {
18190       errmsg ("missing pg interface index");
18191       return -99;
18192     }
18193   if (pcap_file_set > 0)
18194     {
18195       if (vec_len (pcap_file) > 255)
18196         {
18197           errmsg ("pcap file name is too long");
18198           return -99;
18199         }
18200     }
18201
18202   u32 name_len = vec_len (pcap_file);
18203   /* Construct the API message */
18204   M (PG_CAPTURE, mp);
18205   mp->context = 0;
18206   mp->interface_id = ntohl (if_id);
18207   mp->is_enabled = enable;
18208   mp->count = ntohl (count);
18209   mp->pcap_name_length = ntohl (name_len);
18210   if (pcap_file_set != 0)
18211     {
18212       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
18213     }
18214   vec_free (pcap_file);
18215
18216   S (mp);
18217   W (ret);
18218   return ret;
18219 }
18220
18221 int
18222 api_pg_enable_disable (vat_main_t * vam)
18223 {
18224   unformat_input_t *input = vam->input;
18225   vl_api_pg_enable_disable_t *mp;
18226
18227   u8 enable = 1;
18228   u8 stream_name_set = 0;
18229   u8 *stream_name = 0;
18230   int ret;
18231   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18232     {
18233       if (unformat (input, "stream %s", &stream_name))
18234         stream_name_set = 1;
18235       else if (unformat (input, "disable"))
18236         enable = 0;
18237       else
18238         break;
18239     }
18240
18241   if (stream_name_set > 0)
18242     {
18243       if (vec_len (stream_name) > 255)
18244         {
18245           errmsg ("stream name too long");
18246           return -99;
18247         }
18248     }
18249
18250   u32 name_len = vec_len (stream_name);
18251   /* Construct the API message */
18252   M (PG_ENABLE_DISABLE, mp);
18253   mp->context = 0;
18254   mp->is_enabled = enable;
18255   if (stream_name_set != 0)
18256     {
18257       mp->stream_name_length = ntohl (name_len);
18258       clib_memcpy (mp->stream_name, stream_name, name_len);
18259     }
18260   vec_free (stream_name);
18261
18262   S (mp);
18263   W (ret);
18264   return ret;
18265 }
18266
18267 int
18268 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
18269 {
18270   unformat_input_t *input = vam->input;
18271   vl_api_ip_source_and_port_range_check_add_del_t *mp;
18272
18273   u16 *low_ports = 0;
18274   u16 *high_ports = 0;
18275   u16 this_low;
18276   u16 this_hi;
18277   ip4_address_t ip4_addr;
18278   ip6_address_t ip6_addr;
18279   u32 length;
18280   u32 tmp, tmp2;
18281   u8 prefix_set = 0;
18282   u32 vrf_id = ~0;
18283   u8 is_add = 1;
18284   u8 is_ipv6 = 0;
18285   int ret;
18286
18287   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18288     {
18289       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
18290         {
18291           prefix_set = 1;
18292         }
18293       else
18294         if (unformat
18295             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
18296         {
18297           prefix_set = 1;
18298           is_ipv6 = 1;
18299         }
18300       else if (unformat (input, "vrf %d", &vrf_id))
18301         ;
18302       else if (unformat (input, "del"))
18303         is_add = 0;
18304       else if (unformat (input, "port %d", &tmp))
18305         {
18306           if (tmp == 0 || tmp > 65535)
18307             {
18308               errmsg ("port %d out of range", tmp);
18309               return -99;
18310             }
18311           this_low = tmp;
18312           this_hi = this_low + 1;
18313           vec_add1 (low_ports, this_low);
18314           vec_add1 (high_ports, this_hi);
18315         }
18316       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
18317         {
18318           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
18319             {
18320               errmsg ("incorrect range parameters");
18321               return -99;
18322             }
18323           this_low = tmp;
18324           /* Note: in debug CLI +1 is added to high before
18325              passing to real fn that does "the work"
18326              (ip_source_and_port_range_check_add_del).
18327              This fn is a wrapper around the binary API fn a
18328              control plane will call, which expects this increment
18329              to have occurred. Hence letting the binary API control
18330              plane fn do the increment for consistency between VAT
18331              and other control planes.
18332            */
18333           this_hi = tmp2;
18334           vec_add1 (low_ports, this_low);
18335           vec_add1 (high_ports, this_hi);
18336         }
18337       else
18338         break;
18339     }
18340
18341   if (prefix_set == 0)
18342     {
18343       errmsg ("<address>/<mask> not specified");
18344       return -99;
18345     }
18346
18347   if (vrf_id == ~0)
18348     {
18349       errmsg ("VRF ID required, not specified");
18350       return -99;
18351     }
18352
18353   if (vrf_id == 0)
18354     {
18355       errmsg
18356         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
18357       return -99;
18358     }
18359
18360   if (vec_len (low_ports) == 0)
18361     {
18362       errmsg ("At least one port or port range required");
18363       return -99;
18364     }
18365
18366   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
18367
18368   mp->is_add = is_add;
18369
18370   if (is_ipv6)
18371     {
18372       mp->is_ipv6 = 1;
18373       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
18374     }
18375   else
18376     {
18377       mp->is_ipv6 = 0;
18378       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
18379     }
18380
18381   mp->mask_length = length;
18382   mp->number_of_ranges = vec_len (low_ports);
18383
18384   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
18385   vec_free (low_ports);
18386
18387   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
18388   vec_free (high_ports);
18389
18390   mp->vrf_id = ntohl (vrf_id);
18391
18392   S (mp);
18393   W (ret);
18394   return ret;
18395 }
18396
18397 int
18398 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
18399 {
18400   unformat_input_t *input = vam->input;
18401   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
18402   u32 sw_if_index = ~0;
18403   int vrf_set = 0;
18404   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
18405   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
18406   u8 is_add = 1;
18407   int ret;
18408
18409   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18410     {
18411       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18412         ;
18413       else if (unformat (input, "sw_if_index %d", &sw_if_index))
18414         ;
18415       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
18416         vrf_set = 1;
18417       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
18418         vrf_set = 1;
18419       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
18420         vrf_set = 1;
18421       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
18422         vrf_set = 1;
18423       else if (unformat (input, "del"))
18424         is_add = 0;
18425       else
18426         break;
18427     }
18428
18429   if (sw_if_index == ~0)
18430     {
18431       errmsg ("Interface required but not specified");
18432       return -99;
18433     }
18434
18435   if (vrf_set == 0)
18436     {
18437       errmsg ("VRF ID required but not specified");
18438       return -99;
18439     }
18440
18441   if (tcp_out_vrf_id == 0
18442       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
18443     {
18444       errmsg
18445         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
18446       return -99;
18447     }
18448
18449   /* Construct the API message */
18450   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
18451
18452   mp->sw_if_index = ntohl (sw_if_index);
18453   mp->is_add = is_add;
18454   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
18455   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
18456   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
18457   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
18458
18459   /* send it... */
18460   S (mp);
18461
18462   /* Wait for a reply... */
18463   W (ret);
18464   return ret;
18465 }
18466
18467 static int
18468 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
18469 {
18470   unformat_input_t *i = vam->input;
18471   vl_api_ipsec_gre_add_del_tunnel_t *mp;
18472   u32 local_sa_id = 0;
18473   u32 remote_sa_id = 0;
18474   ip4_address_t src_address;
18475   ip4_address_t dst_address;
18476   u8 is_add = 1;
18477   int ret;
18478
18479   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18480     {
18481       if (unformat (i, "local_sa %d", &local_sa_id))
18482         ;
18483       else if (unformat (i, "remote_sa %d", &remote_sa_id))
18484         ;
18485       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
18486         ;
18487       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
18488         ;
18489       else if (unformat (i, "del"))
18490         is_add = 0;
18491       else
18492         {
18493           clib_warning ("parse error '%U'", format_unformat_error, i);
18494           return -99;
18495         }
18496     }
18497
18498   M (IPSEC_GRE_ADD_DEL_TUNNEL, mp);
18499
18500   mp->local_sa_id = ntohl (local_sa_id);
18501   mp->remote_sa_id = ntohl (remote_sa_id);
18502   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
18503   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
18504   mp->is_add = is_add;
18505
18506   S (mp);
18507   W (ret);
18508   return ret;
18509 }
18510
18511 static int
18512 api_punt (vat_main_t * vam)
18513 {
18514   unformat_input_t *i = vam->input;
18515   vl_api_punt_t *mp;
18516   u32 ipv = ~0;
18517   u32 protocol = ~0;
18518   u32 port = ~0;
18519   int is_add = 1;
18520   int ret;
18521
18522   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18523     {
18524       if (unformat (i, "ip %d", &ipv))
18525         ;
18526       else if (unformat (i, "protocol %d", &protocol))
18527         ;
18528       else if (unformat (i, "port %d", &port))
18529         ;
18530       else if (unformat (i, "del"))
18531         is_add = 0;
18532       else
18533         {
18534           clib_warning ("parse error '%U'", format_unformat_error, i);
18535           return -99;
18536         }
18537     }
18538
18539   M (PUNT, mp);
18540
18541   mp->is_add = (u8) is_add;
18542   mp->ipv = (u8) ipv;
18543   mp->l4_protocol = (u8) protocol;
18544   mp->l4_port = htons ((u16) port);
18545
18546   S (mp);
18547   W (ret);
18548   return ret;
18549 }
18550
18551 static void vl_api_ipsec_gre_tunnel_details_t_handler
18552   (vl_api_ipsec_gre_tunnel_details_t * mp)
18553 {
18554   vat_main_t *vam = &vat_main;
18555
18556   print (vam->ofp, "%11d%15U%15U%14d%14d",
18557          ntohl (mp->sw_if_index),
18558          format_ip4_address, &mp->src_address,
18559          format_ip4_address, &mp->dst_address,
18560          ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
18561 }
18562
18563 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
18564   (vl_api_ipsec_gre_tunnel_details_t * mp)
18565 {
18566   vat_main_t *vam = &vat_main;
18567   vat_json_node_t *node = NULL;
18568   struct in_addr ip4;
18569
18570   if (VAT_JSON_ARRAY != vam->json_tree.type)
18571     {
18572       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18573       vat_json_init_array (&vam->json_tree);
18574     }
18575   node = vat_json_array_add (&vam->json_tree);
18576
18577   vat_json_init_object (node);
18578   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
18579   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
18580   vat_json_object_add_ip4 (node, "src_address", ip4);
18581   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
18582   vat_json_object_add_ip4 (node, "dst_address", ip4);
18583   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
18584   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
18585 }
18586
18587 static int
18588 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
18589 {
18590   unformat_input_t *i = vam->input;
18591   vl_api_ipsec_gre_tunnel_dump_t *mp;
18592   vl_api_control_ping_t *mp_ping;
18593   u32 sw_if_index;
18594   u8 sw_if_index_set = 0;
18595   int ret;
18596
18597   /* Parse args required to build the message */
18598   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18599     {
18600       if (unformat (i, "sw_if_index %d", &sw_if_index))
18601         sw_if_index_set = 1;
18602       else
18603         break;
18604     }
18605
18606   if (sw_if_index_set == 0)
18607     {
18608       sw_if_index = ~0;
18609     }
18610
18611   if (!vam->json_output)
18612     {
18613       print (vam->ofp, "%11s%15s%15s%14s%14s",
18614              "sw_if_index", "src_address", "dst_address",
18615              "local_sa_id", "remote_sa_id");
18616     }
18617
18618   /* Get list of gre-tunnel interfaces */
18619   M (IPSEC_GRE_TUNNEL_DUMP, mp);
18620
18621   mp->sw_if_index = htonl (sw_if_index);
18622
18623   S (mp);
18624
18625   /* Use a control ping for synchronization */
18626   M (CONTROL_PING, mp_ping);
18627   S (mp_ping);
18628
18629   W (ret);
18630   return ret;
18631 }
18632
18633 static int
18634 api_delete_subif (vat_main_t * vam)
18635 {
18636   unformat_input_t *i = vam->input;
18637   vl_api_delete_subif_t *mp;
18638   u32 sw_if_index = ~0;
18639   int ret;
18640
18641   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18642     {
18643       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18644         ;
18645       if (unformat (i, "sw_if_index %d", &sw_if_index))
18646         ;
18647       else
18648         break;
18649     }
18650
18651   if (sw_if_index == ~0)
18652     {
18653       errmsg ("missing sw_if_index");
18654       return -99;
18655     }
18656
18657   /* Construct the API message */
18658   M (DELETE_SUBIF, mp);
18659   mp->sw_if_index = ntohl (sw_if_index);
18660
18661   S (mp);
18662   W (ret);
18663   return ret;
18664 }
18665
18666 #define foreach_pbb_vtr_op      \
18667 _("disable",  L2_VTR_DISABLED)  \
18668 _("pop",  L2_VTR_POP_2)         \
18669 _("push",  L2_VTR_PUSH_2)
18670
18671 static int
18672 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
18673 {
18674   unformat_input_t *i = vam->input;
18675   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
18676   u32 sw_if_index = ~0, vtr_op = ~0;
18677   u16 outer_tag = ~0;
18678   u8 dmac[6], smac[6];
18679   u8 dmac_set = 0, smac_set = 0;
18680   u16 vlanid = 0;
18681   u32 sid = ~0;
18682   u32 tmp;
18683   int ret;
18684
18685   /* Shut up coverity */
18686   memset (dmac, 0, sizeof (dmac));
18687   memset (smac, 0, sizeof (smac));
18688
18689   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18690     {
18691       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18692         ;
18693       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18694         ;
18695       else if (unformat (i, "vtr_op %d", &vtr_op))
18696         ;
18697 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
18698       foreach_pbb_vtr_op
18699 #undef _
18700         else if (unformat (i, "translate_pbb_stag"))
18701         {
18702           if (unformat (i, "%d", &tmp))
18703             {
18704               vtr_op = L2_VTR_TRANSLATE_2_1;
18705               outer_tag = tmp;
18706             }
18707           else
18708             {
18709               errmsg
18710                 ("translate_pbb_stag operation requires outer tag definition");
18711               return -99;
18712             }
18713         }
18714       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
18715         dmac_set++;
18716       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
18717         smac_set++;
18718       else if (unformat (i, "sid %d", &sid))
18719         ;
18720       else if (unformat (i, "vlanid %d", &tmp))
18721         vlanid = tmp;
18722       else
18723         {
18724           clib_warning ("parse error '%U'", format_unformat_error, i);
18725           return -99;
18726         }
18727     }
18728
18729   if ((sw_if_index == ~0) || (vtr_op == ~0))
18730     {
18731       errmsg ("missing sw_if_index or vtr operation");
18732       return -99;
18733     }
18734   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
18735       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
18736     {
18737       errmsg
18738         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
18739       return -99;
18740     }
18741
18742   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
18743   mp->sw_if_index = ntohl (sw_if_index);
18744   mp->vtr_op = ntohl (vtr_op);
18745   mp->outer_tag = ntohs (outer_tag);
18746   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
18747   clib_memcpy (mp->b_smac, smac, sizeof (smac));
18748   mp->b_vlanid = ntohs (vlanid);
18749   mp->i_sid = ntohl (sid);
18750
18751   S (mp);
18752   W (ret);
18753   return ret;
18754 }
18755
18756 static int
18757 api_flow_classify_set_interface (vat_main_t * vam)
18758 {
18759   unformat_input_t *i = vam->input;
18760   vl_api_flow_classify_set_interface_t *mp;
18761   u32 sw_if_index;
18762   int sw_if_index_set;
18763   u32 ip4_table_index = ~0;
18764   u32 ip6_table_index = ~0;
18765   u8 is_add = 1;
18766   int ret;
18767
18768   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18769     {
18770       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18771         sw_if_index_set = 1;
18772       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18773         sw_if_index_set = 1;
18774       else if (unformat (i, "del"))
18775         is_add = 0;
18776       else if (unformat (i, "ip4-table %d", &ip4_table_index))
18777         ;
18778       else if (unformat (i, "ip6-table %d", &ip6_table_index))
18779         ;
18780       else
18781         {
18782           clib_warning ("parse error '%U'", format_unformat_error, i);
18783           return -99;
18784         }
18785     }
18786
18787   if (sw_if_index_set == 0)
18788     {
18789       errmsg ("missing interface name or sw_if_index");
18790       return -99;
18791     }
18792
18793   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
18794
18795   mp->sw_if_index = ntohl (sw_if_index);
18796   mp->ip4_table_index = ntohl (ip4_table_index);
18797   mp->ip6_table_index = ntohl (ip6_table_index);
18798   mp->is_add = is_add;
18799
18800   S (mp);
18801   W (ret);
18802   return ret;
18803 }
18804
18805 static int
18806 api_flow_classify_dump (vat_main_t * vam)
18807 {
18808   unformat_input_t *i = vam->input;
18809   vl_api_flow_classify_dump_t *mp;
18810   vl_api_control_ping_t *mp_ping;
18811   u8 type = FLOW_CLASSIFY_N_TABLES;
18812   int ret;
18813
18814   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
18815     ;
18816   else
18817     {
18818       errmsg ("classify table type must be specified");
18819       return -99;
18820     }
18821
18822   if (!vam->json_output)
18823     {
18824       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
18825     }
18826
18827   M (FLOW_CLASSIFY_DUMP, mp);
18828   mp->type = type;
18829   /* send it... */
18830   S (mp);
18831
18832   /* Use a control ping for synchronization */
18833   M (CONTROL_PING, mp_ping);
18834   S (mp_ping);
18835
18836   /* Wait for a reply... */
18837   W (ret);
18838   return ret;
18839 }
18840
18841 static int
18842 api_feature_enable_disable (vat_main_t * vam)
18843 {
18844   unformat_input_t *i = vam->input;
18845   vl_api_feature_enable_disable_t *mp;
18846   u8 *arc_name = 0;
18847   u8 *feature_name = 0;
18848   u32 sw_if_index = ~0;
18849   u8 enable = 1;
18850   int ret;
18851
18852   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18853     {
18854       if (unformat (i, "arc_name %s", &arc_name))
18855         ;
18856       else if (unformat (i, "feature_name %s", &feature_name))
18857         ;
18858       else
18859         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18860         ;
18861       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18862         ;
18863       else if (unformat (i, "disable"))
18864         enable = 0;
18865       else
18866         break;
18867     }
18868
18869   if (arc_name == 0)
18870     {
18871       errmsg ("missing arc name");
18872       return -99;
18873     }
18874   if (vec_len (arc_name) > 63)
18875     {
18876       errmsg ("arc name too long");
18877     }
18878
18879   if (feature_name == 0)
18880     {
18881       errmsg ("missing feature name");
18882       return -99;
18883     }
18884   if (vec_len (feature_name) > 63)
18885     {
18886       errmsg ("feature name too long");
18887     }
18888
18889   if (sw_if_index == ~0)
18890     {
18891       errmsg ("missing interface name or sw_if_index");
18892       return -99;
18893     }
18894
18895   /* Construct the API message */
18896   M (FEATURE_ENABLE_DISABLE, mp);
18897   mp->sw_if_index = ntohl (sw_if_index);
18898   mp->enable = enable;
18899   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
18900   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
18901   vec_free (arc_name);
18902   vec_free (feature_name);
18903
18904   S (mp);
18905   W (ret);
18906   return ret;
18907 }
18908
18909 static int
18910 api_sw_interface_tag_add_del (vat_main_t * vam)
18911 {
18912   unformat_input_t *i = vam->input;
18913   vl_api_sw_interface_tag_add_del_t *mp;
18914   u32 sw_if_index = ~0;
18915   u8 *tag = 0;
18916   u8 enable = 1;
18917   int ret;
18918
18919   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18920     {
18921       if (unformat (i, "tag %s", &tag))
18922         ;
18923       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18924         ;
18925       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18926         ;
18927       else if (unformat (i, "del"))
18928         enable = 0;
18929       else
18930         break;
18931     }
18932
18933   if (sw_if_index == ~0)
18934     {
18935       errmsg ("missing interface name or sw_if_index");
18936       return -99;
18937     }
18938
18939   if (enable && (tag == 0))
18940     {
18941       errmsg ("no tag specified");
18942       return -99;
18943     }
18944
18945   /* Construct the API message */
18946   M (SW_INTERFACE_TAG_ADD_DEL, mp);
18947   mp->sw_if_index = ntohl (sw_if_index);
18948   mp->is_add = enable;
18949   if (enable)
18950     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
18951   vec_free (tag);
18952
18953   S (mp);
18954   W (ret);
18955   return ret;
18956 }
18957
18958 static void vl_api_l2_xconnect_details_t_handler
18959   (vl_api_l2_xconnect_details_t * mp)
18960 {
18961   vat_main_t *vam = &vat_main;
18962
18963   print (vam->ofp, "%15d%15d",
18964          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
18965 }
18966
18967 static void vl_api_l2_xconnect_details_t_handler_json
18968   (vl_api_l2_xconnect_details_t * mp)
18969 {
18970   vat_main_t *vam = &vat_main;
18971   vat_json_node_t *node = NULL;
18972
18973   if (VAT_JSON_ARRAY != vam->json_tree.type)
18974     {
18975       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18976       vat_json_init_array (&vam->json_tree);
18977     }
18978   node = vat_json_array_add (&vam->json_tree);
18979
18980   vat_json_init_object (node);
18981   vat_json_object_add_uint (node, "rx_sw_if_index",
18982                             ntohl (mp->rx_sw_if_index));
18983   vat_json_object_add_uint (node, "tx_sw_if_index",
18984                             ntohl (mp->tx_sw_if_index));
18985 }
18986
18987 static int
18988 api_l2_xconnect_dump (vat_main_t * vam)
18989 {
18990   vl_api_l2_xconnect_dump_t *mp;
18991   vl_api_control_ping_t *mp_ping;
18992   int ret;
18993
18994   if (!vam->json_output)
18995     {
18996       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
18997     }
18998
18999   M (L2_XCONNECT_DUMP, mp);
19000
19001   S (mp);
19002
19003   /* Use a control ping for synchronization */
19004   M (CONTROL_PING, mp_ping);
19005   S (mp_ping);
19006
19007   W (ret);
19008   return ret;
19009 }
19010
19011 static int
19012 api_sw_interface_set_mtu (vat_main_t * vam)
19013 {
19014   unformat_input_t *i = vam->input;
19015   vl_api_sw_interface_set_mtu_t *mp;
19016   u32 sw_if_index = ~0;
19017   u32 mtu = 0;
19018   int ret;
19019
19020   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19021     {
19022       if (unformat (i, "mtu %d", &mtu))
19023         ;
19024       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19025         ;
19026       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19027         ;
19028       else
19029         break;
19030     }
19031
19032   if (sw_if_index == ~0)
19033     {
19034       errmsg ("missing interface name or sw_if_index");
19035       return -99;
19036     }
19037
19038   if (mtu == 0)
19039     {
19040       errmsg ("no mtu specified");
19041       return -99;
19042     }
19043
19044   /* Construct the API message */
19045   M (SW_INTERFACE_SET_MTU, mp);
19046   mp->sw_if_index = ntohl (sw_if_index);
19047   mp->mtu = ntohs ((u16) mtu);
19048
19049   S (mp);
19050   W (ret);
19051   return ret;
19052 }
19053
19054 static int
19055 api_p2p_ethernet_add (vat_main_t * vam)
19056 {
19057   unformat_input_t *i = vam->input;
19058   vl_api_p2p_ethernet_add_t *mp;
19059   u32 parent_if_index = ~0;
19060   u8 remote_mac[6];
19061   u8 mac_set = 0;
19062   int ret;
19063
19064   memset (remote_mac, 0, sizeof (remote_mac));
19065   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19066     {
19067       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
19068         ;
19069       else if (unformat (i, "sw_if_index %d", &parent_if_index))
19070         ;
19071       else
19072         if (unformat
19073             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
19074         mac_set++;
19075       else
19076         {
19077           clib_warning ("parse error '%U'", format_unformat_error, i);
19078           return -99;
19079         }
19080     }
19081
19082   if (parent_if_index == ~0)
19083     {
19084       errmsg ("missing interface name or sw_if_index");
19085       return -99;
19086     }
19087   if (mac_set == 0)
19088     {
19089       errmsg ("missing remote mac address");
19090       return -99;
19091     }
19092
19093   M (P2P_ETHERNET_ADD, mp);
19094   mp->parent_if_index = ntohl (parent_if_index);
19095   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
19096
19097   S (mp);
19098   W (ret);
19099   return ret;
19100 }
19101
19102 static int
19103 api_p2p_ethernet_del (vat_main_t * vam)
19104 {
19105   unformat_input_t *i = vam->input;
19106   vl_api_p2p_ethernet_del_t *mp;
19107   u32 parent_if_index = ~0;
19108   u8 remote_mac[6];
19109   u8 mac_set = 0;
19110   int ret;
19111
19112   memset (remote_mac, 0, sizeof (remote_mac));
19113   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19114     {
19115       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
19116         ;
19117       else if (unformat (i, "sw_if_index %d", &parent_if_index))
19118         ;
19119       else
19120         if (unformat
19121             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
19122         mac_set++;
19123       else
19124         {
19125           clib_warning ("parse error '%U'", format_unformat_error, i);
19126           return -99;
19127         }
19128     }
19129
19130   if (parent_if_index == ~0)
19131     {
19132       errmsg ("missing interface name or sw_if_index");
19133       return -99;
19134     }
19135   if (mac_set == 0)
19136     {
19137       errmsg ("missing remote mac address");
19138       return -99;
19139     }
19140
19141   M (P2P_ETHERNET_DEL, mp);
19142   mp->parent_if_index = ntohl (parent_if_index);
19143   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
19144
19145   S (mp);
19146   W (ret);
19147   return ret;
19148 }
19149
19150 static int
19151 q_or_quit (vat_main_t * vam)
19152 {
19153 #if VPP_API_TEST_BUILTIN == 0
19154   longjmp (vam->jump_buf, 1);
19155 #endif
19156   return 0;                     /* not so much */
19157 }
19158
19159 static int
19160 q (vat_main_t * vam)
19161 {
19162   return q_or_quit (vam);
19163 }
19164
19165 static int
19166 quit (vat_main_t * vam)
19167 {
19168   return q_or_quit (vam);
19169 }
19170
19171 static int
19172 comment (vat_main_t * vam)
19173 {
19174   return 0;
19175 }
19176
19177 static int
19178 cmd_cmp (void *a1, void *a2)
19179 {
19180   u8 **c1 = a1;
19181   u8 **c2 = a2;
19182
19183   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
19184 }
19185
19186 static int
19187 help (vat_main_t * vam)
19188 {
19189   u8 **cmds = 0;
19190   u8 *name = 0;
19191   hash_pair_t *p;
19192   unformat_input_t *i = vam->input;
19193   int j;
19194
19195   if (unformat (i, "%s", &name))
19196     {
19197       uword *hs;
19198
19199       vec_add1 (name, 0);
19200
19201       hs = hash_get_mem (vam->help_by_name, name);
19202       if (hs)
19203         print (vam->ofp, "usage: %s %s", name, hs[0]);
19204       else
19205         print (vam->ofp, "No such msg / command '%s'", name);
19206       vec_free (name);
19207       return 0;
19208     }
19209
19210   print (vam->ofp, "Help is available for the following:");
19211
19212     /* *INDENT-OFF* */
19213     hash_foreach_pair (p, vam->function_by_name,
19214     ({
19215       vec_add1 (cmds, (u8 *)(p->key));
19216     }));
19217     /* *INDENT-ON* */
19218
19219   vec_sort_with_function (cmds, cmd_cmp);
19220
19221   for (j = 0; j < vec_len (cmds); j++)
19222     print (vam->ofp, "%s", cmds[j]);
19223
19224   vec_free (cmds);
19225   return 0;
19226 }
19227
19228 static int
19229 set (vat_main_t * vam)
19230 {
19231   u8 *name = 0, *value = 0;
19232   unformat_input_t *i = vam->input;
19233
19234   if (unformat (i, "%s", &name))
19235     {
19236       /* The input buffer is a vector, not a string. */
19237       value = vec_dup (i->buffer);
19238       vec_delete (value, i->index, 0);
19239       /* Almost certainly has a trailing newline */
19240       if (value[vec_len (value) - 1] == '\n')
19241         value[vec_len (value) - 1] = 0;
19242       /* Make sure it's a proper string, one way or the other */
19243       vec_add1 (value, 0);
19244       (void) clib_macro_set_value (&vam->macro_main,
19245                                    (char *) name, (char *) value);
19246     }
19247   else
19248     errmsg ("usage: set <name> <value>");
19249
19250   vec_free (name);
19251   vec_free (value);
19252   return 0;
19253 }
19254
19255 static int
19256 unset (vat_main_t * vam)
19257 {
19258   u8 *name = 0;
19259
19260   if (unformat (vam->input, "%s", &name))
19261     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
19262       errmsg ("unset: %s wasn't set", name);
19263   vec_free (name);
19264   return 0;
19265 }
19266
19267 typedef struct
19268 {
19269   u8 *name;
19270   u8 *value;
19271 } macro_sort_t;
19272
19273
19274 static int
19275 macro_sort_cmp (void *a1, void *a2)
19276 {
19277   macro_sort_t *s1 = a1;
19278   macro_sort_t *s2 = a2;
19279
19280   return strcmp ((char *) (s1->name), (char *) (s2->name));
19281 }
19282
19283 static int
19284 dump_macro_table (vat_main_t * vam)
19285 {
19286   macro_sort_t *sort_me = 0, *sm;
19287   int i;
19288   hash_pair_t *p;
19289
19290     /* *INDENT-OFF* */
19291     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
19292     ({
19293       vec_add2 (sort_me, sm, 1);
19294       sm->name = (u8 *)(p->key);
19295       sm->value = (u8 *) (p->value[0]);
19296     }));
19297     /* *INDENT-ON* */
19298
19299   vec_sort_with_function (sort_me, macro_sort_cmp);
19300
19301   if (vec_len (sort_me))
19302     print (vam->ofp, "%-15s%s", "Name", "Value");
19303   else
19304     print (vam->ofp, "The macro table is empty...");
19305
19306   for (i = 0; i < vec_len (sort_me); i++)
19307     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
19308   return 0;
19309 }
19310
19311 static int
19312 dump_node_table (vat_main_t * vam)
19313 {
19314   int i, j;
19315   vlib_node_t *node, *next_node;
19316
19317   if (vec_len (vam->graph_nodes) == 0)
19318     {
19319       print (vam->ofp, "Node table empty, issue get_node_graph...");
19320       return 0;
19321     }
19322
19323   for (i = 0; i < vec_len (vam->graph_nodes); i++)
19324     {
19325       node = vam->graph_nodes[i];
19326       print (vam->ofp, "[%d] %s", i, node->name);
19327       for (j = 0; j < vec_len (node->next_nodes); j++)
19328         {
19329           if (node->next_nodes[j] != ~0)
19330             {
19331               next_node = vam->graph_nodes[node->next_nodes[j]];
19332               print (vam->ofp, "  [%d] %s", j, next_node->name);
19333             }
19334         }
19335     }
19336   return 0;
19337 }
19338
19339 static int
19340 value_sort_cmp (void *a1, void *a2)
19341 {
19342   name_sort_t *n1 = a1;
19343   name_sort_t *n2 = a2;
19344
19345   if (n1->value < n2->value)
19346     return -1;
19347   if (n1->value > n2->value)
19348     return 1;
19349   return 0;
19350 }
19351
19352
19353 static int
19354 dump_msg_api_table (vat_main_t * vam)
19355 {
19356   api_main_t *am = &api_main;
19357   name_sort_t *nses = 0, *ns;
19358   hash_pair_t *hp;
19359   int i;
19360
19361   /* *INDENT-OFF* */
19362   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
19363   ({
19364     vec_add2 (nses, ns, 1);
19365     ns->name = (u8 *)(hp->key);
19366     ns->value = (u32) hp->value[0];
19367   }));
19368   /* *INDENT-ON* */
19369
19370   vec_sort_with_function (nses, value_sort_cmp);
19371
19372   for (i = 0; i < vec_len (nses); i++)
19373     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
19374   vec_free (nses);
19375   return 0;
19376 }
19377
19378 static int
19379 get_msg_id (vat_main_t * vam)
19380 {
19381   u8 *name_and_crc;
19382   u32 message_index;
19383
19384   if (unformat (vam->input, "%s", &name_and_crc))
19385     {
19386       message_index = vl_api_get_msg_index (name_and_crc);
19387       if (message_index == ~0)
19388         {
19389           print (vam->ofp, " '%s' not found", name_and_crc);
19390           return 0;
19391         }
19392       print (vam->ofp, " '%s' has message index %d",
19393              name_and_crc, message_index);
19394       return 0;
19395     }
19396   errmsg ("name_and_crc required...");
19397   return 0;
19398 }
19399
19400 static int
19401 search_node_table (vat_main_t * vam)
19402 {
19403   unformat_input_t *line_input = vam->input;
19404   u8 *node_to_find;
19405   int j;
19406   vlib_node_t *node, *next_node;
19407   uword *p;
19408
19409   if (vam->graph_node_index_by_name == 0)
19410     {
19411       print (vam->ofp, "Node table empty, issue get_node_graph...");
19412       return 0;
19413     }
19414
19415   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
19416     {
19417       if (unformat (line_input, "%s", &node_to_find))
19418         {
19419           vec_add1 (node_to_find, 0);
19420           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
19421           if (p == 0)
19422             {
19423               print (vam->ofp, "%s not found...", node_to_find);
19424               goto out;
19425             }
19426           node = vam->graph_nodes[p[0]];
19427           print (vam->ofp, "[%d] %s", p[0], node->name);
19428           for (j = 0; j < vec_len (node->next_nodes); j++)
19429             {
19430               if (node->next_nodes[j] != ~0)
19431                 {
19432                   next_node = vam->graph_nodes[node->next_nodes[j]];
19433                   print (vam->ofp, "  [%d] %s", j, next_node->name);
19434                 }
19435             }
19436         }
19437
19438       else
19439         {
19440           clib_warning ("parse error '%U'", format_unformat_error,
19441                         line_input);
19442           return -99;
19443         }
19444
19445     out:
19446       vec_free (node_to_find);
19447
19448     }
19449
19450   return 0;
19451 }
19452
19453
19454 static int
19455 script (vat_main_t * vam)
19456 {
19457 #if (VPP_API_TEST_BUILTIN==0)
19458   u8 *s = 0;
19459   char *save_current_file;
19460   unformat_input_t save_input;
19461   jmp_buf save_jump_buf;
19462   u32 save_line_number;
19463
19464   FILE *new_fp, *save_ifp;
19465
19466   if (unformat (vam->input, "%s", &s))
19467     {
19468       new_fp = fopen ((char *) s, "r");
19469       if (new_fp == 0)
19470         {
19471           errmsg ("Couldn't open script file %s", s);
19472           vec_free (s);
19473           return -99;
19474         }
19475     }
19476   else
19477     {
19478       errmsg ("Missing script name");
19479       return -99;
19480     }
19481
19482   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
19483   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
19484   save_ifp = vam->ifp;
19485   save_line_number = vam->input_line_number;
19486   save_current_file = (char *) vam->current_file;
19487
19488   vam->input_line_number = 0;
19489   vam->ifp = new_fp;
19490   vam->current_file = s;
19491   do_one_file (vam);
19492
19493   clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
19494   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
19495   vam->ifp = save_ifp;
19496   vam->input_line_number = save_line_number;
19497   vam->current_file = (u8 *) save_current_file;
19498   vec_free (s);
19499
19500   return 0;
19501 #else
19502   clib_warning ("use the exec command...");
19503   return -99;
19504 #endif
19505 }
19506
19507 static int
19508 echo (vat_main_t * vam)
19509 {
19510   print (vam->ofp, "%v", vam->input->buffer);
19511   return 0;
19512 }
19513
19514 /* List of API message constructors, CLI names map to api_xxx */
19515 #define foreach_vpe_api_msg                                             \
19516 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
19517 _(sw_interface_dump,"")                                                 \
19518 _(sw_interface_set_flags,                                               \
19519   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
19520 _(sw_interface_add_del_address,                                         \
19521   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
19522 _(sw_interface_set_table,                                               \
19523   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
19524 _(sw_interface_set_mpls_enable,                                         \
19525   "<intfc> | sw_if_index [disable | dis]")                              \
19526 _(sw_interface_set_vpath,                                               \
19527   "<intfc> | sw_if_index <id> enable | disable")                        \
19528 _(sw_interface_set_vxlan_bypass,                                        \
19529   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
19530 _(sw_interface_set_l2_xconnect,                                         \
19531   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
19532   "enable | disable")                                                   \
19533 _(sw_interface_set_l2_bridge,                                           \
19534   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
19535   "[shg <split-horizon-group>] [bvi]\n"                                 \
19536   "enable | disable")                                                   \
19537 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
19538 _(bridge_domain_add_del,                                                \
19539   "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") \
19540 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
19541 _(l2fib_add_del,                                                        \
19542   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
19543 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
19544 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
19545 _(l2_flags,                                                             \
19546   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood]\n") \
19547 _(bridge_flags,                                                         \
19548   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
19549 _(tap_connect,                                                          \
19550   "tapname <name> mac <mac-addr> | random-mac [tag <string>]")          \
19551 _(tap_modify,                                                           \
19552   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
19553 _(tap_delete,                                                           \
19554   "<vpp-if-name> | sw_if_index <id>")                                   \
19555 _(sw_interface_tap_dump, "")                                            \
19556 _(ip_add_del_route,                                                     \
19557   "<addr>/<mask> via <addr> [table-id <n>]\n"                           \
19558   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
19559   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
19560   "[multipath] [count <n>]")                                            \
19561 _(ip_mroute_add_del,                                                    \
19562   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
19563   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
19564 _(mpls_route_add_del,                                                   \
19565   "<label> <eos> via <addr> [table-id <n>]\n"                           \
19566   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
19567   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
19568   "[multipath] [count <n>]")                                            \
19569 _(mpls_ip_bind_unbind,                                                  \
19570   "<label> <addr/len>")                                                 \
19571 _(mpls_tunnel_add_del,                                                  \
19572   " via <addr> [table-id <n>]\n"                                        \
19573   "sw_if_index <id>] [l2]  [del]")                                      \
19574 _(proxy_arp_add_del,                                                    \
19575   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
19576 _(proxy_arp_intfc_enable_disable,                                       \
19577   "<intfc> | sw_if_index <id> enable | disable")                        \
19578 _(sw_interface_set_unnumbered,                                          \
19579   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
19580 _(ip_neighbor_add_del,                                                  \
19581   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
19582   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
19583 _(reset_vrf, "vrf <id> [ipv6]")                                         \
19584 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
19585 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
19586   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
19587   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
19588   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
19589 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
19590 _(reset_fib, "vrf <n> [ipv6]")                                          \
19591 _(dhcp_proxy_config,                                                    \
19592   "svr <v46-address> src <v46-address>\n"                               \
19593    "rx_vrf_id <nn> server_vrf_id <nn>  [del]")                          \
19594 _(dhcp_proxy_set_vss,                                                   \
19595   "tbl_id <n> fib_id <n> oui <n> [ipv6] [del]")                         \
19596 _(dhcp_proxy_dump, "ip6")                                               \
19597 _(dhcp_client_config,                                                   \
19598   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
19599 _(set_ip_flow_hash,                                                     \
19600   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
19601 _(sw_interface_ip6_enable_disable,                                      \
19602   "<intfc> | sw_if_index <id> enable | disable")                        \
19603 _(sw_interface_ip6_set_link_local_address,                              \
19604   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
19605 _(ip6nd_proxy_add_del,                                                  \
19606   "<intfc> | sw_if_index <id> <ip6-address>")                           \
19607 _(ip6nd_proxy_dump, "")                                                 \
19608 _(sw_interface_ip6nd_ra_prefix,                                         \
19609   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
19610   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
19611   "[nolink] [isno]")                                                    \
19612 _(sw_interface_ip6nd_ra_config,                                         \
19613   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
19614   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
19615   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
19616 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
19617 _(l2_patch_add_del,                                                     \
19618   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
19619   "enable | disable")                                                   \
19620 _(sr_localsid_add_del,                                                  \
19621   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
19622   "fib-table <num> (end.psp) sw_if_index <num>")                        \
19623 _(classify_add_del_table,                                               \
19624   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
19625   " [del] [del-chain] mask <mask-value>\n"                              \
19626   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
19627   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
19628 _(classify_add_del_session,                                             \
19629   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
19630   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
19631   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
19632   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
19633 _(classify_set_interface_ip_table,                                      \
19634   "<intfc> | sw_if_index <nn> table <nn>")                              \
19635 _(classify_set_interface_l2_tables,                                     \
19636   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
19637   "  [other-table <nn>]")                                               \
19638 _(get_node_index, "node <node-name")                                    \
19639 _(add_node_next, "node <node-name> next <next-node-name>")              \
19640 _(l2tpv3_create_tunnel,                                                 \
19641   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
19642   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
19643   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
19644 _(l2tpv3_set_tunnel_cookies,                                            \
19645   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
19646   "[new_remote_cookie <nn>]\n")                                         \
19647 _(l2tpv3_interface_enable_disable,                                      \
19648   "<intfc> | sw_if_index <nn> enable | disable")                        \
19649 _(l2tpv3_set_lookup_key,                                                \
19650   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
19651 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
19652 _(vxlan_add_del_tunnel,                                                 \
19653   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
19654   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
19655   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
19656 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
19657 _(gre_add_del_tunnel,                                                   \
19658   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [teb] [del]\n")    \
19659 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
19660 _(l2_fib_clear_table, "")                                               \
19661 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
19662 _(l2_interface_vlan_tag_rewrite,                                        \
19663   "<intfc> | sw_if_index <nn> \n"                                       \
19664   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
19665   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
19666 _(create_vhost_user_if,                                                 \
19667         "socket <filename> [server] [renumber <dev_instance>] "         \
19668         "[mac <mac_address>]")                                          \
19669 _(modify_vhost_user_if,                                                 \
19670         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
19671         "[server] [renumber <dev_instance>]")                           \
19672 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
19673 _(sw_interface_vhost_user_dump, "")                                     \
19674 _(show_version, "")                                                     \
19675 _(vxlan_gpe_add_del_tunnel,                                             \
19676   "local <addr> remote <addr> vni <nn>\n"                               \
19677     "[encap-vrf-id <nn>] [decap-vrf-id <nn>] [next-ip4][next-ip6]"      \
19678   "[next-ethernet] [next-nsh]\n")                                       \
19679 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
19680 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
19681 _(interface_name_renumber,                                              \
19682   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
19683 _(input_acl_set_interface,                                              \
19684   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
19685   "  [l2-table <nn>] [del]")                                            \
19686 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
19687 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
19688 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
19689 _(ip_dump, "ipv4 | ipv6")                                               \
19690 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
19691 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
19692   "  spid_id <n> ")                                                     \
19693 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
19694   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
19695   "  integ_alg <alg> integ_key <hex>")                                  \
19696 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
19697   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
19698   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
19699   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
19700 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
19701 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
19702   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
19703   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
19704   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n")     \
19705 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
19706 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
19707   "(auth_data 0x<data> | auth_data <data>)")                            \
19708 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
19709   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
19710 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
19711   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
19712   "(local|remote)")                                                     \
19713 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
19714 _(ikev2_set_responder, "<profile_name> interface <interface> address <addr>") \
19715 _(ikev2_set_ike_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
19716 _(ikev2_set_esp_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
19717 _(ikev2_set_sa_lifetime, "<profile_name> <seconds> <jitter> <handover> <max bytes>") \
19718 _(ikev2_initiate_sa_init, "<profile_name>")                             \
19719 _(ikev2_initiate_del_ike_sa, "<ispi>")                                  \
19720 _(ikev2_initiate_del_child_sa, "<ispi>")                                \
19721 _(ikev2_initiate_rekey_child_sa, "<ispi>")                              \
19722 _(delete_loopback,"sw_if_index <nn>")                                   \
19723 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
19724 _(map_add_domain,                                                       \
19725   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
19726   "ip6-src <ip6addr> "                                                  \
19727   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
19728 _(map_del_domain, "index <n>")                                          \
19729 _(map_add_del_rule,                                                     \
19730   "index <n> psid <n> dst <ip6addr> [del]")                             \
19731 _(map_domain_dump, "")                                                  \
19732 _(map_rule_dump, "index <map-domain>")                                  \
19733 _(want_interface_events,  "enable|disable")                             \
19734 _(want_stats,"enable|disable")                                          \
19735 _(get_first_msg_id, "client <name>")                                    \
19736 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
19737 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
19738   "fib-id <nn> [ip4][ip6][default]")                                    \
19739 _(get_node_graph, " ")                                                  \
19740 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
19741 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
19742 _(ioam_disable, "")                                                     \
19743 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
19744                             " sw_if_index <sw_if_index> p <priority> "  \
19745                             "w <weight>] [del]")                        \
19746 _(one_add_del_locator, "locator-set <locator_name> "                    \
19747                         "iface <intf> | sw_if_index <sw_if_index> "     \
19748                         "p <priority> w <weight> [del]")                \
19749 _(one_add_del_local_eid,"vni <vni> eid "                                \
19750                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
19751                          "locator-set <locator_name> [del]"             \
19752                          "[key-id sha1|sha256 secret-key <secret-key>]")\
19753 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
19754 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
19755 _(one_enable_disable, "enable|disable")                                 \
19756 _(one_map_register_enable_disable, "enable|disable")                    \
19757 _(one_rloc_probe_enable_disable, "enable|disable")                      \
19758 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
19759                                "[seid <seid>] "                         \
19760                                "rloc <locator> p <prio> "               \
19761                                "w <weight> [rloc <loc> ... ] "          \
19762                                "action <action> [del-all]")             \
19763 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
19764                           "<local-eid>")                                \
19765 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
19766 _(one_use_petr, "ip-address> | disable")                                \
19767 _(one_map_request_mode, "src-dst|dst-only")                             \
19768 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
19769 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
19770 _(one_locator_set_dump, "[local | remote]")                             \
19771 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
19772 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
19773                        "[local] | [remote]")                            \
19774 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
19775 _(one_l2_arp_bd_get, "")                                                \
19776 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
19777 _(one_stats_enable_disable, "enable|disalbe")                           \
19778 _(show_one_stats_enable_disable, "")                                    \
19779 _(one_eid_table_vni_dump, "")                                           \
19780 _(one_eid_table_map_dump, "l2|l3")                                      \
19781 _(one_map_resolver_dump, "")                                            \
19782 _(one_map_server_dump, "")                                              \
19783 _(one_adjacencies_get, "vni <vni>")                                     \
19784 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
19785 _(show_one_rloc_probe_state, "")                                        \
19786 _(show_one_map_register_state, "")                                      \
19787 _(show_one_status, "")                                                  \
19788 _(one_stats_dump, "")                                                   \
19789 _(one_stats_flush, "")                                                  \
19790 _(one_get_map_request_itr_rlocs, "")                                    \
19791 _(show_one_nsh_mapping, "")                                             \
19792 _(show_one_pitr, "")                                                    \
19793 _(show_one_use_petr, "")                                                \
19794 _(show_one_map_request_mode, "")                                        \
19795 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
19796                             " sw_if_index <sw_if_index> p <priority> "  \
19797                             "w <weight>] [del]")                        \
19798 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
19799                         "iface <intf> | sw_if_index <sw_if_index> "     \
19800                         "p <priority> w <weight> [del]")                \
19801 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
19802                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
19803                          "locator-set <locator_name> [del]"             \
19804                          "[key-id sha1|sha256 secret-key <secret-key>]") \
19805 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
19806 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
19807 _(lisp_enable_disable, "enable|disable")                                \
19808 _(lisp_map_register_enable_disable, "enable|disable")                   \
19809 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
19810 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
19811                                "[seid <seid>] "                         \
19812                                "rloc <locator> p <prio> "               \
19813                                "w <weight> [rloc <loc> ... ] "          \
19814                                "action <action> [del-all]")             \
19815 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
19816                           "<local-eid>")                                \
19817 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
19818 _(lisp_use_petr, "<ip-address> | disable")                              \
19819 _(lisp_map_request_mode, "src-dst|dst-only")                            \
19820 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
19821 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
19822 _(lisp_locator_set_dump, "[local | remote]")                            \
19823 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
19824 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
19825                        "[local] | [remote]")                            \
19826 _(lisp_eid_table_vni_dump, "")                                          \
19827 _(lisp_eid_table_map_dump, "l2|l3")                                     \
19828 _(lisp_map_resolver_dump, "")                                           \
19829 _(lisp_map_server_dump, "")                                             \
19830 _(lisp_adjacencies_get, "vni <vni>")                                    \
19831 _(gpe_fwd_entry_vnis_get, "")                                           \
19832 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
19833 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
19834                                 "[table <table-id>]")                   \
19835 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
19836 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
19837 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
19838 _(gpe_get_encap_mode, "")                                               \
19839 _(lisp_gpe_add_del_iface, "up|down")                                    \
19840 _(lisp_gpe_enable_disable, "enable|disable")                            \
19841 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
19842   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
19843 _(show_lisp_rloc_probe_state, "")                                       \
19844 _(show_lisp_map_register_state, "")                                     \
19845 _(show_lisp_status, "")                                                 \
19846 _(lisp_get_map_request_itr_rlocs, "")                                   \
19847 _(show_lisp_pitr, "")                                                   \
19848 _(show_lisp_use_petr, "")                                               \
19849 _(show_lisp_map_request_mode, "")                                       \
19850 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
19851 _(af_packet_delete, "name <host interface name>")                       \
19852 _(policer_add_del, "name <policer name> <params> [del]")                \
19853 _(policer_dump, "[name <policer name>]")                                \
19854 _(policer_classify_set_interface,                                       \
19855   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
19856   "  [l2-table <nn>] [del]")                                            \
19857 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
19858 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
19859     "[master|slave]")                                                   \
19860 _(netmap_delete, "name <interface name>")                               \
19861 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
19862 _(mpls_fib_dump, "")                                                    \
19863 _(classify_table_ids, "")                                               \
19864 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
19865 _(classify_table_info, "table_id <nn>")                                 \
19866 _(classify_session_dump, "table_id <nn>")                               \
19867 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
19868     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
19869     "[template_interval <nn>] [udp_checksum]")                          \
19870 _(ipfix_exporter_dump, "")                                              \
19871 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
19872 _(ipfix_classify_stream_dump, "")                                       \
19873 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
19874 _(ipfix_classify_table_dump, "")                                        \
19875 _(sw_interface_span_enable_disable, "[src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
19876 _(sw_interface_span_dump, "")                                           \
19877 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
19878 _(pg_create_interface, "if_id <nn>")                                    \
19879 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
19880 _(pg_enable_disable, "[stream <id>] disable")                           \
19881 _(ip_source_and_port_range_check_add_del,                               \
19882   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
19883 _(ip_source_and_port_range_check_interface_add_del,                     \
19884   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
19885   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
19886 _(ipsec_gre_add_del_tunnel,                                             \
19887   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
19888 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
19889 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
19890 _(l2_interface_pbb_tag_rewrite,                                         \
19891   "<intfc> | sw_if_index <nn> \n"                                       \
19892   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
19893   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
19894 _(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
19895 _(flow_classify_set_interface,                                          \
19896   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
19897 _(flow_classify_dump, "type [ip4|ip6]")                                 \
19898 _(ip_fib_dump, "")                                                      \
19899 _(ip_mfib_dump, "")                                                     \
19900 _(ip6_fib_dump, "")                                                     \
19901 _(ip6_mfib_dump, "")                                                    \
19902 _(feature_enable_disable, "arc_name <arc_name> "                        \
19903   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
19904 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
19905 "[disable]")                                                            \
19906 _(l2_xconnect_dump, "")                                                 \
19907 _(sw_interface_set_mtu, "<intfc> | sw_if_index <nn> mtu <nn>")        \
19908 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
19909 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
19910 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
19911 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>")
19912
19913 /* List of command functions, CLI names map directly to functions */
19914 #define foreach_cli_function                                    \
19915 _(comment, "usage: comment <ignore-rest-of-line>")              \
19916 _(dump_interface_table, "usage: dump_interface_table")          \
19917 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
19918 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
19919 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
19920 _(dump_stats_table, "usage: dump_stats_table")                  \
19921 _(dump_macro_table, "usage: dump_macro_table ")                 \
19922 _(dump_node_table, "usage: dump_node_table")                    \
19923 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
19924 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
19925 _(echo, "usage: echo <message>")                                \
19926 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
19927 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
19928 _(help, "usage: help")                                          \
19929 _(q, "usage: quit")                                             \
19930 _(quit, "usage: quit")                                          \
19931 _(search_node_table, "usage: search_node_table <name>...")      \
19932 _(set, "usage: set <variable-name> <value>")                    \
19933 _(script, "usage: script <file-name>")                          \
19934 _(unset, "usage: unset <variable-name>")
19935
19936 #define _(N,n)                                  \
19937     static void vl_api_##n##_t_handler_uni      \
19938     (vl_api_##n##_t * mp)                       \
19939     {                                           \
19940         vat_main_t * vam = &vat_main;           \
19941         if (vam->json_output) {                 \
19942             vl_api_##n##_t_handler_json(mp);    \
19943         } else {                                \
19944             vl_api_##n##_t_handler(mp);         \
19945         }                                       \
19946     }
19947 foreach_vpe_api_reply_msg;
19948 #if VPP_API_TEST_BUILTIN == 0
19949 foreach_standalone_reply_msg;
19950 #endif
19951 #undef _
19952
19953 void
19954 vat_api_hookup (vat_main_t * vam)
19955 {
19956 #define _(N,n)                                                  \
19957     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
19958                            vl_api_##n##_t_handler_uni,          \
19959                            vl_noop_handler,                     \
19960                            vl_api_##n##_t_endian,               \
19961                            vl_api_##n##_t_print,                \
19962                            sizeof(vl_api_##n##_t), 1);
19963   foreach_vpe_api_reply_msg;
19964 #if VPP_API_TEST_BUILTIN == 0
19965   foreach_standalone_reply_msg;
19966 #endif
19967 #undef _
19968
19969 #if (VPP_API_TEST_BUILTIN==0)
19970   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
19971
19972   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
19973
19974   vam->function_by_name = hash_create_string (0, sizeof (uword));
19975
19976   vam->help_by_name = hash_create_string (0, sizeof (uword));
19977 #endif
19978
19979   /* API messages we can send */
19980 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
19981   foreach_vpe_api_msg;
19982 #undef _
19983
19984   /* Help strings */
19985 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
19986   foreach_vpe_api_msg;
19987 #undef _
19988
19989   /* CLI functions */
19990 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
19991   foreach_cli_function;
19992 #undef _
19993
19994   /* Help strings */
19995 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
19996   foreach_cli_function;
19997 #undef _
19998 }
19999
20000 #if VPP_API_TEST_BUILTIN
20001 static clib_error_t *
20002 vat_api_hookup_shim (vlib_main_t * vm)
20003 {
20004   vat_api_hookup (&vat_main);
20005   return 0;
20006 }
20007
20008 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
20009 #endif
20010
20011 /*
20012  * fd.io coding-style-patch-verification: ON
20013  *
20014  * Local Variables:
20015  * eval: (c-set-style "gnu")
20016  * End:
20017  */