FIB table add/delete API only
[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_event_t_handler
976   (vl_api_sw_interface_event_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_event_t_handler_json
988   (vl_api_sw_interface_event_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 static void
1287 vl_api_l2_macs_event_t_handler (vl_api_l2_macs_event_t * mp)
1288 {
1289   u32 n_macs = ntohl (mp->n_macs);
1290   errmsg ("L2MAC event recived with pid %d cl-idx %d for %d macs: \n",
1291           ntohl (mp->pid), mp->client_index, n_macs);
1292   int i;
1293   for (i = 0; i < n_macs; i++)
1294     {
1295       vl_api_mac_entry_t *mac = &mp->mac[i];
1296       errmsg (" [%d] sw_if_index %d  mac_addr %U  is_del %d \n",
1297               i + 1, ntohl (mac->sw_if_index),
1298               format_ethernet_address, mac->mac_addr, mac->is_del);
1299       if (i == 1000)
1300         break;
1301     }
1302 }
1303
1304 static void
1305 vl_api_l2_macs_event_t_handler_json (vl_api_l2_macs_event_t * mp)
1306 {
1307   /* JSON output not supported */
1308 }
1309
1310 #define vl_api_bridge_domain_details_t_endian vl_noop_handler
1311 #define vl_api_bridge_domain_details_t_print vl_noop_handler
1312
1313 /*
1314  * Special-case: build the bridge domain table, maintain
1315  * the next bd id vbl.
1316  */
1317 static void vl_api_bridge_domain_details_t_handler
1318   (vl_api_bridge_domain_details_t * mp)
1319 {
1320   vat_main_t *vam = &vat_main;
1321   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1322   int i;
1323
1324   print (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-3s",
1325          " ID", "LRN", "FWD", "FLD", "BVI", "#IF");
1326
1327   print (vam->ofp, "%3d %3d %3d %3d %3d %3d",
1328          ntohl (mp->bd_id), mp->learn, mp->forward,
1329          mp->flood, ntohl (mp->bvi_sw_if_index), n_sw_ifs);
1330
1331   if (n_sw_ifs)
1332     {
1333       vl_api_bridge_domain_sw_if_t *sw_ifs;
1334       print (vam->ofp, "\n\n%s %s  %s", "sw_if_index", "SHG",
1335              "Interface Name");
1336
1337       sw_ifs = mp->sw_if_details;
1338       for (i = 0; i < n_sw_ifs; i++)
1339         {
1340           u8 *sw_if_name = 0;
1341           u32 sw_if_index;
1342           hash_pair_t *p;
1343
1344           sw_if_index = ntohl (sw_ifs->sw_if_index);
1345
1346           /* *INDENT-OFF* */
1347           hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1348                              ({
1349                                if ((u32) p->value[0] == sw_if_index)
1350                                  {
1351                                    sw_if_name = (u8 *)(p->key);
1352                                    break;
1353                                  }
1354                              }));
1355           /* *INDENT-ON* */
1356           print (vam->ofp, "%7d     %3d  %s", sw_if_index,
1357                  sw_ifs->shg, sw_if_name ? (char *) sw_if_name :
1358                  "sw_if_index not found!");
1359
1360           sw_ifs++;
1361         }
1362     }
1363 }
1364
1365 static void vl_api_bridge_domain_details_t_handler_json
1366   (vl_api_bridge_domain_details_t * mp)
1367 {
1368   vat_main_t *vam = &vat_main;
1369   vat_json_node_t *node, *array = NULL;
1370   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1371
1372   if (VAT_JSON_ARRAY != vam->json_tree.type)
1373     {
1374       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1375       vat_json_init_array (&vam->json_tree);
1376     }
1377   node = vat_json_array_add (&vam->json_tree);
1378
1379   vat_json_init_object (node);
1380   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1381   vat_json_object_add_uint (node, "flood", mp->flood);
1382   vat_json_object_add_uint (node, "forward", mp->forward);
1383   vat_json_object_add_uint (node, "learn", mp->learn);
1384   vat_json_object_add_uint (node, "bvi_sw_if_index",
1385                             ntohl (mp->bvi_sw_if_index));
1386   vat_json_object_add_uint (node, "n_sw_ifs", n_sw_ifs);
1387   array = vat_json_object_add (node, "sw_if");
1388   vat_json_init_array (array);
1389
1390
1391
1392   if (n_sw_ifs)
1393     {
1394       vl_api_bridge_domain_sw_if_t *sw_ifs;
1395       int i;
1396
1397       sw_ifs = mp->sw_if_details;
1398       for (i = 0; i < n_sw_ifs; i++)
1399         {
1400           node = vat_json_array_add (array);
1401           vat_json_init_object (node);
1402           vat_json_object_add_uint (node, "sw_if_index",
1403                                     ntohl (sw_ifs->sw_if_index));
1404           vat_json_object_add_uint (node, "shg", sw_ifs->shg);
1405           sw_ifs++;
1406         }
1407     }
1408 }
1409
1410 static void vl_api_control_ping_reply_t_handler
1411   (vl_api_control_ping_reply_t * mp)
1412 {
1413   vat_main_t *vam = &vat_main;
1414   i32 retval = ntohl (mp->retval);
1415   if (vam->async_mode)
1416     {
1417       vam->async_errors += (retval < 0);
1418     }
1419   else
1420     {
1421       vam->retval = retval;
1422       vam->result_ready = 1;
1423     }
1424 }
1425
1426 static void vl_api_control_ping_reply_t_handler_json
1427   (vl_api_control_ping_reply_t * mp)
1428 {
1429   vat_main_t *vam = &vat_main;
1430   i32 retval = ntohl (mp->retval);
1431
1432   if (VAT_JSON_NONE != vam->json_tree.type)
1433     {
1434       vat_json_print (vam->ofp, &vam->json_tree);
1435       vat_json_free (&vam->json_tree);
1436       vam->json_tree.type = VAT_JSON_NONE;
1437     }
1438   else
1439     {
1440       /* just print [] */
1441       vat_json_init_array (&vam->json_tree);
1442       vat_json_print (vam->ofp, &vam->json_tree);
1443       vam->json_tree.type = VAT_JSON_NONE;
1444     }
1445
1446   vam->retval = retval;
1447   vam->result_ready = 1;
1448 }
1449
1450 static void
1451   vl_api_bridge_domain_set_mac_age_reply_t_handler
1452   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1453 {
1454   vat_main_t *vam = &vat_main;
1455   i32 retval = ntohl (mp->retval);
1456   if (vam->async_mode)
1457     {
1458       vam->async_errors += (retval < 0);
1459     }
1460   else
1461     {
1462       vam->retval = retval;
1463       vam->result_ready = 1;
1464     }
1465 }
1466
1467 static void vl_api_bridge_domain_set_mac_age_reply_t_handler_json
1468   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1469 {
1470   vat_main_t *vam = &vat_main;
1471   vat_json_node_t node;
1472
1473   vat_json_init_object (&node);
1474   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1475
1476   vat_json_print (vam->ofp, &node);
1477   vat_json_free (&node);
1478
1479   vam->retval = ntohl (mp->retval);
1480   vam->result_ready = 1;
1481 }
1482
1483 static void
1484 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1485 {
1486   vat_main_t *vam = &vat_main;
1487   i32 retval = ntohl (mp->retval);
1488   if (vam->async_mode)
1489     {
1490       vam->async_errors += (retval < 0);
1491     }
1492   else
1493     {
1494       vam->retval = retval;
1495       vam->result_ready = 1;
1496     }
1497 }
1498
1499 static void vl_api_l2_flags_reply_t_handler_json
1500   (vl_api_l2_flags_reply_t * mp)
1501 {
1502   vat_main_t *vam = &vat_main;
1503   vat_json_node_t node;
1504
1505   vat_json_init_object (&node);
1506   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1507   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1508                             ntohl (mp->resulting_feature_bitmap));
1509
1510   vat_json_print (vam->ofp, &node);
1511   vat_json_free (&node);
1512
1513   vam->retval = ntohl (mp->retval);
1514   vam->result_ready = 1;
1515 }
1516
1517 static void vl_api_bridge_flags_reply_t_handler
1518   (vl_api_bridge_flags_reply_t * mp)
1519 {
1520   vat_main_t *vam = &vat_main;
1521   i32 retval = ntohl (mp->retval);
1522   if (vam->async_mode)
1523     {
1524       vam->async_errors += (retval < 0);
1525     }
1526   else
1527     {
1528       vam->retval = retval;
1529       vam->result_ready = 1;
1530     }
1531 }
1532
1533 static void vl_api_bridge_flags_reply_t_handler_json
1534   (vl_api_bridge_flags_reply_t * mp)
1535 {
1536   vat_main_t *vam = &vat_main;
1537   vat_json_node_t node;
1538
1539   vat_json_init_object (&node);
1540   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1541   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1542                             ntohl (mp->resulting_feature_bitmap));
1543
1544   vat_json_print (vam->ofp, &node);
1545   vat_json_free (&node);
1546
1547   vam->retval = ntohl (mp->retval);
1548   vam->result_ready = 1;
1549 }
1550
1551 static void vl_api_tap_connect_reply_t_handler
1552   (vl_api_tap_connect_reply_t * mp)
1553 {
1554   vat_main_t *vam = &vat_main;
1555   i32 retval = ntohl (mp->retval);
1556   if (vam->async_mode)
1557     {
1558       vam->async_errors += (retval < 0);
1559     }
1560   else
1561     {
1562       vam->retval = retval;
1563       vam->sw_if_index = ntohl (mp->sw_if_index);
1564       vam->result_ready = 1;
1565     }
1566
1567 }
1568
1569 static void vl_api_tap_connect_reply_t_handler_json
1570   (vl_api_tap_connect_reply_t * mp)
1571 {
1572   vat_main_t *vam = &vat_main;
1573   vat_json_node_t node;
1574
1575   vat_json_init_object (&node);
1576   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1577   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1578
1579   vat_json_print (vam->ofp, &node);
1580   vat_json_free (&node);
1581
1582   vam->retval = ntohl (mp->retval);
1583   vam->result_ready = 1;
1584
1585 }
1586
1587 static void
1588 vl_api_tap_modify_reply_t_handler (vl_api_tap_modify_reply_t * mp)
1589 {
1590   vat_main_t *vam = &vat_main;
1591   i32 retval = ntohl (mp->retval);
1592   if (vam->async_mode)
1593     {
1594       vam->async_errors += (retval < 0);
1595     }
1596   else
1597     {
1598       vam->retval = retval;
1599       vam->sw_if_index = ntohl (mp->sw_if_index);
1600       vam->result_ready = 1;
1601     }
1602 }
1603
1604 static void vl_api_tap_modify_reply_t_handler_json
1605   (vl_api_tap_modify_reply_t * mp)
1606 {
1607   vat_main_t *vam = &vat_main;
1608   vat_json_node_t node;
1609
1610   vat_json_init_object (&node);
1611   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1612   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1613
1614   vat_json_print (vam->ofp, &node);
1615   vat_json_free (&node);
1616
1617   vam->retval = ntohl (mp->retval);
1618   vam->result_ready = 1;
1619 }
1620
1621 static void
1622 vl_api_tap_delete_reply_t_handler (vl_api_tap_delete_reply_t * mp)
1623 {
1624   vat_main_t *vam = &vat_main;
1625   i32 retval = ntohl (mp->retval);
1626   if (vam->async_mode)
1627     {
1628       vam->async_errors += (retval < 0);
1629     }
1630   else
1631     {
1632       vam->retval = retval;
1633       vam->result_ready = 1;
1634     }
1635 }
1636
1637 static void vl_api_tap_delete_reply_t_handler_json
1638   (vl_api_tap_delete_reply_t * mp)
1639 {
1640   vat_main_t *vam = &vat_main;
1641   vat_json_node_t node;
1642
1643   vat_json_init_object (&node);
1644   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1645
1646   vat_json_print (vam->ofp, &node);
1647   vat_json_free (&node);
1648
1649   vam->retval = ntohl (mp->retval);
1650   vam->result_ready = 1;
1651 }
1652
1653 static void vl_api_mpls_tunnel_add_del_reply_t_handler
1654   (vl_api_mpls_tunnel_add_del_reply_t * mp)
1655 {
1656   vat_main_t *vam = &vat_main;
1657   i32 retval = ntohl (mp->retval);
1658   if (vam->async_mode)
1659     {
1660       vam->async_errors += (retval < 0);
1661     }
1662   else
1663     {
1664       vam->retval = retval;
1665       vam->result_ready = 1;
1666     }
1667 }
1668
1669 static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
1670   (vl_api_mpls_tunnel_add_del_reply_t * mp)
1671 {
1672   vat_main_t *vam = &vat_main;
1673   vat_json_node_t node;
1674
1675   vat_json_init_object (&node);
1676   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1677   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
1678                             ntohl (mp->sw_if_index));
1679
1680   vat_json_print (vam->ofp, &node);
1681   vat_json_free (&node);
1682
1683   vam->retval = ntohl (mp->retval);
1684   vam->result_ready = 1;
1685 }
1686
1687 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
1688   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1689 {
1690   vat_main_t *vam = &vat_main;
1691   i32 retval = ntohl (mp->retval);
1692   if (vam->async_mode)
1693     {
1694       vam->async_errors += (retval < 0);
1695     }
1696   else
1697     {
1698       vam->retval = retval;
1699       vam->sw_if_index = ntohl (mp->sw_if_index);
1700       vam->result_ready = 1;
1701     }
1702 }
1703
1704 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
1705   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1706 {
1707   vat_main_t *vam = &vat_main;
1708   vat_json_node_t node;
1709
1710   vat_json_init_object (&node);
1711   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1712   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1713
1714   vat_json_print (vam->ofp, &node);
1715   vat_json_free (&node);
1716
1717   vam->retval = ntohl (mp->retval);
1718   vam->result_ready = 1;
1719 }
1720
1721 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler
1722   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
1723 {
1724   vat_main_t *vam = &vat_main;
1725   i32 retval = ntohl (mp->retval);
1726   if (vam->async_mode)
1727     {
1728       vam->async_errors += (retval < 0);
1729     }
1730   else
1731     {
1732       vam->retval = retval;
1733       vam->result_ready = 1;
1734     }
1735 }
1736
1737 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler_json
1738   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
1739 {
1740   vat_main_t *vam = &vat_main;
1741   vat_json_node_t node;
1742
1743   vat_json_init_object (&node);
1744   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1745   vat_json_object_add_uint (&node, "fwd_entry_index",
1746                             clib_net_to_host_u32 (mp->fwd_entry_index));
1747
1748   vat_json_print (vam->ofp, &node);
1749   vat_json_free (&node);
1750
1751   vam->retval = ntohl (mp->retval);
1752   vam->result_ready = 1;
1753 }
1754
1755 static void vl_api_one_add_del_locator_set_reply_t_handler
1756   (vl_api_one_add_del_locator_set_reply_t * mp)
1757 {
1758   vat_main_t *vam = &vat_main;
1759   i32 retval = ntohl (mp->retval);
1760   if (vam->async_mode)
1761     {
1762       vam->async_errors += (retval < 0);
1763     }
1764   else
1765     {
1766       vam->retval = retval;
1767       vam->result_ready = 1;
1768     }
1769 }
1770
1771 static void vl_api_one_add_del_locator_set_reply_t_handler_json
1772   (vl_api_one_add_del_locator_set_reply_t * mp)
1773 {
1774   vat_main_t *vam = &vat_main;
1775   vat_json_node_t node;
1776
1777   vat_json_init_object (&node);
1778   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1779   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
1780
1781   vat_json_print (vam->ofp, &node);
1782   vat_json_free (&node);
1783
1784   vam->retval = ntohl (mp->retval);
1785   vam->result_ready = 1;
1786 }
1787
1788 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
1789   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1790 {
1791   vat_main_t *vam = &vat_main;
1792   i32 retval = ntohl (mp->retval);
1793   if (vam->async_mode)
1794     {
1795       vam->async_errors += (retval < 0);
1796     }
1797   else
1798     {
1799       vam->retval = retval;
1800       vam->sw_if_index = ntohl (mp->sw_if_index);
1801       vam->result_ready = 1;
1802     }
1803 }
1804
1805 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
1806   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1807 {
1808   vat_main_t *vam = &vat_main;
1809   vat_json_node_t node;
1810
1811   vat_json_init_object (&node);
1812   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1813   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1814
1815   vat_json_print (vam->ofp, &node);
1816   vat_json_free (&node);
1817
1818   vam->retval = ntohl (mp->retval);
1819   vam->result_ready = 1;
1820 }
1821
1822 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler
1823   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
1824 {
1825   vat_main_t *vam = &vat_main;
1826   i32 retval = ntohl (mp->retval);
1827   if (vam->async_mode)
1828     {
1829       vam->async_errors += (retval < 0);
1830     }
1831   else
1832     {
1833       vam->retval = retval;
1834       vam->sw_if_index = ntohl (mp->sw_if_index);
1835       vam->result_ready = 1;
1836     }
1837 }
1838
1839 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler_json
1840   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
1841 {
1842   vat_main_t *vam = &vat_main;
1843   vat_json_node_t node;
1844
1845   vat_json_init_object (&node);
1846   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1847   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1848
1849   vat_json_print (vam->ofp, &node);
1850   vat_json_free (&node);
1851
1852   vam->retval = ntohl (mp->retval);
1853   vam->result_ready = 1;
1854 }
1855
1856 static void vl_api_gre_add_del_tunnel_reply_t_handler
1857   (vl_api_gre_add_del_tunnel_reply_t * mp)
1858 {
1859   vat_main_t *vam = &vat_main;
1860   i32 retval = ntohl (mp->retval);
1861   if (vam->async_mode)
1862     {
1863       vam->async_errors += (retval < 0);
1864     }
1865   else
1866     {
1867       vam->retval = retval;
1868       vam->sw_if_index = ntohl (mp->sw_if_index);
1869       vam->result_ready = 1;
1870     }
1871 }
1872
1873 static void vl_api_gre_add_del_tunnel_reply_t_handler_json
1874   (vl_api_gre_add_del_tunnel_reply_t * mp)
1875 {
1876   vat_main_t *vam = &vat_main;
1877   vat_json_node_t node;
1878
1879   vat_json_init_object (&node);
1880   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1881   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1882
1883   vat_json_print (vam->ofp, &node);
1884   vat_json_free (&node);
1885
1886   vam->retval = ntohl (mp->retval);
1887   vam->result_ready = 1;
1888 }
1889
1890 static void vl_api_create_vhost_user_if_reply_t_handler
1891   (vl_api_create_vhost_user_if_reply_t * mp)
1892 {
1893   vat_main_t *vam = &vat_main;
1894   i32 retval = ntohl (mp->retval);
1895   if (vam->async_mode)
1896     {
1897       vam->async_errors += (retval < 0);
1898     }
1899   else
1900     {
1901       vam->retval = retval;
1902       vam->sw_if_index = ntohl (mp->sw_if_index);
1903       vam->result_ready = 1;
1904     }
1905 }
1906
1907 static void vl_api_create_vhost_user_if_reply_t_handler_json
1908   (vl_api_create_vhost_user_if_reply_t * mp)
1909 {
1910   vat_main_t *vam = &vat_main;
1911   vat_json_node_t node;
1912
1913   vat_json_init_object (&node);
1914   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1915   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1916
1917   vat_json_print (vam->ofp, &node);
1918   vat_json_free (&node);
1919
1920   vam->retval = ntohl (mp->retval);
1921   vam->result_ready = 1;
1922 }
1923
1924 static void vl_api_ip_address_details_t_handler
1925   (vl_api_ip_address_details_t * mp)
1926 {
1927   vat_main_t *vam = &vat_main;
1928   static ip_address_details_t empty_ip_address_details = { {0} };
1929   ip_address_details_t *address = NULL;
1930   ip_details_t *current_ip_details = NULL;
1931   ip_details_t *details = NULL;
1932
1933   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
1934
1935   if (!details || vam->current_sw_if_index >= vec_len (details)
1936       || !details[vam->current_sw_if_index].present)
1937     {
1938       errmsg ("ip address details arrived but not stored");
1939       errmsg ("ip_dump should be called first");
1940       return;
1941     }
1942
1943   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
1944
1945 #define addresses (current_ip_details->addr)
1946
1947   vec_validate_init_empty (addresses, vec_len (addresses),
1948                            empty_ip_address_details);
1949
1950   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
1951
1952   clib_memcpy (&address->ip, &mp->ip, sizeof (address->ip));
1953   address->prefix_length = mp->prefix_length;
1954 #undef addresses
1955 }
1956
1957 static void vl_api_ip_address_details_t_handler_json
1958   (vl_api_ip_address_details_t * mp)
1959 {
1960   vat_main_t *vam = &vat_main;
1961   vat_json_node_t *node = NULL;
1962   struct in6_addr ip6;
1963   struct in_addr ip4;
1964
1965   if (VAT_JSON_ARRAY != vam->json_tree.type)
1966     {
1967       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1968       vat_json_init_array (&vam->json_tree);
1969     }
1970   node = vat_json_array_add (&vam->json_tree);
1971
1972   vat_json_init_object (node);
1973   if (vam->is_ipv6)
1974     {
1975       clib_memcpy (&ip6, mp->ip, sizeof (ip6));
1976       vat_json_object_add_ip6 (node, "ip", ip6);
1977     }
1978   else
1979     {
1980       clib_memcpy (&ip4, mp->ip, sizeof (ip4));
1981       vat_json_object_add_ip4 (node, "ip", ip4);
1982     }
1983   vat_json_object_add_uint (node, "prefix_length", mp->prefix_length);
1984 }
1985
1986 static void
1987 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
1988 {
1989   vat_main_t *vam = &vat_main;
1990   static ip_details_t empty_ip_details = { 0 };
1991   ip_details_t *ip = NULL;
1992   u32 sw_if_index = ~0;
1993
1994   sw_if_index = ntohl (mp->sw_if_index);
1995
1996   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1997                            sw_if_index, empty_ip_details);
1998
1999   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2000                          sw_if_index);
2001
2002   ip->present = 1;
2003 }
2004
2005 static void
2006 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
2007 {
2008   vat_main_t *vam = &vat_main;
2009
2010   if (VAT_JSON_ARRAY != vam->json_tree.type)
2011     {
2012       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2013       vat_json_init_array (&vam->json_tree);
2014     }
2015   vat_json_array_add_uint (&vam->json_tree,
2016                            clib_net_to_host_u32 (mp->sw_if_index));
2017 }
2018
2019 static void vl_api_map_domain_details_t_handler_json
2020   (vl_api_map_domain_details_t * mp)
2021 {
2022   vat_json_node_t *node = NULL;
2023   vat_main_t *vam = &vat_main;
2024   struct in6_addr ip6;
2025   struct in_addr ip4;
2026
2027   if (VAT_JSON_ARRAY != vam->json_tree.type)
2028     {
2029       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2030       vat_json_init_array (&vam->json_tree);
2031     }
2032
2033   node = vat_json_array_add (&vam->json_tree);
2034   vat_json_init_object (node);
2035
2036   vat_json_object_add_uint (node, "domain_index",
2037                             clib_net_to_host_u32 (mp->domain_index));
2038   clib_memcpy (&ip6, mp->ip6_prefix, sizeof (ip6));
2039   vat_json_object_add_ip6 (node, "ip6_prefix", ip6);
2040   clib_memcpy (&ip4, mp->ip4_prefix, sizeof (ip4));
2041   vat_json_object_add_ip4 (node, "ip4_prefix", ip4);
2042   clib_memcpy (&ip6, mp->ip6_src, sizeof (ip6));
2043   vat_json_object_add_ip6 (node, "ip6_src", ip6);
2044   vat_json_object_add_int (node, "ip6_prefix_len", mp->ip6_prefix_len);
2045   vat_json_object_add_int (node, "ip4_prefix_len", mp->ip4_prefix_len);
2046   vat_json_object_add_int (node, "ip6_src_len", mp->ip6_src_len);
2047   vat_json_object_add_int (node, "ea_bits_len", mp->ea_bits_len);
2048   vat_json_object_add_int (node, "psid_offset", mp->psid_offset);
2049   vat_json_object_add_int (node, "psid_length", mp->psid_length);
2050   vat_json_object_add_uint (node, "flags", mp->flags);
2051   vat_json_object_add_uint (node, "mtu", clib_net_to_host_u16 (mp->mtu));
2052   vat_json_object_add_int (node, "is_translation", mp->is_translation);
2053 }
2054
2055 static void vl_api_map_domain_details_t_handler
2056   (vl_api_map_domain_details_t * mp)
2057 {
2058   vat_main_t *vam = &vat_main;
2059
2060   if (mp->is_translation)
2061     {
2062       print (vam->ofp,
2063              "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U/%d (ip6-src) index: %u",
2064              format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
2065              format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
2066              format_ip6_address, mp->ip6_src, mp->ip6_src_len,
2067              clib_net_to_host_u32 (mp->domain_index));
2068     }
2069   else
2070     {
2071       print (vam->ofp,
2072              "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U (ip6-src) index: %u",
2073              format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
2074              format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
2075              format_ip6_address, mp->ip6_src,
2076              clib_net_to_host_u32 (mp->domain_index));
2077     }
2078   print (vam->ofp, "  ea-len %d psid-offset %d psid-len %d mtu %d %s",
2079          mp->ea_bits_len, mp->psid_offset, mp->psid_length, mp->mtu,
2080          mp->is_translation ? "map-t" : "");
2081 }
2082
2083 static void vl_api_map_rule_details_t_handler_json
2084   (vl_api_map_rule_details_t * mp)
2085 {
2086   struct in6_addr ip6;
2087   vat_json_node_t *node = NULL;
2088   vat_main_t *vam = &vat_main;
2089
2090   if (VAT_JSON_ARRAY != vam->json_tree.type)
2091     {
2092       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2093       vat_json_init_array (&vam->json_tree);
2094     }
2095
2096   node = vat_json_array_add (&vam->json_tree);
2097   vat_json_init_object (node);
2098
2099   vat_json_object_add_uint (node, "psid", clib_net_to_host_u16 (mp->psid));
2100   clib_memcpy (&ip6, mp->ip6_dst, sizeof (ip6));
2101   vat_json_object_add_ip6 (node, "ip6_dst", ip6);
2102 }
2103
2104 static void
2105 vl_api_map_rule_details_t_handler (vl_api_map_rule_details_t * mp)
2106 {
2107   vat_main_t *vam = &vat_main;
2108   print (vam->ofp, " %d (psid) %U (ip6-dst)",
2109          clib_net_to_host_u16 (mp->psid), format_ip6_address, mp->ip6_dst);
2110 }
2111
2112 static void
2113 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
2114 {
2115   errmsg ("DHCP compl event: pid %d %s hostname %s host_addr %U "
2116           "router_addr %U host_mac %U",
2117           ntohl (mp->pid), mp->is_ipv6 ? "ipv6" : "ipv4", mp->hostname,
2118           format_ip4_address, &mp->host_address,
2119           format_ip4_address, &mp->router_address,
2120           format_ethernet_address, mp->host_mac);
2121 }
2122
2123 static void vl_api_dhcp_compl_event_t_handler_json
2124   (vl_api_dhcp_compl_event_t * mp)
2125 {
2126   /* JSON output not supported */
2127 }
2128
2129 static void
2130 set_simple_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
2131                               u32 counter)
2132 {
2133   vat_main_t *vam = &vat_main;
2134   static u64 default_counter = 0;
2135
2136   vec_validate_init_empty (vam->simple_interface_counters, vnet_counter_type,
2137                            NULL);
2138   vec_validate_init_empty (vam->simple_interface_counters[vnet_counter_type],
2139                            sw_if_index, default_counter);
2140   vam->simple_interface_counters[vnet_counter_type][sw_if_index] = counter;
2141 }
2142
2143 static void
2144 set_combined_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
2145                                 interface_counter_t counter)
2146 {
2147   vat_main_t *vam = &vat_main;
2148   static interface_counter_t default_counter = { 0, };
2149
2150   vec_validate_init_empty (vam->combined_interface_counters,
2151                            vnet_counter_type, NULL);
2152   vec_validate_init_empty (vam->combined_interface_counters
2153                            [vnet_counter_type], sw_if_index, default_counter);
2154   vam->combined_interface_counters[vnet_counter_type][sw_if_index] = counter;
2155 }
2156
2157 static void vl_api_vnet_interface_simple_counters_t_handler
2158   (vl_api_vnet_interface_simple_counters_t * mp)
2159 {
2160   /* not supported */
2161 }
2162
2163 static void vl_api_vnet_interface_combined_counters_t_handler
2164   (vl_api_vnet_interface_combined_counters_t * mp)
2165 {
2166   /* not supported */
2167 }
2168
2169 static void vl_api_vnet_interface_simple_counters_t_handler_json
2170   (vl_api_vnet_interface_simple_counters_t * mp)
2171 {
2172   u64 *v_packets;
2173   u64 packets;
2174   u32 count;
2175   u32 first_sw_if_index;
2176   int i;
2177
2178   count = ntohl (mp->count);
2179   first_sw_if_index = ntohl (mp->first_sw_if_index);
2180
2181   v_packets = (u64 *) & mp->data;
2182   for (i = 0; i < count; i++)
2183     {
2184       packets = clib_net_to_host_u64 (clib_mem_unaligned (v_packets, u64));
2185       set_simple_interface_counter (mp->vnet_counter_type,
2186                                     first_sw_if_index + i, packets);
2187       v_packets++;
2188     }
2189 }
2190
2191 static void vl_api_vnet_interface_combined_counters_t_handler_json
2192   (vl_api_vnet_interface_combined_counters_t * mp)
2193 {
2194   interface_counter_t counter;
2195   vlib_counter_t *v;
2196   u32 first_sw_if_index;
2197   int i;
2198   u32 count;
2199
2200   count = ntohl (mp->count);
2201   first_sw_if_index = ntohl (mp->first_sw_if_index);
2202
2203   v = (vlib_counter_t *) & mp->data;
2204   for (i = 0; i < count; i++)
2205     {
2206       counter.packets =
2207         clib_net_to_host_u64 (clib_mem_unaligned (&v->packets, u64));
2208       counter.bytes =
2209         clib_net_to_host_u64 (clib_mem_unaligned (&v->bytes, u64));
2210       set_combined_interface_counter (mp->vnet_counter_type,
2211                                       first_sw_if_index + i, counter);
2212       v++;
2213     }
2214 }
2215
2216 static u32
2217 ip4_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2218 {
2219   vat_main_t *vam = &vat_main;
2220   u32 i;
2221
2222   for (i = 0; i < vec_len (vam->ip4_fib_counters_vrf_id_by_index); i++)
2223     {
2224       if (vam->ip4_fib_counters_vrf_id_by_index[i] == vrf_id)
2225         {
2226           return i;
2227         }
2228     }
2229   return ~0;
2230 }
2231
2232 static u32
2233 ip6_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2234 {
2235   vat_main_t *vam = &vat_main;
2236   u32 i;
2237
2238   for (i = 0; i < vec_len (vam->ip6_fib_counters_vrf_id_by_index); i++)
2239     {
2240       if (vam->ip6_fib_counters_vrf_id_by_index[i] == vrf_id)
2241         {
2242           return i;
2243         }
2244     }
2245   return ~0;
2246 }
2247
2248 static void vl_api_vnet_ip4_fib_counters_t_handler
2249   (vl_api_vnet_ip4_fib_counters_t * mp)
2250 {
2251   /* not supported */
2252 }
2253
2254 static void vl_api_vnet_ip4_fib_counters_t_handler_json
2255   (vl_api_vnet_ip4_fib_counters_t * mp)
2256 {
2257   vat_main_t *vam = &vat_main;
2258   vl_api_ip4_fib_counter_t *v;
2259   ip4_fib_counter_t *counter;
2260   struct in_addr ip4;
2261   u32 vrf_id;
2262   u32 vrf_index;
2263   u32 count;
2264   int i;
2265
2266   vrf_id = ntohl (mp->vrf_id);
2267   vrf_index = ip4_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2268   if (~0 == vrf_index)
2269     {
2270       vrf_index = vec_len (vam->ip4_fib_counters_vrf_id_by_index);
2271       vec_validate (vam->ip4_fib_counters_vrf_id_by_index, vrf_index);
2272       vam->ip4_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2273       vec_validate (vam->ip4_fib_counters, vrf_index);
2274       vam->ip4_fib_counters[vrf_index] = NULL;
2275     }
2276
2277   vec_free (vam->ip4_fib_counters[vrf_index]);
2278   v = (vl_api_ip4_fib_counter_t *) & mp->c;
2279   count = ntohl (mp->count);
2280   for (i = 0; i < count; i++)
2281     {
2282       vec_validate (vam->ip4_fib_counters[vrf_index], i);
2283       counter = &vam->ip4_fib_counters[vrf_index][i];
2284       clib_memcpy (&ip4, &v->address, sizeof (ip4));
2285       counter->address = ip4;
2286       counter->address_length = v->address_length;
2287       counter->packets = clib_net_to_host_u64 (v->packets);
2288       counter->bytes = clib_net_to_host_u64 (v->bytes);
2289       v++;
2290     }
2291 }
2292
2293 static void vl_api_vnet_ip4_nbr_counters_t_handler
2294   (vl_api_vnet_ip4_nbr_counters_t * mp)
2295 {
2296   /* not supported */
2297 }
2298
2299 static void vl_api_vnet_ip4_nbr_counters_t_handler_json
2300   (vl_api_vnet_ip4_nbr_counters_t * mp)
2301 {
2302   vat_main_t *vam = &vat_main;
2303   vl_api_ip4_nbr_counter_t *v;
2304   ip4_nbr_counter_t *counter;
2305   u32 sw_if_index;
2306   u32 count;
2307   int i;
2308
2309   sw_if_index = ntohl (mp->sw_if_index);
2310   count = ntohl (mp->count);
2311   vec_validate (vam->ip4_nbr_counters, sw_if_index);
2312
2313   if (mp->begin)
2314     vec_free (vam->ip4_nbr_counters[sw_if_index]);
2315
2316   v = (vl_api_ip4_nbr_counter_t *) & mp->c;
2317   for (i = 0; i < count; i++)
2318     {
2319       vec_validate (vam->ip4_nbr_counters[sw_if_index], i);
2320       counter = &vam->ip4_nbr_counters[sw_if_index][i];
2321       counter->address.s_addr = v->address;
2322       counter->packets = clib_net_to_host_u64 (v->packets);
2323       counter->bytes = clib_net_to_host_u64 (v->bytes);
2324       counter->linkt = v->link_type;
2325       v++;
2326     }
2327 }
2328
2329 static void vl_api_vnet_ip6_fib_counters_t_handler
2330   (vl_api_vnet_ip6_fib_counters_t * mp)
2331 {
2332   /* not supported */
2333 }
2334
2335 static void vl_api_vnet_ip6_fib_counters_t_handler_json
2336   (vl_api_vnet_ip6_fib_counters_t * mp)
2337 {
2338   vat_main_t *vam = &vat_main;
2339   vl_api_ip6_fib_counter_t *v;
2340   ip6_fib_counter_t *counter;
2341   struct in6_addr ip6;
2342   u32 vrf_id;
2343   u32 vrf_index;
2344   u32 count;
2345   int i;
2346
2347   vrf_id = ntohl (mp->vrf_id);
2348   vrf_index = ip6_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2349   if (~0 == vrf_index)
2350     {
2351       vrf_index = vec_len (vam->ip6_fib_counters_vrf_id_by_index);
2352       vec_validate (vam->ip6_fib_counters_vrf_id_by_index, vrf_index);
2353       vam->ip6_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2354       vec_validate (vam->ip6_fib_counters, vrf_index);
2355       vam->ip6_fib_counters[vrf_index] = NULL;
2356     }
2357
2358   vec_free (vam->ip6_fib_counters[vrf_index]);
2359   v = (vl_api_ip6_fib_counter_t *) & mp->c;
2360   count = ntohl (mp->count);
2361   for (i = 0; i < count; i++)
2362     {
2363       vec_validate (vam->ip6_fib_counters[vrf_index], i);
2364       counter = &vam->ip6_fib_counters[vrf_index][i];
2365       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2366       counter->address = ip6;
2367       counter->address_length = v->address_length;
2368       counter->packets = clib_net_to_host_u64 (v->packets);
2369       counter->bytes = clib_net_to_host_u64 (v->bytes);
2370       v++;
2371     }
2372 }
2373
2374 static void vl_api_vnet_ip6_nbr_counters_t_handler
2375   (vl_api_vnet_ip6_nbr_counters_t * mp)
2376 {
2377   /* not supported */
2378 }
2379
2380 static void vl_api_vnet_ip6_nbr_counters_t_handler_json
2381   (vl_api_vnet_ip6_nbr_counters_t * mp)
2382 {
2383   vat_main_t *vam = &vat_main;
2384   vl_api_ip6_nbr_counter_t *v;
2385   ip6_nbr_counter_t *counter;
2386   struct in6_addr ip6;
2387   u32 sw_if_index;
2388   u32 count;
2389   int i;
2390
2391   sw_if_index = ntohl (mp->sw_if_index);
2392   count = ntohl (mp->count);
2393   vec_validate (vam->ip6_nbr_counters, sw_if_index);
2394
2395   if (mp->begin)
2396     vec_free (vam->ip6_nbr_counters[sw_if_index]);
2397
2398   v = (vl_api_ip6_nbr_counter_t *) & mp->c;
2399   for (i = 0; i < count; i++)
2400     {
2401       vec_validate (vam->ip6_nbr_counters[sw_if_index], i);
2402       counter = &vam->ip6_nbr_counters[sw_if_index][i];
2403       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2404       counter->address = ip6;
2405       counter->packets = clib_net_to_host_u64 (v->packets);
2406       counter->bytes = clib_net_to_host_u64 (v->bytes);
2407       v++;
2408     }
2409 }
2410
2411 static void vl_api_get_first_msg_id_reply_t_handler
2412   (vl_api_get_first_msg_id_reply_t * mp)
2413 {
2414   vat_main_t *vam = &vat_main;
2415   i32 retval = ntohl (mp->retval);
2416
2417   if (vam->async_mode)
2418     {
2419       vam->async_errors += (retval < 0);
2420     }
2421   else
2422     {
2423       vam->retval = retval;
2424       vam->result_ready = 1;
2425     }
2426   if (retval >= 0)
2427     {
2428       errmsg ("first message id %d", ntohs (mp->first_msg_id));
2429     }
2430 }
2431
2432 static void vl_api_get_first_msg_id_reply_t_handler_json
2433   (vl_api_get_first_msg_id_reply_t * mp)
2434 {
2435   vat_main_t *vam = &vat_main;
2436   vat_json_node_t node;
2437
2438   vat_json_init_object (&node);
2439   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2440   vat_json_object_add_uint (&node, "first_msg_id",
2441                             (uint) ntohs (mp->first_msg_id));
2442
2443   vat_json_print (vam->ofp, &node);
2444   vat_json_free (&node);
2445
2446   vam->retval = ntohl (mp->retval);
2447   vam->result_ready = 1;
2448 }
2449
2450 static void vl_api_get_node_graph_reply_t_handler
2451   (vl_api_get_node_graph_reply_t * mp)
2452 {
2453   vat_main_t *vam = &vat_main;
2454   api_main_t *am = &api_main;
2455   i32 retval = ntohl (mp->retval);
2456   u8 *pvt_copy, *reply;
2457   void *oldheap;
2458   vlib_node_t *node;
2459   int i;
2460
2461   if (vam->async_mode)
2462     {
2463       vam->async_errors += (retval < 0);
2464     }
2465   else
2466     {
2467       vam->retval = retval;
2468       vam->result_ready = 1;
2469     }
2470
2471   /* "Should never happen..." */
2472   if (retval != 0)
2473     return;
2474
2475   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2476   pvt_copy = vec_dup (reply);
2477
2478   /* Toss the shared-memory original... */
2479   pthread_mutex_lock (&am->vlib_rp->mutex);
2480   oldheap = svm_push_data_heap (am->vlib_rp);
2481
2482   vec_free (reply);
2483
2484   svm_pop_heap (oldheap);
2485   pthread_mutex_unlock (&am->vlib_rp->mutex);
2486
2487   if (vam->graph_nodes)
2488     {
2489       hash_free (vam->graph_node_index_by_name);
2490
2491       for (i = 0; i < vec_len (vam->graph_nodes); i++)
2492         {
2493           node = vam->graph_nodes[i];
2494           vec_free (node->name);
2495           vec_free (node->next_nodes);
2496           vec_free (node);
2497         }
2498       vec_free (vam->graph_nodes);
2499     }
2500
2501   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2502   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2503   vec_free (pvt_copy);
2504
2505   for (i = 0; i < vec_len (vam->graph_nodes); i++)
2506     {
2507       node = vam->graph_nodes[i];
2508       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2509     }
2510 }
2511
2512 static void vl_api_get_node_graph_reply_t_handler_json
2513   (vl_api_get_node_graph_reply_t * mp)
2514 {
2515   vat_main_t *vam = &vat_main;
2516   api_main_t *am = &api_main;
2517   void *oldheap;
2518   vat_json_node_t node;
2519   u8 *reply;
2520
2521   /* $$$$ make this real? */
2522   vat_json_init_object (&node);
2523   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2524   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2525
2526   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2527
2528   /* Toss the shared-memory original... */
2529   pthread_mutex_lock (&am->vlib_rp->mutex);
2530   oldheap = svm_push_data_heap (am->vlib_rp);
2531
2532   vec_free (reply);
2533
2534   svm_pop_heap (oldheap);
2535   pthread_mutex_unlock (&am->vlib_rp->mutex);
2536
2537   vat_json_print (vam->ofp, &node);
2538   vat_json_free (&node);
2539
2540   vam->retval = ntohl (mp->retval);
2541   vam->result_ready = 1;
2542 }
2543
2544 static void
2545 vl_api_one_locator_details_t_handler (vl_api_one_locator_details_t * mp)
2546 {
2547   vat_main_t *vam = &vat_main;
2548   u8 *s = 0;
2549
2550   if (mp->local)
2551     {
2552       s = format (s, "%=16d%=16d%=16d",
2553                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
2554     }
2555   else
2556     {
2557       s = format (s, "%=16U%=16d%=16d",
2558                   mp->is_ipv6 ? format_ip6_address :
2559                   format_ip4_address,
2560                   mp->ip_address, mp->priority, mp->weight);
2561     }
2562
2563   print (vam->ofp, "%v", s);
2564   vec_free (s);
2565 }
2566
2567 static void
2568 vl_api_one_locator_details_t_handler_json (vl_api_one_locator_details_t * mp)
2569 {
2570   vat_main_t *vam = &vat_main;
2571   vat_json_node_t *node = NULL;
2572   struct in6_addr ip6;
2573   struct in_addr ip4;
2574
2575   if (VAT_JSON_ARRAY != vam->json_tree.type)
2576     {
2577       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2578       vat_json_init_array (&vam->json_tree);
2579     }
2580   node = vat_json_array_add (&vam->json_tree);
2581   vat_json_init_object (node);
2582
2583   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2584   vat_json_object_add_uint (node, "priority", mp->priority);
2585   vat_json_object_add_uint (node, "weight", mp->weight);
2586
2587   if (mp->local)
2588     vat_json_object_add_uint (node, "sw_if_index",
2589                               clib_net_to_host_u32 (mp->sw_if_index));
2590   else
2591     {
2592       if (mp->is_ipv6)
2593         {
2594           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2595           vat_json_object_add_ip6 (node, "address", ip6);
2596         }
2597       else
2598         {
2599           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2600           vat_json_object_add_ip4 (node, "address", ip4);
2601         }
2602     }
2603 }
2604
2605 static void
2606 vl_api_one_locator_set_details_t_handler (vl_api_one_locator_set_details_t *
2607                                           mp)
2608 {
2609   vat_main_t *vam = &vat_main;
2610   u8 *ls_name = 0;
2611
2612   ls_name = format (0, "%s", mp->ls_name);
2613
2614   print (vam->ofp, "%=10d%=15v", clib_net_to_host_u32 (mp->ls_index),
2615          ls_name);
2616   vec_free (ls_name);
2617 }
2618
2619 static void
2620   vl_api_one_locator_set_details_t_handler_json
2621   (vl_api_one_locator_set_details_t * mp)
2622 {
2623   vat_main_t *vam = &vat_main;
2624   vat_json_node_t *node = 0;
2625   u8 *ls_name = 0;
2626
2627   ls_name = format (0, "%s", mp->ls_name);
2628   vec_add1 (ls_name, 0);
2629
2630   if (VAT_JSON_ARRAY != vam->json_tree.type)
2631     {
2632       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2633       vat_json_init_array (&vam->json_tree);
2634     }
2635   node = vat_json_array_add (&vam->json_tree);
2636
2637   vat_json_init_object (node);
2638   vat_json_object_add_string_copy (node, "ls_name", ls_name);
2639   vat_json_object_add_uint (node, "ls_index",
2640                             clib_net_to_host_u32 (mp->ls_index));
2641   vec_free (ls_name);
2642 }
2643
2644 typedef struct
2645 {
2646   u32 spi;
2647   u8 si;
2648 } __attribute__ ((__packed__)) lisp_nsh_api_t;
2649
2650 uword
2651 unformat_nsh_address (unformat_input_t * input, va_list * args)
2652 {
2653   lisp_nsh_api_t *nsh = va_arg (*args, lisp_nsh_api_t *);
2654   return unformat (input, "SPI:%d SI:%d", &nsh->spi, &nsh->si);
2655 }
2656
2657 u8 *
2658 format_nsh_address_vat (u8 * s, va_list * args)
2659 {
2660   nsh_t *a = va_arg (*args, nsh_t *);
2661   return format (s, "SPI:%d SI:%d", clib_net_to_host_u32 (a->spi), a->si);
2662 }
2663
2664 static u8 *
2665 format_lisp_flat_eid (u8 * s, va_list * args)
2666 {
2667   u32 type = va_arg (*args, u32);
2668   u8 *eid = va_arg (*args, u8 *);
2669   u32 eid_len = va_arg (*args, u32);
2670
2671   switch (type)
2672     {
2673     case 0:
2674       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
2675     case 1:
2676       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
2677     case 2:
2678       return format (s, "%U", format_ethernet_address, eid);
2679     case 3:
2680       return format (s, "%U", format_nsh_address_vat, eid);
2681     }
2682   return 0;
2683 }
2684
2685 static u8 *
2686 format_lisp_eid_vat (u8 * s, va_list * args)
2687 {
2688   u32 type = va_arg (*args, u32);
2689   u8 *eid = va_arg (*args, u8 *);
2690   u32 eid_len = va_arg (*args, u32);
2691   u8 *seid = va_arg (*args, u8 *);
2692   u32 seid_len = va_arg (*args, u32);
2693   u32 is_src_dst = va_arg (*args, u32);
2694
2695   if (is_src_dst)
2696     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
2697
2698   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
2699
2700   return s;
2701 }
2702
2703 static void
2704 vl_api_one_eid_table_details_t_handler (vl_api_one_eid_table_details_t * mp)
2705 {
2706   vat_main_t *vam = &vat_main;
2707   u8 *s = 0, *eid = 0;
2708
2709   if (~0 == mp->locator_set_index)
2710     s = format (0, "action: %d", mp->action);
2711   else
2712     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
2713
2714   eid = format (0, "%U", format_lisp_eid_vat,
2715                 mp->eid_type,
2716                 mp->eid,
2717                 mp->eid_prefix_len,
2718                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2719   vec_add1 (eid, 0);
2720
2721   print (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s",
2722          clib_net_to_host_u32 (mp->vni),
2723          eid,
2724          mp->is_local ? "local" : "remote",
2725          s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
2726          clib_net_to_host_u16 (mp->key_id), mp->key);
2727
2728   vec_free (s);
2729   vec_free (eid);
2730 }
2731
2732 static void
2733 vl_api_one_eid_table_details_t_handler_json (vl_api_one_eid_table_details_t
2734                                              * mp)
2735 {
2736   vat_main_t *vam = &vat_main;
2737   vat_json_node_t *node = 0;
2738   u8 *eid = 0;
2739
2740   if (VAT_JSON_ARRAY != vam->json_tree.type)
2741     {
2742       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2743       vat_json_init_array (&vam->json_tree);
2744     }
2745   node = vat_json_array_add (&vam->json_tree);
2746
2747   vat_json_init_object (node);
2748   if (~0 == mp->locator_set_index)
2749     vat_json_object_add_uint (node, "action", mp->action);
2750   else
2751     vat_json_object_add_uint (node, "locator_set_index",
2752                               clib_net_to_host_u32 (mp->locator_set_index));
2753
2754   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
2755   if (mp->eid_type == 3)
2756     {
2757       vat_json_node_t *nsh_json = vat_json_object_add (node, "eid");
2758       vat_json_init_object (nsh_json);
2759       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) mp->eid;
2760       vat_json_object_add_uint (nsh_json, "spi",
2761                                 clib_net_to_host_u32 (nsh->spi));
2762       vat_json_object_add_uint (nsh_json, "si", nsh->si);
2763     }
2764   else
2765     {
2766       eid = format (0, "%U", format_lisp_eid_vat,
2767                     mp->eid_type,
2768                     mp->eid,
2769                     mp->eid_prefix_len,
2770                     mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2771       vec_add1 (eid, 0);
2772       vat_json_object_add_string_copy (node, "eid", eid);
2773       vec_free (eid);
2774     }
2775   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2776   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
2777   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
2778
2779   if (mp->key_id)
2780     {
2781       vat_json_object_add_uint (node, "key_id",
2782                                 clib_net_to_host_u16 (mp->key_id));
2783       vat_json_object_add_string_copy (node, "key", mp->key);
2784     }
2785 }
2786
2787 static void
2788 vl_api_one_stats_details_t_handler (vl_api_one_stats_details_t * mp)
2789 {
2790   vat_main_t *vam = &vat_main;
2791   u8 *seid = 0, *deid = 0;
2792   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
2793
2794   deid = format (0, "%U", format_lisp_eid_vat,
2795                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
2796
2797   seid = format (0, "%U", format_lisp_eid_vat,
2798                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
2799
2800   vec_add1 (deid, 0);
2801   vec_add1 (seid, 0);
2802
2803   if (mp->is_ip4)
2804     format_ip_address_fcn = format_ip4_address;
2805   else
2806     format_ip_address_fcn = format_ip6_address;
2807
2808
2809   print (vam->ofp, "([%d] %s %s) (%U %U) %u %u",
2810          clib_net_to_host_u32 (mp->vni),
2811          seid, deid,
2812          format_ip_address_fcn, mp->lloc,
2813          format_ip_address_fcn, mp->rloc,
2814          clib_net_to_host_u32 (mp->pkt_count),
2815          clib_net_to_host_u32 (mp->bytes));
2816
2817   vec_free (deid);
2818   vec_free (seid);
2819 }
2820
2821 static void
2822 vl_api_one_stats_details_t_handler_json (vl_api_one_stats_details_t * mp)
2823 {
2824   struct in6_addr ip6;
2825   struct in_addr ip4;
2826   vat_main_t *vam = &vat_main;
2827   vat_json_node_t *node = 0;
2828   u8 *deid = 0, *seid = 0;
2829
2830   if (VAT_JSON_ARRAY != vam->json_tree.type)
2831     {
2832       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2833       vat_json_init_array (&vam->json_tree);
2834     }
2835   node = vat_json_array_add (&vam->json_tree);
2836
2837   vat_json_init_object (node);
2838   deid = format (0, "%U", format_lisp_eid_vat,
2839                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
2840
2841   seid = format (0, "%U", format_lisp_eid_vat,
2842                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
2843
2844   vec_add1 (deid, 0);
2845   vec_add1 (seid, 0);
2846
2847   vat_json_object_add_string_copy (node, "seid", seid);
2848   vat_json_object_add_string_copy (node, "deid", deid);
2849   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2850
2851   if (mp->is_ip4)
2852     {
2853       clib_memcpy (&ip4, mp->lloc, sizeof (ip4));
2854       vat_json_object_add_ip4 (node, "lloc", ip4);
2855       clib_memcpy (&ip4, mp->rloc, sizeof (ip4));
2856       vat_json_object_add_ip4 (node, "rloc", ip4);
2857     }
2858   else
2859     {
2860       clib_memcpy (&ip6, mp->lloc, sizeof (ip6));
2861       vat_json_object_add_ip6 (node, "lloc", ip6);
2862       clib_memcpy (&ip6, mp->rloc, sizeof (ip6));
2863       vat_json_object_add_ip6 (node, "rloc", ip6);
2864     }
2865   vat_json_object_add_uint (node, "pkt_count",
2866                             clib_net_to_host_u32 (mp->pkt_count));
2867   vat_json_object_add_uint (node, "bytes", clib_net_to_host_u32 (mp->bytes));
2868
2869   vec_free (deid);
2870   vec_free (seid);
2871 }
2872
2873 static void
2874   vl_api_one_eid_table_map_details_t_handler
2875   (vl_api_one_eid_table_map_details_t * mp)
2876 {
2877   vat_main_t *vam = &vat_main;
2878
2879   u8 *line = format (0, "%=10d%=10d",
2880                      clib_net_to_host_u32 (mp->vni),
2881                      clib_net_to_host_u32 (mp->dp_table));
2882   print (vam->ofp, "%v", line);
2883   vec_free (line);
2884 }
2885
2886 static void
2887   vl_api_one_eid_table_map_details_t_handler_json
2888   (vl_api_one_eid_table_map_details_t * mp)
2889 {
2890   vat_main_t *vam = &vat_main;
2891   vat_json_node_t *node = NULL;
2892
2893   if (VAT_JSON_ARRAY != vam->json_tree.type)
2894     {
2895       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2896       vat_json_init_array (&vam->json_tree);
2897     }
2898   node = vat_json_array_add (&vam->json_tree);
2899   vat_json_init_object (node);
2900   vat_json_object_add_uint (node, "dp_table",
2901                             clib_net_to_host_u32 (mp->dp_table));
2902   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2903 }
2904
2905 static void
2906   vl_api_one_eid_table_vni_details_t_handler
2907   (vl_api_one_eid_table_vni_details_t * mp)
2908 {
2909   vat_main_t *vam = &vat_main;
2910
2911   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
2912   print (vam->ofp, "%v", line);
2913   vec_free (line);
2914 }
2915
2916 static void
2917   vl_api_one_eid_table_vni_details_t_handler_json
2918   (vl_api_one_eid_table_vni_details_t * mp)
2919 {
2920   vat_main_t *vam = &vat_main;
2921   vat_json_node_t *node = NULL;
2922
2923   if (VAT_JSON_ARRAY != vam->json_tree.type)
2924     {
2925       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2926       vat_json_init_array (&vam->json_tree);
2927     }
2928   node = vat_json_array_add (&vam->json_tree);
2929   vat_json_init_object (node);
2930   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2931 }
2932
2933 static void
2934   vl_api_show_one_map_register_fallback_threshold_reply_t_handler
2935   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
2936 {
2937   vat_main_t *vam = &vat_main;
2938   int retval = clib_net_to_host_u32 (mp->retval);
2939
2940   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
2941   print (vam->ofp, "fallback threshold value: %d", mp->value);
2942
2943   vam->retval = retval;
2944   vam->result_ready = 1;
2945 }
2946
2947 static void
2948   vl_api_show_one_map_register_fallback_threshold_reply_t_handler_json
2949   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
2950 {
2951   vat_main_t *vam = &vat_main;
2952   vat_json_node_t _node, *node = &_node;
2953   int retval = clib_net_to_host_u32 (mp->retval);
2954
2955   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
2956   vat_json_init_object (node);
2957   vat_json_object_add_uint (node, "value", mp->value);
2958
2959   vat_json_print (vam->ofp, node);
2960   vat_json_free (node);
2961
2962   vam->retval = retval;
2963   vam->result_ready = 1;
2964 }
2965
2966 static void
2967   vl_api_show_one_map_register_state_reply_t_handler
2968   (vl_api_show_one_map_register_state_reply_t * mp)
2969 {
2970   vat_main_t *vam = &vat_main;
2971   int retval = clib_net_to_host_u32 (mp->retval);
2972
2973   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
2974
2975   vam->retval = retval;
2976   vam->result_ready = 1;
2977 }
2978
2979 static void
2980   vl_api_show_one_map_register_state_reply_t_handler_json
2981   (vl_api_show_one_map_register_state_reply_t * mp)
2982 {
2983   vat_main_t *vam = &vat_main;
2984   vat_json_node_t _node, *node = &_node;
2985   int retval = clib_net_to_host_u32 (mp->retval);
2986
2987   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
2988
2989   vat_json_init_object (node);
2990   vat_json_object_add_string_copy (node, "state", s);
2991
2992   vat_json_print (vam->ofp, node);
2993   vat_json_free (node);
2994
2995   vam->retval = retval;
2996   vam->result_ready = 1;
2997   vec_free (s);
2998 }
2999
3000 static void
3001   vl_api_show_one_rloc_probe_state_reply_t_handler
3002   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3003 {
3004   vat_main_t *vam = &vat_main;
3005   int retval = clib_net_to_host_u32 (mp->retval);
3006
3007   if (retval)
3008     goto end;
3009
3010   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3011 end:
3012   vam->retval = retval;
3013   vam->result_ready = 1;
3014 }
3015
3016 static void
3017   vl_api_show_one_rloc_probe_state_reply_t_handler_json
3018   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3019 {
3020   vat_main_t *vam = &vat_main;
3021   vat_json_node_t _node, *node = &_node;
3022   int retval = clib_net_to_host_u32 (mp->retval);
3023
3024   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3025   vat_json_init_object (node);
3026   vat_json_object_add_string_copy (node, "state", s);
3027
3028   vat_json_print (vam->ofp, node);
3029   vat_json_free (node);
3030
3031   vam->retval = retval;
3032   vam->result_ready = 1;
3033   vec_free (s);
3034 }
3035
3036 static void
3037   vl_api_show_one_stats_enable_disable_reply_t_handler
3038   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3039 {
3040   vat_main_t *vam = &vat_main;
3041   int retval = clib_net_to_host_u32 (mp->retval);
3042
3043   if (retval)
3044     goto end;
3045
3046   print (vam->ofp, "%s", mp->is_en ? "enabled" : "disabled");
3047 end:
3048   vam->retval = retval;
3049   vam->result_ready = 1;
3050 }
3051
3052 static void
3053   vl_api_show_one_stats_enable_disable_reply_t_handler_json
3054   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3055 {
3056   vat_main_t *vam = &vat_main;
3057   vat_json_node_t _node, *node = &_node;
3058   int retval = clib_net_to_host_u32 (mp->retval);
3059
3060   u8 *s = format (0, "%s", mp->is_en ? "enabled" : "disabled");
3061   vat_json_init_object (node);
3062   vat_json_object_add_string_copy (node, "state", s);
3063
3064   vat_json_print (vam->ofp, node);
3065   vat_json_free (node);
3066
3067   vam->retval = retval;
3068   vam->result_ready = 1;
3069   vec_free (s);
3070 }
3071
3072 static void
3073 api_gpe_fwd_entry_net_to_host (vl_api_gpe_fwd_entry_t * e)
3074 {
3075   e->dp_table = clib_net_to_host_u32 (e->dp_table);
3076   e->fwd_entry_index = clib_net_to_host_u32 (e->fwd_entry_index);
3077   e->vni = clib_net_to_host_u32 (e->vni);
3078 }
3079
3080 static void
3081   gpe_fwd_entries_get_reply_t_net_to_host
3082   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3083 {
3084   u32 i;
3085
3086   mp->count = clib_net_to_host_u32 (mp->count);
3087   for (i = 0; i < mp->count; i++)
3088     {
3089       api_gpe_fwd_entry_net_to_host (&mp->entries[i]);
3090     }
3091 }
3092
3093 static u8 *
3094 format_gpe_encap_mode (u8 * s, va_list * args)
3095 {
3096   u32 mode = va_arg (*args, u32);
3097
3098   switch (mode)
3099     {
3100     case 0:
3101       return format (s, "lisp");
3102     case 1:
3103       return format (s, "vxlan");
3104     }
3105   return 0;
3106 }
3107
3108 static void
3109   vl_api_gpe_get_encap_mode_reply_t_handler
3110   (vl_api_gpe_get_encap_mode_reply_t * mp)
3111 {
3112   vat_main_t *vam = &vat_main;
3113
3114   print (vam->ofp, "gpe mode: %U", format_gpe_encap_mode, mp->encap_mode);
3115   vam->retval = ntohl (mp->retval);
3116   vam->result_ready = 1;
3117 }
3118
3119 static void
3120   vl_api_gpe_get_encap_mode_reply_t_handler_json
3121   (vl_api_gpe_get_encap_mode_reply_t * mp)
3122 {
3123   vat_main_t *vam = &vat_main;
3124   vat_json_node_t node;
3125
3126   u8 *encap_mode = format (0, "%U", format_gpe_encap_mode, mp->encap_mode);
3127   vec_add1 (encap_mode, 0);
3128
3129   vat_json_init_object (&node);
3130   vat_json_object_add_string_copy (&node, "gpe_mode", encap_mode);
3131
3132   vec_free (encap_mode);
3133   vat_json_print (vam->ofp, &node);
3134   vat_json_free (&node);
3135
3136   vam->retval = ntohl (mp->retval);
3137   vam->result_ready = 1;
3138 }
3139
3140 static void
3141   vl_api_gpe_fwd_entry_path_details_t_handler
3142   (vl_api_gpe_fwd_entry_path_details_t * mp)
3143 {
3144   vat_main_t *vam = &vat_main;
3145   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3146
3147   if (mp->lcl_loc.is_ip4)
3148     format_ip_address_fcn = format_ip4_address;
3149   else
3150     format_ip_address_fcn = format_ip6_address;
3151
3152   print (vam->ofp, "w:%d %30U %30U", mp->rmt_loc.weight,
3153          format_ip_address_fcn, &mp->lcl_loc,
3154          format_ip_address_fcn, &mp->rmt_loc);
3155 }
3156
3157 static void
3158 lisp_fill_locator_node (vat_json_node_t * n, vl_api_gpe_locator_t * loc)
3159 {
3160   struct in6_addr ip6;
3161   struct in_addr ip4;
3162
3163   if (loc->is_ip4)
3164     {
3165       clib_memcpy (&ip4, loc->addr, sizeof (ip4));
3166       vat_json_object_add_ip4 (n, "address", ip4);
3167     }
3168   else
3169     {
3170       clib_memcpy (&ip6, loc->addr, sizeof (ip6));
3171       vat_json_object_add_ip6 (n, "address", ip6);
3172     }
3173   vat_json_object_add_uint (n, "weight", loc->weight);
3174 }
3175
3176 static void
3177   vl_api_gpe_fwd_entry_path_details_t_handler_json
3178   (vl_api_gpe_fwd_entry_path_details_t * mp)
3179 {
3180   vat_main_t *vam = &vat_main;
3181   vat_json_node_t *node = NULL;
3182   vat_json_node_t *loc_node;
3183
3184   if (VAT_JSON_ARRAY != vam->json_tree.type)
3185     {
3186       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3187       vat_json_init_array (&vam->json_tree);
3188     }
3189   node = vat_json_array_add (&vam->json_tree);
3190   vat_json_init_object (node);
3191
3192   loc_node = vat_json_object_add (node, "local_locator");
3193   vat_json_init_object (loc_node);
3194   lisp_fill_locator_node (loc_node, &mp->lcl_loc);
3195
3196   loc_node = vat_json_object_add (node, "remote_locator");
3197   vat_json_init_object (loc_node);
3198   lisp_fill_locator_node (loc_node, &mp->rmt_loc);
3199 }
3200
3201 static void
3202   vl_api_gpe_fwd_entries_get_reply_t_handler
3203   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3204 {
3205   vat_main_t *vam = &vat_main;
3206   u32 i;
3207   int retval = clib_net_to_host_u32 (mp->retval);
3208   vl_api_gpe_fwd_entry_t *e;
3209
3210   if (retval)
3211     goto end;
3212
3213   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3214
3215   for (i = 0; i < mp->count; i++)
3216     {
3217       e = &mp->entries[i];
3218       print (vam->ofp, "%10d %10d %U %40U", e->fwd_entry_index, e->dp_table,
3219              format_lisp_flat_eid, e->eid_type, e->leid, e->leid_prefix_len,
3220              format_lisp_flat_eid, e->eid_type, e->reid, e->reid_prefix_len);
3221     }
3222
3223 end:
3224   vam->retval = retval;
3225   vam->result_ready = 1;
3226 }
3227
3228 static void
3229   vl_api_gpe_fwd_entries_get_reply_t_handler_json
3230   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3231 {
3232   u8 *s = 0;
3233   vat_main_t *vam = &vat_main;
3234   vat_json_node_t *e = 0, root;
3235   u32 i;
3236   int retval = clib_net_to_host_u32 (mp->retval);
3237   vl_api_gpe_fwd_entry_t *fwd;
3238
3239   if (retval)
3240     goto end;
3241
3242   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3243   vat_json_init_array (&root);
3244
3245   for (i = 0; i < mp->count; i++)
3246     {
3247       e = vat_json_array_add (&root);
3248       fwd = &mp->entries[i];
3249
3250       vat_json_init_object (e);
3251       vat_json_object_add_int (e, "fwd_entry_index", fwd->fwd_entry_index);
3252       vat_json_object_add_int (e, "dp_table", fwd->dp_table);
3253       vat_json_object_add_int (e, "vni", fwd->vni);
3254       vat_json_object_add_int (e, "action", fwd->action);
3255
3256       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->leid,
3257                   fwd->leid_prefix_len);
3258       vec_add1 (s, 0);
3259       vat_json_object_add_string_copy (e, "leid", s);
3260       vec_free (s);
3261
3262       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->reid,
3263                   fwd->reid_prefix_len);
3264       vec_add1 (s, 0);
3265       vat_json_object_add_string_copy (e, "reid", s);
3266       vec_free (s);
3267     }
3268
3269   vat_json_print (vam->ofp, &root);
3270   vat_json_free (&root);
3271
3272 end:
3273   vam->retval = retval;
3274   vam->result_ready = 1;
3275 }
3276
3277 static void
3278   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler
3279   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3280 {
3281   vat_main_t *vam = &vat_main;
3282   u32 i, n;
3283   int retval = clib_net_to_host_u32 (mp->retval);
3284   vl_api_gpe_native_fwd_rpath_t *r;
3285
3286   if (retval)
3287     goto end;
3288
3289   n = clib_net_to_host_u32 (mp->count);
3290
3291   for (i = 0; i < n; i++)
3292     {
3293       r = &mp->entries[i];
3294       print (vam->ofp, "fib_index: %d sw_if_index %d nh %U",
3295              clib_net_to_host_u32 (r->fib_index),
3296              clib_net_to_host_u32 (r->nh_sw_if_index),
3297              r->is_ip4 ? format_ip4_address : format_ip6_address, r->nh_addr);
3298     }
3299
3300 end:
3301   vam->retval = retval;
3302   vam->result_ready = 1;
3303 }
3304
3305 static void
3306   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler_json
3307   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3308 {
3309   vat_main_t *vam = &vat_main;
3310   vat_json_node_t root, *e;
3311   u32 i, n;
3312   int retval = clib_net_to_host_u32 (mp->retval);
3313   vl_api_gpe_native_fwd_rpath_t *r;
3314   u8 *s;
3315
3316   if (retval)
3317     goto end;
3318
3319   n = clib_net_to_host_u32 (mp->count);
3320   vat_json_init_array (&root);
3321
3322   for (i = 0; i < n; i++)
3323     {
3324       e = vat_json_array_add (&root);
3325       vat_json_init_object (e);
3326       r = &mp->entries[i];
3327       s =
3328         format (0, "%U", r->is_ip4 ? format_ip4_address : format_ip6_address,
3329                 r->nh_addr);
3330       vec_add1 (s, 0);
3331       vat_json_object_add_string_copy (e, "ip4", s);
3332       vec_free (s);
3333
3334       vat_json_object_add_uint (e, "fib_index",
3335                                 clib_net_to_host_u32 (r->fib_index));
3336       vat_json_object_add_uint (e, "nh_sw_if_index",
3337                                 clib_net_to_host_u32 (r->nh_sw_if_index));
3338     }
3339
3340   vat_json_print (vam->ofp, &root);
3341   vat_json_free (&root);
3342
3343 end:
3344   vam->retval = retval;
3345   vam->result_ready = 1;
3346 }
3347
3348 static void
3349   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler
3350   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3351 {
3352   vat_main_t *vam = &vat_main;
3353   u32 i, n;
3354   int retval = clib_net_to_host_u32 (mp->retval);
3355
3356   if (retval)
3357     goto end;
3358
3359   n = clib_net_to_host_u32 (mp->count);
3360
3361   for (i = 0; i < n; i++)
3362     print (vam->ofp, "%d", clib_net_to_host_u32 (mp->vnis[i]));
3363
3364 end:
3365   vam->retval = retval;
3366   vam->result_ready = 1;
3367 }
3368
3369 static void
3370   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler_json
3371   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3372 {
3373   vat_main_t *vam = &vat_main;
3374   vat_json_node_t root;
3375   u32 i, n;
3376   int retval = clib_net_to_host_u32 (mp->retval);
3377
3378   if (retval)
3379     goto end;
3380
3381   n = clib_net_to_host_u32 (mp->count);
3382   vat_json_init_array (&root);
3383
3384   for (i = 0; i < n; i++)
3385     vat_json_array_add_uint (&root, clib_net_to_host_u32 (mp->vnis[i]));
3386
3387   vat_json_print (vam->ofp, &root);
3388   vat_json_free (&root);
3389
3390 end:
3391   vam->retval = retval;
3392   vam->result_ready = 1;
3393 }
3394
3395 static void
3396   vl_api_one_l2_arp_entries_get_reply_t_handler
3397   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3398 {
3399   vat_main_t *vam = &vat_main;
3400   u32 i, n;
3401   int retval = clib_net_to_host_u32 (mp->retval);
3402
3403   if (retval)
3404     goto end;
3405
3406   n = clib_net_to_host_u32 (mp->count);
3407
3408   for (i = 0; i < n; i++)
3409     print (vam->ofp, "%U -> %U", format_ip4_address, &mp->entries[i].ip4,
3410            format_ethernet_address, mp->entries[i].mac);
3411
3412 end:
3413   vam->retval = retval;
3414   vam->result_ready = 1;
3415 }
3416
3417 static void
3418   vl_api_one_l2_arp_entries_get_reply_t_handler_json
3419   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3420 {
3421   u8 *s = 0;
3422   vat_main_t *vam = &vat_main;
3423   vat_json_node_t *e = 0, root;
3424   u32 i, n;
3425   int retval = clib_net_to_host_u32 (mp->retval);
3426   vl_api_one_l2_arp_entry_t *arp_entry;
3427
3428   if (retval)
3429     goto end;
3430
3431   n = clib_net_to_host_u32 (mp->count);
3432   vat_json_init_array (&root);
3433
3434   for (i = 0; i < n; i++)
3435     {
3436       e = vat_json_array_add (&root);
3437       arp_entry = &mp->entries[i];
3438
3439       vat_json_init_object (e);
3440       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3441       vec_add1 (s, 0);
3442
3443       vat_json_object_add_string_copy (e, "mac", s);
3444       vec_free (s);
3445
3446       s = format (0, "%U", format_ip4_address, &arp_entry->ip4);
3447       vec_add1 (s, 0);
3448       vat_json_object_add_string_copy (e, "ip4", s);
3449       vec_free (s);
3450     }
3451
3452   vat_json_print (vam->ofp, &root);
3453   vat_json_free (&root);
3454
3455 end:
3456   vam->retval = retval;
3457   vam->result_ready = 1;
3458 }
3459
3460 static void
3461   vl_api_one_l2_arp_bd_get_reply_t_handler
3462   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3463 {
3464   vat_main_t *vam = &vat_main;
3465   u32 i, n;
3466   int retval = clib_net_to_host_u32 (mp->retval);
3467
3468   if (retval)
3469     goto end;
3470
3471   n = clib_net_to_host_u32 (mp->count);
3472
3473   for (i = 0; i < n; i++)
3474     {
3475       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3476     }
3477
3478 end:
3479   vam->retval = retval;
3480   vam->result_ready = 1;
3481 }
3482
3483 static void
3484   vl_api_one_l2_arp_bd_get_reply_t_handler_json
3485   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3486 {
3487   vat_main_t *vam = &vat_main;
3488   vat_json_node_t root;
3489   u32 i, n;
3490   int retval = clib_net_to_host_u32 (mp->retval);
3491
3492   if (retval)
3493     goto end;
3494
3495   n = clib_net_to_host_u32 (mp->count);
3496   vat_json_init_array (&root);
3497
3498   for (i = 0; i < n; i++)
3499     {
3500       vat_json_array_add_uint (&root,
3501                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3502     }
3503
3504   vat_json_print (vam->ofp, &root);
3505   vat_json_free (&root);
3506
3507 end:
3508   vam->retval = retval;
3509   vam->result_ready = 1;
3510 }
3511
3512 static void
3513   vl_api_one_adjacencies_get_reply_t_handler
3514   (vl_api_one_adjacencies_get_reply_t * mp)
3515 {
3516   vat_main_t *vam = &vat_main;
3517   u32 i, n;
3518   int retval = clib_net_to_host_u32 (mp->retval);
3519   vl_api_one_adjacency_t *a;
3520
3521   if (retval)
3522     goto end;
3523
3524   n = clib_net_to_host_u32 (mp->count);
3525
3526   for (i = 0; i < n; i++)
3527     {
3528       a = &mp->adjacencies[i];
3529       print (vam->ofp, "%U %40U",
3530              format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
3531              format_lisp_flat_eid, a->eid_type, a->reid, a->reid_prefix_len);
3532     }
3533
3534 end:
3535   vam->retval = retval;
3536   vam->result_ready = 1;
3537 }
3538
3539 static void
3540   vl_api_one_adjacencies_get_reply_t_handler_json
3541   (vl_api_one_adjacencies_get_reply_t * mp)
3542 {
3543   u8 *s = 0;
3544   vat_main_t *vam = &vat_main;
3545   vat_json_node_t *e = 0, root;
3546   u32 i, n;
3547   int retval = clib_net_to_host_u32 (mp->retval);
3548   vl_api_one_adjacency_t *a;
3549
3550   if (retval)
3551     goto end;
3552
3553   n = clib_net_to_host_u32 (mp->count);
3554   vat_json_init_array (&root);
3555
3556   for (i = 0; i < n; i++)
3557     {
3558       e = vat_json_array_add (&root);
3559       a = &mp->adjacencies[i];
3560
3561       vat_json_init_object (e);
3562       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
3563                   a->leid_prefix_len);
3564       vec_add1 (s, 0);
3565       vat_json_object_add_string_copy (e, "leid", s);
3566       vec_free (s);
3567
3568       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
3569                   a->reid_prefix_len);
3570       vec_add1 (s, 0);
3571       vat_json_object_add_string_copy (e, "reid", s);
3572       vec_free (s);
3573     }
3574
3575   vat_json_print (vam->ofp, &root);
3576   vat_json_free (&root);
3577
3578 end:
3579   vam->retval = retval;
3580   vam->result_ready = 1;
3581 }
3582
3583 static void
3584 vl_api_one_map_server_details_t_handler (vl_api_one_map_server_details_t * mp)
3585 {
3586   vat_main_t *vam = &vat_main;
3587
3588   print (vam->ofp, "%=20U",
3589          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
3590          mp->ip_address);
3591 }
3592
3593 static void
3594   vl_api_one_map_server_details_t_handler_json
3595   (vl_api_one_map_server_details_t * mp)
3596 {
3597   vat_main_t *vam = &vat_main;
3598   vat_json_node_t *node = NULL;
3599   struct in6_addr ip6;
3600   struct in_addr ip4;
3601
3602   if (VAT_JSON_ARRAY != vam->json_tree.type)
3603     {
3604       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3605       vat_json_init_array (&vam->json_tree);
3606     }
3607   node = vat_json_array_add (&vam->json_tree);
3608
3609   vat_json_init_object (node);
3610   if (mp->is_ipv6)
3611     {
3612       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
3613       vat_json_object_add_ip6 (node, "map-server", ip6);
3614     }
3615   else
3616     {
3617       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
3618       vat_json_object_add_ip4 (node, "map-server", ip4);
3619     }
3620 }
3621
3622 static void
3623 vl_api_one_map_resolver_details_t_handler (vl_api_one_map_resolver_details_t
3624                                            * mp)
3625 {
3626   vat_main_t *vam = &vat_main;
3627
3628   print (vam->ofp, "%=20U",
3629          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
3630          mp->ip_address);
3631 }
3632
3633 static void
3634   vl_api_one_map_resolver_details_t_handler_json
3635   (vl_api_one_map_resolver_details_t * mp)
3636 {
3637   vat_main_t *vam = &vat_main;
3638   vat_json_node_t *node = NULL;
3639   struct in6_addr ip6;
3640   struct in_addr ip4;
3641
3642   if (VAT_JSON_ARRAY != vam->json_tree.type)
3643     {
3644       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3645       vat_json_init_array (&vam->json_tree);
3646     }
3647   node = vat_json_array_add (&vam->json_tree);
3648
3649   vat_json_init_object (node);
3650   if (mp->is_ipv6)
3651     {
3652       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
3653       vat_json_object_add_ip6 (node, "map resolver", ip6);
3654     }
3655   else
3656     {
3657       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
3658       vat_json_object_add_ip4 (node, "map resolver", ip4);
3659     }
3660 }
3661
3662 static void
3663 vl_api_show_one_status_reply_t_handler (vl_api_show_one_status_reply_t * mp)
3664 {
3665   vat_main_t *vam = &vat_main;
3666   i32 retval = ntohl (mp->retval);
3667
3668   if (0 <= retval)
3669     {
3670       print (vam->ofp, "feature: %s\ngpe: %s",
3671              mp->feature_status ? "enabled" : "disabled",
3672              mp->gpe_status ? "enabled" : "disabled");
3673     }
3674
3675   vam->retval = retval;
3676   vam->result_ready = 1;
3677 }
3678
3679 static void
3680   vl_api_show_one_status_reply_t_handler_json
3681   (vl_api_show_one_status_reply_t * mp)
3682 {
3683   vat_main_t *vam = &vat_main;
3684   vat_json_node_t node;
3685   u8 *gpe_status = NULL;
3686   u8 *feature_status = NULL;
3687
3688   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
3689   feature_status = format (0, "%s",
3690                            mp->feature_status ? "enabled" : "disabled");
3691   vec_add1 (gpe_status, 0);
3692   vec_add1 (feature_status, 0);
3693
3694   vat_json_init_object (&node);
3695   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
3696   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
3697
3698   vec_free (gpe_status);
3699   vec_free (feature_status);
3700
3701   vat_json_print (vam->ofp, &node);
3702   vat_json_free (&node);
3703
3704   vam->retval = ntohl (mp->retval);
3705   vam->result_ready = 1;
3706 }
3707
3708 static void
3709   vl_api_one_get_map_request_itr_rlocs_reply_t_handler
3710   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
3711 {
3712   vat_main_t *vam = &vat_main;
3713   i32 retval = ntohl (mp->retval);
3714
3715   if (retval >= 0)
3716     {
3717       print (vam->ofp, "%=20s", mp->locator_set_name);
3718     }
3719
3720   vam->retval = retval;
3721   vam->result_ready = 1;
3722 }
3723
3724 static void
3725   vl_api_one_get_map_request_itr_rlocs_reply_t_handler_json
3726   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
3727 {
3728   vat_main_t *vam = &vat_main;
3729   vat_json_node_t *node = NULL;
3730
3731   if (VAT_JSON_ARRAY != vam->json_tree.type)
3732     {
3733       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3734       vat_json_init_array (&vam->json_tree);
3735     }
3736   node = vat_json_array_add (&vam->json_tree);
3737
3738   vat_json_init_object (node);
3739   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
3740
3741   vat_json_print (vam->ofp, node);
3742   vat_json_free (node);
3743
3744   vam->retval = ntohl (mp->retval);
3745   vam->result_ready = 1;
3746 }
3747
3748 static u8 *
3749 format_lisp_map_request_mode (u8 * s, va_list * args)
3750 {
3751   u32 mode = va_arg (*args, u32);
3752
3753   switch (mode)
3754     {
3755     case 0:
3756       return format (0, "dst-only");
3757     case 1:
3758       return format (0, "src-dst");
3759     }
3760   return 0;
3761 }
3762
3763 static void
3764   vl_api_show_one_map_request_mode_reply_t_handler
3765   (vl_api_show_one_map_request_mode_reply_t * mp)
3766 {
3767   vat_main_t *vam = &vat_main;
3768   i32 retval = ntohl (mp->retval);
3769
3770   if (0 <= retval)
3771     {
3772       u32 mode = mp->mode;
3773       print (vam->ofp, "map_request_mode: %U",
3774              format_lisp_map_request_mode, mode);
3775     }
3776
3777   vam->retval = retval;
3778   vam->result_ready = 1;
3779 }
3780
3781 static void
3782   vl_api_show_one_map_request_mode_reply_t_handler_json
3783   (vl_api_show_one_map_request_mode_reply_t * mp)
3784 {
3785   vat_main_t *vam = &vat_main;
3786   vat_json_node_t node;
3787   u8 *s = 0;
3788   u32 mode;
3789
3790   mode = mp->mode;
3791   s = format (0, "%U", format_lisp_map_request_mode, mode);
3792   vec_add1 (s, 0);
3793
3794   vat_json_init_object (&node);
3795   vat_json_object_add_string_copy (&node, "map_request_mode", s);
3796   vat_json_print (vam->ofp, &node);
3797   vat_json_free (&node);
3798
3799   vec_free (s);
3800   vam->retval = ntohl (mp->retval);
3801   vam->result_ready = 1;
3802 }
3803
3804 static void
3805   vl_api_show_one_use_petr_reply_t_handler
3806   (vl_api_show_one_use_petr_reply_t * mp)
3807 {
3808   vat_main_t *vam = &vat_main;
3809   i32 retval = ntohl (mp->retval);
3810
3811   if (0 <= retval)
3812     {
3813       print (vam->ofp, "%s\n", mp->status ? "enabled" : "disabled");
3814       if (mp->status)
3815         {
3816           print (vam->ofp, "Proxy-ETR address; %U",
3817                  mp->is_ip4 ? format_ip4_address : format_ip6_address,
3818                  mp->address);
3819         }
3820     }
3821
3822   vam->retval = retval;
3823   vam->result_ready = 1;
3824 }
3825
3826 static void
3827   vl_api_show_one_use_petr_reply_t_handler_json
3828   (vl_api_show_one_use_petr_reply_t * mp)
3829 {
3830   vat_main_t *vam = &vat_main;
3831   vat_json_node_t node;
3832   u8 *status = 0;
3833   struct in_addr ip4;
3834   struct in6_addr ip6;
3835
3836   status = format (0, "%s", mp->status ? "enabled" : "disabled");
3837   vec_add1 (status, 0);
3838
3839   vat_json_init_object (&node);
3840   vat_json_object_add_string_copy (&node, "status", status);
3841   if (mp->status)
3842     {
3843       if (mp->is_ip4)
3844         {
3845           clib_memcpy (&ip6, mp->address, sizeof (ip6));
3846           vat_json_object_add_ip6 (&node, "address", ip6);
3847         }
3848       else
3849         {
3850           clib_memcpy (&ip4, mp->address, sizeof (ip4));
3851           vat_json_object_add_ip4 (&node, "address", ip4);
3852         }
3853     }
3854
3855   vec_free (status);
3856
3857   vat_json_print (vam->ofp, &node);
3858   vat_json_free (&node);
3859
3860   vam->retval = ntohl (mp->retval);
3861   vam->result_ready = 1;
3862 }
3863
3864 static void
3865   vl_api_show_one_nsh_mapping_reply_t_handler
3866   (vl_api_show_one_nsh_mapping_reply_t * mp)
3867 {
3868   vat_main_t *vam = &vat_main;
3869   i32 retval = ntohl (mp->retval);
3870
3871   if (0 <= retval)
3872     {
3873       print (vam->ofp, "%-20s%-16s",
3874              mp->is_set ? "set" : "not-set",
3875              mp->is_set ? (char *) mp->locator_set_name : "");
3876     }
3877
3878   vam->retval = retval;
3879   vam->result_ready = 1;
3880 }
3881
3882 static void
3883   vl_api_show_one_nsh_mapping_reply_t_handler_json
3884   (vl_api_show_one_nsh_mapping_reply_t * mp)
3885 {
3886   vat_main_t *vam = &vat_main;
3887   vat_json_node_t node;
3888   u8 *status = 0;
3889
3890   status = format (0, "%s", mp->is_set ? "yes" : "no");
3891   vec_add1 (status, 0);
3892
3893   vat_json_init_object (&node);
3894   vat_json_object_add_string_copy (&node, "is_set", status);
3895   if (mp->is_set)
3896     {
3897       vat_json_object_add_string_copy (&node, "locator_set",
3898                                        mp->locator_set_name);
3899     }
3900
3901   vec_free (status);
3902
3903   vat_json_print (vam->ofp, &node);
3904   vat_json_free (&node);
3905
3906   vam->retval = ntohl (mp->retval);
3907   vam->result_ready = 1;
3908 }
3909
3910 static void
3911   vl_api_show_one_map_register_ttl_reply_t_handler
3912   (vl_api_show_one_map_register_ttl_reply_t * mp)
3913 {
3914   vat_main_t *vam = &vat_main;
3915   i32 retval = ntohl (mp->retval);
3916
3917   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
3918
3919   if (0 <= retval)
3920     {
3921       print (vam->ofp, "ttl: %u", mp->ttl);
3922     }
3923
3924   vam->retval = retval;
3925   vam->result_ready = 1;
3926 }
3927
3928 static void
3929   vl_api_show_one_map_register_ttl_reply_t_handler_json
3930   (vl_api_show_one_map_register_ttl_reply_t * mp)
3931 {
3932   vat_main_t *vam = &vat_main;
3933   vat_json_node_t node;
3934
3935   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
3936   vat_json_init_object (&node);
3937   vat_json_object_add_uint (&node, "ttl", mp->ttl);
3938
3939   vat_json_print (vam->ofp, &node);
3940   vat_json_free (&node);
3941
3942   vam->retval = ntohl (mp->retval);
3943   vam->result_ready = 1;
3944 }
3945
3946 static void
3947 vl_api_show_one_pitr_reply_t_handler (vl_api_show_one_pitr_reply_t * mp)
3948 {
3949   vat_main_t *vam = &vat_main;
3950   i32 retval = ntohl (mp->retval);
3951
3952   if (0 <= retval)
3953     {
3954       print (vam->ofp, "%-20s%-16s",
3955              mp->status ? "enabled" : "disabled",
3956              mp->status ? (char *) mp->locator_set_name : "");
3957     }
3958
3959   vam->retval = retval;
3960   vam->result_ready = 1;
3961 }
3962
3963 static void
3964 vl_api_show_one_pitr_reply_t_handler_json (vl_api_show_one_pitr_reply_t * mp)
3965 {
3966   vat_main_t *vam = &vat_main;
3967   vat_json_node_t node;
3968   u8 *status = 0;
3969
3970   status = format (0, "%s", mp->status ? "enabled" : "disabled");
3971   vec_add1 (status, 0);
3972
3973   vat_json_init_object (&node);
3974   vat_json_object_add_string_copy (&node, "status", status);
3975   if (mp->status)
3976     {
3977       vat_json_object_add_string_copy (&node, "locator_set",
3978                                        mp->locator_set_name);
3979     }
3980
3981   vec_free (status);
3982
3983   vat_json_print (vam->ofp, &node);
3984   vat_json_free (&node);
3985
3986   vam->retval = ntohl (mp->retval);
3987   vam->result_ready = 1;
3988 }
3989
3990 static u8 *
3991 format_policer_type (u8 * s, va_list * va)
3992 {
3993   u32 i = va_arg (*va, u32);
3994
3995   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
3996     s = format (s, "1r2c");
3997   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
3998     s = format (s, "1r3c");
3999   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
4000     s = format (s, "2r3c-2698");
4001   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
4002     s = format (s, "2r3c-4115");
4003   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
4004     s = format (s, "2r3c-mef5cf1");
4005   else
4006     s = format (s, "ILLEGAL");
4007   return s;
4008 }
4009
4010 static u8 *
4011 format_policer_rate_type (u8 * s, va_list * va)
4012 {
4013   u32 i = va_arg (*va, u32);
4014
4015   if (i == SSE2_QOS_RATE_KBPS)
4016     s = format (s, "kbps");
4017   else if (i == SSE2_QOS_RATE_PPS)
4018     s = format (s, "pps");
4019   else
4020     s = format (s, "ILLEGAL");
4021   return s;
4022 }
4023
4024 static u8 *
4025 format_policer_round_type (u8 * s, va_list * va)
4026 {
4027   u32 i = va_arg (*va, u32);
4028
4029   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
4030     s = format (s, "closest");
4031   else if (i == SSE2_QOS_ROUND_TO_UP)
4032     s = format (s, "up");
4033   else if (i == SSE2_QOS_ROUND_TO_DOWN)
4034     s = format (s, "down");
4035   else
4036     s = format (s, "ILLEGAL");
4037   return s;
4038 }
4039
4040 static u8 *
4041 format_policer_action_type (u8 * s, va_list * va)
4042 {
4043   u32 i = va_arg (*va, u32);
4044
4045   if (i == SSE2_QOS_ACTION_DROP)
4046     s = format (s, "drop");
4047   else if (i == SSE2_QOS_ACTION_TRANSMIT)
4048     s = format (s, "transmit");
4049   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4050     s = format (s, "mark-and-transmit");
4051   else
4052     s = format (s, "ILLEGAL");
4053   return s;
4054 }
4055
4056 static u8 *
4057 format_dscp (u8 * s, va_list * va)
4058 {
4059   u32 i = va_arg (*va, u32);
4060   char *t = 0;
4061
4062   switch (i)
4063     {
4064 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
4065       foreach_vnet_dscp
4066 #undef _
4067     default:
4068       return format (s, "ILLEGAL");
4069     }
4070   s = format (s, "%s", t);
4071   return s;
4072 }
4073
4074 static void
4075 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
4076 {
4077   vat_main_t *vam = &vat_main;
4078   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
4079
4080   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4081     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4082   else
4083     conform_dscp_str = format (0, "");
4084
4085   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4086     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4087   else
4088     exceed_dscp_str = format (0, "");
4089
4090   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4091     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4092   else
4093     violate_dscp_str = format (0, "");
4094
4095   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
4096          "rate type %U, round type %U, %s rate, %s color-aware, "
4097          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
4098          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
4099          "conform action %U%s, exceed action %U%s, violate action %U%s",
4100          mp->name,
4101          format_policer_type, mp->type,
4102          ntohl (mp->cir),
4103          ntohl (mp->eir),
4104          clib_net_to_host_u64 (mp->cb),
4105          clib_net_to_host_u64 (mp->eb),
4106          format_policer_rate_type, mp->rate_type,
4107          format_policer_round_type, mp->round_type,
4108          mp->single_rate ? "single" : "dual",
4109          mp->color_aware ? "is" : "not",
4110          ntohl (mp->cir_tokens_per_period),
4111          ntohl (mp->pir_tokens_per_period),
4112          ntohl (mp->scale),
4113          ntohl (mp->current_limit),
4114          ntohl (mp->current_bucket),
4115          ntohl (mp->extended_limit),
4116          ntohl (mp->extended_bucket),
4117          clib_net_to_host_u64 (mp->last_update_time),
4118          format_policer_action_type, mp->conform_action_type,
4119          conform_dscp_str,
4120          format_policer_action_type, mp->exceed_action_type,
4121          exceed_dscp_str,
4122          format_policer_action_type, mp->violate_action_type,
4123          violate_dscp_str);
4124
4125   vec_free (conform_dscp_str);
4126   vec_free (exceed_dscp_str);
4127   vec_free (violate_dscp_str);
4128 }
4129
4130 static void vl_api_policer_details_t_handler_json
4131   (vl_api_policer_details_t * mp)
4132 {
4133   vat_main_t *vam = &vat_main;
4134   vat_json_node_t *node;
4135   u8 *rate_type_str, *round_type_str, *type_str;
4136   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
4137
4138   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
4139   round_type_str =
4140     format (0, "%U", format_policer_round_type, mp->round_type);
4141   type_str = format (0, "%U", format_policer_type, mp->type);
4142   conform_action_str = format (0, "%U", format_policer_action_type,
4143                                mp->conform_action_type);
4144   exceed_action_str = format (0, "%U", format_policer_action_type,
4145                               mp->exceed_action_type);
4146   violate_action_str = format (0, "%U", format_policer_action_type,
4147                                mp->violate_action_type);
4148
4149   if (VAT_JSON_ARRAY != vam->json_tree.type)
4150     {
4151       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4152       vat_json_init_array (&vam->json_tree);
4153     }
4154   node = vat_json_array_add (&vam->json_tree);
4155
4156   vat_json_init_object (node);
4157   vat_json_object_add_string_copy (node, "name", mp->name);
4158   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
4159   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
4160   vat_json_object_add_uint (node, "cb", clib_net_to_host_u64 (mp->cb));
4161   vat_json_object_add_uint (node, "eb", clib_net_to_host_u64 (mp->eb));
4162   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
4163   vat_json_object_add_string_copy (node, "round_type", round_type_str);
4164   vat_json_object_add_string_copy (node, "type", type_str);
4165   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
4166   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
4167   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
4168   vat_json_object_add_uint (node, "cir_tokens_per_period",
4169                             ntohl (mp->cir_tokens_per_period));
4170   vat_json_object_add_uint (node, "eir_tokens_per_period",
4171                             ntohl (mp->pir_tokens_per_period));
4172   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
4173   vat_json_object_add_uint (node, "current_bucket",
4174                             ntohl (mp->current_bucket));
4175   vat_json_object_add_uint (node, "extended_limit",
4176                             ntohl (mp->extended_limit));
4177   vat_json_object_add_uint (node, "extended_bucket",
4178                             ntohl (mp->extended_bucket));
4179   vat_json_object_add_uint (node, "last_update_time",
4180                             ntohl (mp->last_update_time));
4181   vat_json_object_add_string_copy (node, "conform_action",
4182                                    conform_action_str);
4183   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4184     {
4185       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4186       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
4187       vec_free (dscp_str);
4188     }
4189   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
4190   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4191     {
4192       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4193       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
4194       vec_free (dscp_str);
4195     }
4196   vat_json_object_add_string_copy (node, "violate_action",
4197                                    violate_action_str);
4198   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4199     {
4200       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4201       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
4202       vec_free (dscp_str);
4203     }
4204
4205   vec_free (rate_type_str);
4206   vec_free (round_type_str);
4207   vec_free (type_str);
4208   vec_free (conform_action_str);
4209   vec_free (exceed_action_str);
4210   vec_free (violate_action_str);
4211 }
4212
4213 static void
4214 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
4215                                            mp)
4216 {
4217   vat_main_t *vam = &vat_main;
4218   int i, count = ntohl (mp->count);
4219
4220   if (count > 0)
4221     print (vam->ofp, "classify table ids (%d) : ", count);
4222   for (i = 0; i < count; i++)
4223     {
4224       print (vam->ofp, "%d", ntohl (mp->ids[i]));
4225       print (vam->ofp, (i < count - 1) ? "," : "");
4226     }
4227   vam->retval = ntohl (mp->retval);
4228   vam->result_ready = 1;
4229 }
4230
4231 static void
4232   vl_api_classify_table_ids_reply_t_handler_json
4233   (vl_api_classify_table_ids_reply_t * mp)
4234 {
4235   vat_main_t *vam = &vat_main;
4236   int i, count = ntohl (mp->count);
4237
4238   if (count > 0)
4239     {
4240       vat_json_node_t node;
4241
4242       vat_json_init_object (&node);
4243       for (i = 0; i < count; i++)
4244         {
4245           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
4246         }
4247       vat_json_print (vam->ofp, &node);
4248       vat_json_free (&node);
4249     }
4250   vam->retval = ntohl (mp->retval);
4251   vam->result_ready = 1;
4252 }
4253
4254 static void
4255   vl_api_classify_table_by_interface_reply_t_handler
4256   (vl_api_classify_table_by_interface_reply_t * mp)
4257 {
4258   vat_main_t *vam = &vat_main;
4259   u32 table_id;
4260
4261   table_id = ntohl (mp->l2_table_id);
4262   if (table_id != ~0)
4263     print (vam->ofp, "l2 table id : %d", table_id);
4264   else
4265     print (vam->ofp, "l2 table id : No input ACL tables configured");
4266   table_id = ntohl (mp->ip4_table_id);
4267   if (table_id != ~0)
4268     print (vam->ofp, "ip4 table id : %d", table_id);
4269   else
4270     print (vam->ofp, "ip4 table id : No input ACL tables configured");
4271   table_id = ntohl (mp->ip6_table_id);
4272   if (table_id != ~0)
4273     print (vam->ofp, "ip6 table id : %d", table_id);
4274   else
4275     print (vam->ofp, "ip6 table id : No input ACL tables configured");
4276   vam->retval = ntohl (mp->retval);
4277   vam->result_ready = 1;
4278 }
4279
4280 static void
4281   vl_api_classify_table_by_interface_reply_t_handler_json
4282   (vl_api_classify_table_by_interface_reply_t * mp)
4283 {
4284   vat_main_t *vam = &vat_main;
4285   vat_json_node_t node;
4286
4287   vat_json_init_object (&node);
4288
4289   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
4290   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
4291   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
4292
4293   vat_json_print (vam->ofp, &node);
4294   vat_json_free (&node);
4295
4296   vam->retval = ntohl (mp->retval);
4297   vam->result_ready = 1;
4298 }
4299
4300 static void vl_api_policer_add_del_reply_t_handler
4301   (vl_api_policer_add_del_reply_t * mp)
4302 {
4303   vat_main_t *vam = &vat_main;
4304   i32 retval = ntohl (mp->retval);
4305   if (vam->async_mode)
4306     {
4307       vam->async_errors += (retval < 0);
4308     }
4309   else
4310     {
4311       vam->retval = retval;
4312       vam->result_ready = 1;
4313       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
4314         /*
4315          * Note: this is just barely thread-safe, depends on
4316          * the main thread spinning waiting for an answer...
4317          */
4318         errmsg ("policer index %d", ntohl (mp->policer_index));
4319     }
4320 }
4321
4322 static void vl_api_policer_add_del_reply_t_handler_json
4323   (vl_api_policer_add_del_reply_t * mp)
4324 {
4325   vat_main_t *vam = &vat_main;
4326   vat_json_node_t node;
4327
4328   vat_json_init_object (&node);
4329   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
4330   vat_json_object_add_uint (&node, "policer_index",
4331                             ntohl (mp->policer_index));
4332
4333   vat_json_print (vam->ofp, &node);
4334   vat_json_free (&node);
4335
4336   vam->retval = ntohl (mp->retval);
4337   vam->result_ready = 1;
4338 }
4339
4340 /* Format hex dump. */
4341 u8 *
4342 format_hex_bytes (u8 * s, va_list * va)
4343 {
4344   u8 *bytes = va_arg (*va, u8 *);
4345   int n_bytes = va_arg (*va, int);
4346   uword i;
4347
4348   /* Print short or long form depending on byte count. */
4349   uword short_form = n_bytes <= 32;
4350   uword indent = format_get_indent (s);
4351
4352   if (n_bytes == 0)
4353     return s;
4354
4355   for (i = 0; i < n_bytes; i++)
4356     {
4357       if (!short_form && (i % 32) == 0)
4358         s = format (s, "%08x: ", i);
4359       s = format (s, "%02x", bytes[i]);
4360       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
4361         s = format (s, "\n%U", format_white_space, indent);
4362     }
4363
4364   return s;
4365 }
4366
4367 static void
4368 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
4369                                             * mp)
4370 {
4371   vat_main_t *vam = &vat_main;
4372   i32 retval = ntohl (mp->retval);
4373   if (retval == 0)
4374     {
4375       print (vam->ofp, "classify table info :");
4376       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
4377              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
4378              ntohl (mp->miss_next_index));
4379       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
4380              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
4381              ntohl (mp->match_n_vectors));
4382       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
4383              ntohl (mp->mask_length));
4384     }
4385   vam->retval = retval;
4386   vam->result_ready = 1;
4387 }
4388
4389 static void
4390   vl_api_classify_table_info_reply_t_handler_json
4391   (vl_api_classify_table_info_reply_t * mp)
4392 {
4393   vat_main_t *vam = &vat_main;
4394   vat_json_node_t node;
4395
4396   i32 retval = ntohl (mp->retval);
4397   if (retval == 0)
4398     {
4399       vat_json_init_object (&node);
4400
4401       vat_json_object_add_int (&node, "sessions",
4402                                ntohl (mp->active_sessions));
4403       vat_json_object_add_int (&node, "nexttbl",
4404                                ntohl (mp->next_table_index));
4405       vat_json_object_add_int (&node, "nextnode",
4406                                ntohl (mp->miss_next_index));
4407       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
4408       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
4409       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
4410       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
4411                       ntohl (mp->mask_length), 0);
4412       vat_json_object_add_string_copy (&node, "mask", s);
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
4422 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
4423                                            mp)
4424 {
4425   vat_main_t *vam = &vat_main;
4426
4427   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
4428          ntohl (mp->hit_next_index), ntohl (mp->advance),
4429          ntohl (mp->opaque_index));
4430   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
4431          ntohl (mp->match_length));
4432 }
4433
4434 static void
4435   vl_api_classify_session_details_t_handler_json
4436   (vl_api_classify_session_details_t * mp)
4437 {
4438   vat_main_t *vam = &vat_main;
4439   vat_json_node_t *node = NULL;
4440
4441   if (VAT_JSON_ARRAY != vam->json_tree.type)
4442     {
4443       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4444       vat_json_init_array (&vam->json_tree);
4445     }
4446   node = vat_json_array_add (&vam->json_tree);
4447
4448   vat_json_init_object (node);
4449   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
4450   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
4451   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
4452   u8 *s =
4453     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
4454             0);
4455   vat_json_object_add_string_copy (node, "match", s);
4456 }
4457
4458 static void vl_api_pg_create_interface_reply_t_handler
4459   (vl_api_pg_create_interface_reply_t * mp)
4460 {
4461   vat_main_t *vam = &vat_main;
4462
4463   vam->retval = ntohl (mp->retval);
4464   vam->result_ready = 1;
4465 }
4466
4467 static void vl_api_pg_create_interface_reply_t_handler_json
4468   (vl_api_pg_create_interface_reply_t * mp)
4469 {
4470   vat_main_t *vam = &vat_main;
4471   vat_json_node_t node;
4472
4473   i32 retval = ntohl (mp->retval);
4474   if (retval == 0)
4475     {
4476       vat_json_init_object (&node);
4477
4478       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
4479
4480       vat_json_print (vam->ofp, &node);
4481       vat_json_free (&node);
4482     }
4483   vam->retval = ntohl (mp->retval);
4484   vam->result_ready = 1;
4485 }
4486
4487 static void vl_api_policer_classify_details_t_handler
4488   (vl_api_policer_classify_details_t * mp)
4489 {
4490   vat_main_t *vam = &vat_main;
4491
4492   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
4493          ntohl (mp->table_index));
4494 }
4495
4496 static void vl_api_policer_classify_details_t_handler_json
4497   (vl_api_policer_classify_details_t * mp)
4498 {
4499   vat_main_t *vam = &vat_main;
4500   vat_json_node_t *node;
4501
4502   if (VAT_JSON_ARRAY != vam->json_tree.type)
4503     {
4504       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4505       vat_json_init_array (&vam->json_tree);
4506     }
4507   node = vat_json_array_add (&vam->json_tree);
4508
4509   vat_json_init_object (node);
4510   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
4511   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
4512 }
4513
4514 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler
4515   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
4516 {
4517   vat_main_t *vam = &vat_main;
4518   i32 retval = ntohl (mp->retval);
4519   if (vam->async_mode)
4520     {
4521       vam->async_errors += (retval < 0);
4522     }
4523   else
4524     {
4525       vam->retval = retval;
4526       vam->sw_if_index = ntohl (mp->sw_if_index);
4527       vam->result_ready = 1;
4528     }
4529 }
4530
4531 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler_json
4532   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
4533 {
4534   vat_main_t *vam = &vat_main;
4535   vat_json_node_t node;
4536
4537   vat_json_init_object (&node);
4538   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
4539   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
4540
4541   vat_json_print (vam->ofp, &node);
4542   vat_json_free (&node);
4543
4544   vam->retval = ntohl (mp->retval);
4545   vam->result_ready = 1;
4546 }
4547
4548 static void vl_api_flow_classify_details_t_handler
4549   (vl_api_flow_classify_details_t * mp)
4550 {
4551   vat_main_t *vam = &vat_main;
4552
4553   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
4554          ntohl (mp->table_index));
4555 }
4556
4557 static void vl_api_flow_classify_details_t_handler_json
4558   (vl_api_flow_classify_details_t * mp)
4559 {
4560   vat_main_t *vam = &vat_main;
4561   vat_json_node_t *node;
4562
4563   if (VAT_JSON_ARRAY != vam->json_tree.type)
4564     {
4565       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4566       vat_json_init_array (&vam->json_tree);
4567     }
4568   node = vat_json_array_add (&vam->json_tree);
4569
4570   vat_json_init_object (node);
4571   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
4572   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
4573 }
4574
4575 #define vl_api_vnet_interface_simple_counters_t_endian vl_noop_handler
4576 #define vl_api_vnet_interface_simple_counters_t_print vl_noop_handler
4577 #define vl_api_vnet_interface_combined_counters_t_endian vl_noop_handler
4578 #define vl_api_vnet_interface_combined_counters_t_print vl_noop_handler
4579 #define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
4580 #define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler
4581 #define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler
4582 #define vl_api_vnet_ip6_fib_counters_t_print vl_noop_handler
4583 #define vl_api_vnet_ip4_nbr_counters_t_endian vl_noop_handler
4584 #define vl_api_vnet_ip4_nbr_counters_t_print vl_noop_handler
4585 #define vl_api_vnet_ip6_nbr_counters_t_endian vl_noop_handler
4586 #define vl_api_vnet_ip6_nbr_counters_t_print vl_noop_handler
4587 #define vl_api_one_adjacencies_get_reply_t_endian vl_noop_handler
4588 #define vl_api_one_adjacencies_get_reply_t_print vl_noop_handler
4589 #define vl_api_one_l2_arp_bd_get_reply_t_print vl_noop_handler
4590 #define vl_api_one_l2_arp_entries_get_reply_t_endian vl_noop_handler
4591 #define vl_api_one_l2_arp_entries_get_reply_t_print vl_noop_handler
4592 #define vl_api_one_l2_arp_bd_get_reply_t_endian vl_noop_handler
4593
4594 /*
4595  * Generate boilerplate reply handlers, which
4596  * dig the return value out of the xxx_reply_t API message,
4597  * stick it into vam->retval, and set vam->result_ready
4598  *
4599  * Could also do this by pointing N message decode slots at
4600  * a single function, but that could break in subtle ways.
4601  */
4602
4603 #define foreach_standard_reply_retval_handler           \
4604 _(sw_interface_set_flags_reply)                         \
4605 _(sw_interface_add_del_address_reply)                   \
4606 _(sw_interface_set_table_reply)                         \
4607 _(sw_interface_set_mpls_enable_reply)                   \
4608 _(sw_interface_set_vpath_reply)                         \
4609 _(sw_interface_set_vxlan_bypass_reply)                  \
4610 _(sw_interface_set_vxlan_gpe_bypass_reply)              \
4611 _(sw_interface_set_l2_bridge_reply)                     \
4612 _(bridge_domain_add_del_reply)                          \
4613 _(sw_interface_set_l2_xconnect_reply)                   \
4614 _(l2fib_add_del_reply)                                  \
4615 _(l2fib_flush_int_reply)                                \
4616 _(l2fib_flush_bd_reply)                                 \
4617 _(ip_add_del_route_reply)                               \
4618 _(ip_table_add_del_reply)                               \
4619 _(ip_mroute_add_del_reply)                              \
4620 _(mpls_route_add_del_reply)                             \
4621 _(mpls_table_add_del_reply)                             \
4622 _(mpls_ip_bind_unbind_reply)                            \
4623 _(proxy_arp_add_del_reply)                              \
4624 _(proxy_arp_intfc_enable_disable_reply)                 \
4625 _(sw_interface_set_unnumbered_reply)                    \
4626 _(ip_neighbor_add_del_reply)                            \
4627 _(reset_vrf_reply)                                      \
4628 _(oam_add_del_reply)                                    \
4629 _(reset_fib_reply)                                      \
4630 _(dhcp_proxy_config_reply)                              \
4631 _(dhcp_proxy_set_vss_reply)                             \
4632 _(dhcp_client_config_reply)                             \
4633 _(set_ip_flow_hash_reply)                               \
4634 _(sw_interface_ip6_enable_disable_reply)                \
4635 _(sw_interface_ip6_set_link_local_address_reply)        \
4636 _(ip6nd_proxy_add_del_reply)                            \
4637 _(sw_interface_ip6nd_ra_prefix_reply)                   \
4638 _(sw_interface_ip6nd_ra_config_reply)                   \
4639 _(set_arp_neighbor_limit_reply)                         \
4640 _(l2_patch_add_del_reply)                               \
4641 _(sr_policy_add_reply)                                  \
4642 _(sr_policy_mod_reply)                                  \
4643 _(sr_policy_del_reply)                                  \
4644 _(sr_localsid_add_del_reply)                            \
4645 _(sr_steering_add_del_reply)                            \
4646 _(classify_add_del_session_reply)                       \
4647 _(classify_set_interface_ip_table_reply)                \
4648 _(classify_set_interface_l2_tables_reply)               \
4649 _(l2tpv3_set_tunnel_cookies_reply)                      \
4650 _(l2tpv3_interface_enable_disable_reply)                \
4651 _(l2tpv3_set_lookup_key_reply)                          \
4652 _(l2_fib_clear_table_reply)                             \
4653 _(l2_interface_efp_filter_reply)                        \
4654 _(l2_interface_vlan_tag_rewrite_reply)                  \
4655 _(modify_vhost_user_if_reply)                           \
4656 _(delete_vhost_user_if_reply)                           \
4657 _(want_ip4_arp_events_reply)                            \
4658 _(want_ip6_nd_events_reply)                             \
4659 _(want_l2_macs_events_reply)                            \
4660 _(input_acl_set_interface_reply)                        \
4661 _(ipsec_spd_add_del_reply)                              \
4662 _(ipsec_interface_add_del_spd_reply)                    \
4663 _(ipsec_spd_add_del_entry_reply)                        \
4664 _(ipsec_sad_add_del_entry_reply)                        \
4665 _(ipsec_sa_set_key_reply)                               \
4666 _(ipsec_tunnel_if_add_del_reply)                        \
4667 _(ikev2_profile_add_del_reply)                          \
4668 _(ikev2_profile_set_auth_reply)                         \
4669 _(ikev2_profile_set_id_reply)                           \
4670 _(ikev2_profile_set_ts_reply)                           \
4671 _(ikev2_set_local_key_reply)                            \
4672 _(ikev2_set_responder_reply)                            \
4673 _(ikev2_set_ike_transforms_reply)                       \
4674 _(ikev2_set_esp_transforms_reply)                       \
4675 _(ikev2_set_sa_lifetime_reply)                          \
4676 _(ikev2_initiate_sa_init_reply)                         \
4677 _(ikev2_initiate_del_ike_sa_reply)                      \
4678 _(ikev2_initiate_del_child_sa_reply)                    \
4679 _(ikev2_initiate_rekey_child_sa_reply)                  \
4680 _(delete_loopback_reply)                                \
4681 _(bd_ip_mac_add_del_reply)                              \
4682 _(map_del_domain_reply)                                 \
4683 _(map_add_del_rule_reply)                               \
4684 _(want_interface_events_reply)                          \
4685 _(want_stats_reply)                                     \
4686 _(cop_interface_enable_disable_reply)                   \
4687 _(cop_whitelist_enable_disable_reply)                   \
4688 _(sw_interface_clear_stats_reply)                       \
4689 _(ioam_enable_reply)                              \
4690 _(ioam_disable_reply)                              \
4691 _(one_add_del_locator_reply)                            \
4692 _(one_add_del_local_eid_reply)                          \
4693 _(one_add_del_remote_mapping_reply)                     \
4694 _(one_add_del_adjacency_reply)                          \
4695 _(one_add_del_map_resolver_reply)                       \
4696 _(one_add_del_map_server_reply)                         \
4697 _(one_enable_disable_reply)                             \
4698 _(one_rloc_probe_enable_disable_reply)                  \
4699 _(one_map_register_enable_disable_reply)                \
4700 _(one_map_register_set_ttl_reply)                       \
4701 _(one_map_register_fallback_threshold_reply)            \
4702 _(one_pitr_set_locator_set_reply)                       \
4703 _(one_map_request_mode_reply)                           \
4704 _(one_add_del_map_request_itr_rlocs_reply)              \
4705 _(one_eid_table_add_del_map_reply)                      \
4706 _(one_use_petr_reply)                                   \
4707 _(one_stats_enable_disable_reply)                       \
4708 _(one_add_del_l2_arp_entry_reply)                       \
4709 _(one_stats_flush_reply)                                \
4710 _(gpe_enable_disable_reply)                             \
4711 _(gpe_set_encap_mode_reply)                             \
4712 _(gpe_add_del_iface_reply)                              \
4713 _(gpe_add_del_native_fwd_rpath_reply)                   \
4714 _(af_packet_delete_reply)                               \
4715 _(policer_classify_set_interface_reply)                 \
4716 _(netmap_create_reply)                                  \
4717 _(netmap_delete_reply)                                  \
4718 _(set_ipfix_exporter_reply)                             \
4719 _(set_ipfix_classify_stream_reply)                      \
4720 _(ipfix_classify_table_add_del_reply)                   \
4721 _(flow_classify_set_interface_reply)                    \
4722 _(sw_interface_span_enable_disable_reply)               \
4723 _(pg_capture_reply)                                     \
4724 _(pg_enable_disable_reply)                              \
4725 _(ip_source_and_port_range_check_add_del_reply)         \
4726 _(ip_source_and_port_range_check_interface_add_del_reply)\
4727 _(delete_subif_reply)                                   \
4728 _(l2_interface_pbb_tag_rewrite_reply)                   \
4729 _(punt_reply)                                           \
4730 _(feature_enable_disable_reply)                         \
4731 _(sw_interface_tag_add_del_reply)                       \
4732 _(sw_interface_set_mtu_reply)                           \
4733 _(p2p_ethernet_add_reply)                               \
4734 _(p2p_ethernet_del_reply)                               \
4735 _(lldp_config_reply)                                    \
4736 _(sw_interface_set_lldp_reply)
4737
4738 #define _(n)                                    \
4739     static void vl_api_##n##_t_handler          \
4740     (vl_api_##n##_t * mp)                       \
4741     {                                           \
4742         vat_main_t * vam = &vat_main;           \
4743         i32 retval = ntohl(mp->retval);         \
4744         if (vam->async_mode) {                  \
4745             vam->async_errors += (retval < 0);  \
4746         } else {                                \
4747             vam->retval = retval;               \
4748             vam->result_ready = 1;              \
4749         }                                       \
4750     }
4751 foreach_standard_reply_retval_handler;
4752 #undef _
4753
4754 #define _(n)                                    \
4755     static void vl_api_##n##_t_handler_json     \
4756     (vl_api_##n##_t * mp)                       \
4757     {                                           \
4758         vat_main_t * vam = &vat_main;           \
4759         vat_json_node_t node;                   \
4760         vat_json_init_object(&node);            \
4761         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
4762         vat_json_print(vam->ofp, &node);        \
4763         vam->retval = ntohl(mp->retval);        \
4764         vam->result_ready = 1;                  \
4765     }
4766 foreach_standard_reply_retval_handler;
4767 #undef _
4768
4769 /*
4770  * Table of message reply handlers, must include boilerplate handlers
4771  * we just generated
4772  */
4773
4774 #define foreach_vpe_api_reply_msg                                       \
4775 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
4776 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
4777 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
4778 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
4779 _(CONTROL_PING_REPLY, control_ping_reply)                               \
4780 _(CLI_REPLY, cli_reply)                                                 \
4781 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
4782 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
4783   sw_interface_add_del_address_reply)                                   \
4784 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
4785 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
4786 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
4787 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
4788 _(SW_INTERFACE_SET_VXLAN_GPE_BYPASS_REPLY, sw_interface_set_vxlan_gpe_bypass_reply) \
4789 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
4790   sw_interface_set_l2_xconnect_reply)                                   \
4791 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
4792   sw_interface_set_l2_bridge_reply)                                     \
4793 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
4794 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
4795 _(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply)     \
4796 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
4797 _(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply)                         \
4798 _(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply)                           \
4799 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
4800 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
4801 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
4802 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
4803 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
4804 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
4805 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
4806 _(IP_TABLE_ADD_DEL_REPLY, ip_table_add_del_reply)                       \
4807 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
4808 _(MPLS_TABLE_ADD_DEL_REPLY, mpls_table_add_del_reply)                   \
4809 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
4810 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
4811 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
4812 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
4813   proxy_arp_intfc_enable_disable_reply)                                 \
4814 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
4815 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
4816   sw_interface_set_unnumbered_reply)                                    \
4817 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
4818 _(RESET_VRF_REPLY, reset_vrf_reply)                                     \
4819 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
4820 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
4821 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
4822 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
4823 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
4824 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
4825 _(DHCP_PROXY_DETAILS, dhcp_proxy_details)                               \
4826 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
4827 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
4828 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
4829   sw_interface_ip6_enable_disable_reply)                                \
4830 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY,                        \
4831   sw_interface_ip6_set_link_local_address_reply)                        \
4832 _(IP6ND_PROXY_ADD_DEL_REPLY, ip6nd_proxy_add_del_reply)                 \
4833 _(IP6ND_PROXY_DETAILS, ip6nd_proxy_details)                             \
4834 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
4835   sw_interface_ip6nd_ra_prefix_reply)                                   \
4836 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
4837   sw_interface_ip6nd_ra_config_reply)                                   \
4838 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
4839 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
4840 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
4841 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
4842 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
4843 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
4844 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
4845 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
4846 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
4847 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
4848 classify_set_interface_ip_table_reply)                                  \
4849 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
4850   classify_set_interface_l2_tables_reply)                               \
4851 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
4852 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
4853 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
4854 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
4855 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
4856   l2tpv3_interface_enable_disable_reply)                                \
4857 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
4858 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
4859 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
4860 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
4861 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
4862 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
4863 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
4864 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
4865 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
4866 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
4867 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
4868 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
4869 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
4870 _(SHOW_VERSION_REPLY, show_version_reply)                               \
4871 _(L2_FIB_TABLE_DETAILS, l2_fib_table_details)                           \
4872 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)           \
4873 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
4874 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
4875 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
4876 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
4877 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
4878 _(IP6_ND_EVENT, ip6_nd_event)                                           \
4879 _(WANT_L2_MACS_EVENTS_REPLY, want_l2_macs_events_reply)                 \
4880 _(L2_MACS_EVENT, l2_macs_event)                                         \
4881 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
4882 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
4883 _(IP_DETAILS, ip_details)                                               \
4884 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
4885 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
4886 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
4887 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
4888 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
4889 _(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply)         \
4890 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
4891 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
4892 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
4893 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
4894 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
4895 _(IKEV2_SET_RESPONDER_REPLY, ikev2_set_responder_reply)                 \
4896 _(IKEV2_SET_IKE_TRANSFORMS_REPLY, ikev2_set_ike_transforms_reply)       \
4897 _(IKEV2_SET_ESP_TRANSFORMS_REPLY, ikev2_set_esp_transforms_reply)       \
4898 _(IKEV2_SET_SA_LIFETIME_REPLY, ikev2_set_sa_lifetime_reply)             \
4899 _(IKEV2_INITIATE_SA_INIT_REPLY, ikev2_initiate_sa_init_reply)           \
4900 _(IKEV2_INITIATE_DEL_IKE_SA_REPLY, ikev2_initiate_del_ike_sa_reply)     \
4901 _(IKEV2_INITIATE_DEL_CHILD_SA_REPLY, ikev2_initiate_del_child_sa_reply) \
4902 _(IKEV2_INITIATE_REKEY_CHILD_SA_REPLY, ikev2_initiate_rekey_child_sa_reply) \
4903 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
4904 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
4905 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
4906 _(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply)                           \
4907 _(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply)                           \
4908 _(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply)                       \
4909 _(MAP_DOMAIN_DETAILS, map_domain_details)                               \
4910 _(MAP_RULE_DETAILS, map_rule_details)                                   \
4911 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
4912 _(WANT_STATS_REPLY, want_stats_reply)                                   \
4913 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
4914 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
4915 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
4916 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
4917 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
4918 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
4919 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
4920 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
4921 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
4922 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
4923 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
4924 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
4925 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
4926 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
4927 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
4928 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
4929   one_map_register_enable_disable_reply)                                \
4930 _(ONE_MAP_REGISTER_SET_TTL_REPLY, one_map_register_set_ttl_reply)       \
4931 _(ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                            \
4932   one_map_register_fallback_threshold_reply)                            \
4933 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
4934   one_rloc_probe_enable_disable_reply)                                  \
4935 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
4936 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
4937 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
4938 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
4939 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
4940 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
4941 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
4942 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
4943 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
4944 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
4945 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
4946 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
4947 _(ONE_STATS_DETAILS, one_stats_details)                                 \
4948 _(ONE_STATS_FLUSH_REPLY, one_stats_flush_reply)                         \
4949 _(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply)       \
4950 _(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,                                  \
4951   show_one_stats_enable_disable_reply)                                  \
4952 _(ONE_ADD_DEL_L2_ARP_ENTRY_REPLY, one_add_del_l2_arp_entry_reply)       \
4953 _(ONE_L2_ARP_BD_GET_REPLY, one_l2_arp_bd_get_reply)                     \
4954 _(ONE_L2_ARP_ENTRIES_GET_REPLY, one_l2_arp_entries_get_reply)           \
4955 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
4956 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
4957 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
4958 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
4959 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
4960 _(GPE_FWD_ENTRY_VNIS_GET_REPLY, gpe_fwd_entry_vnis_get_reply)           \
4961 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
4962 _(GPE_NATIVE_FWD_RPATHS_GET_REPLY, gpe_native_fwd_rpaths_get_reply)     \
4963 _(GPE_ADD_DEL_NATIVE_FWD_RPATH_REPLY,                                   \
4964   gpe_add_del_native_fwd_rpath_reply)                                   \
4965 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
4966   gpe_fwd_entry_path_details)                                           \
4967 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
4968 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
4969   one_add_del_map_request_itr_rlocs_reply)                              \
4970 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
4971   one_get_map_request_itr_rlocs_reply)                                  \
4972 _(SHOW_ONE_NSH_MAPPING_REPLY, show_one_nsh_mapping_reply)               \
4973 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
4974 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
4975 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
4976 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
4977 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
4978   show_one_map_register_state_reply)                                    \
4979 _(SHOW_ONE_MAP_REGISTER_TTL_REPLY, show_one_map_register_ttl_reply)     \
4980 _(SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                       \
4981   show_one_map_register_fallback_threshold_reply)                       \
4982 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
4983 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
4984 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
4985 _(POLICER_DETAILS, policer_details)                                     \
4986 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
4987 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
4988 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
4989 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
4990 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
4991 _(MPLS_FIB_DETAILS, mpls_fib_details)                                   \
4992 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
4993 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
4994 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
4995 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
4996 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
4997 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
4998 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
4999 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
5000 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
5001 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
5002 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
5003 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
5004 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
5005 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
5006 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
5007 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
5008 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
5009 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
5010 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
5011  ip_source_and_port_range_check_add_del_reply)                          \
5012 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
5013  ip_source_and_port_range_check_interface_add_del_reply)                \
5014 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
5015 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
5016 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
5017 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
5018 _(PUNT_REPLY, punt_reply)                                               \
5019 _(IP_FIB_DETAILS, ip_fib_details)                                       \
5020 _(IP6_FIB_DETAILS, ip6_fib_details)                                     \
5021 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
5022 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
5023 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
5024 _(SW_INTERFACE_SET_MTU_REPLY, sw_interface_set_mtu_reply)               \
5025 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
5026 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)           \
5027 _(P2P_ETHERNET_ADD_REPLY, p2p_ethernet_add_reply)                       \
5028 _(P2P_ETHERNET_DEL_REPLY, p2p_ethernet_del_reply)                       \
5029 _(LLDP_CONFIG_REPLY, lldp_config_reply)                                 \
5030 _(SW_INTERFACE_SET_LLDP_REPLY, sw_interface_set_lldp_reply)
5031
5032 #define foreach_standalone_reply_msg                                    \
5033 _(SW_INTERFACE_EVENT, sw_interface_event)                               \
5034 _(VNET_INTERFACE_SIMPLE_COUNTERS, vnet_interface_simple_counters)       \
5035 _(VNET_INTERFACE_COMBINED_COUNTERS, vnet_interface_combined_counters)   \
5036 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
5037 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
5038 _(VNET_IP4_NBR_COUNTERS, vnet_ip4_nbr_counters)                         \
5039 _(VNET_IP6_NBR_COUNTERS, vnet_ip6_nbr_counters)
5040
5041 typedef struct
5042 {
5043   u8 *name;
5044   u32 value;
5045 } name_sort_t;
5046
5047
5048 #define STR_VTR_OP_CASE(op)     \
5049     case L2_VTR_ ## op:         \
5050         return "" # op;
5051
5052 static const char *
5053 str_vtr_op (u32 vtr_op)
5054 {
5055   switch (vtr_op)
5056     {
5057       STR_VTR_OP_CASE (DISABLED);
5058       STR_VTR_OP_CASE (PUSH_1);
5059       STR_VTR_OP_CASE (PUSH_2);
5060       STR_VTR_OP_CASE (POP_1);
5061       STR_VTR_OP_CASE (POP_2);
5062       STR_VTR_OP_CASE (TRANSLATE_1_1);
5063       STR_VTR_OP_CASE (TRANSLATE_1_2);
5064       STR_VTR_OP_CASE (TRANSLATE_2_1);
5065       STR_VTR_OP_CASE (TRANSLATE_2_2);
5066     }
5067
5068   return "UNKNOWN";
5069 }
5070
5071 static int
5072 dump_sub_interface_table (vat_main_t * vam)
5073 {
5074   const sw_interface_subif_t *sub = NULL;
5075
5076   if (vam->json_output)
5077     {
5078       clib_warning
5079         ("JSON output supported only for VPE API calls and dump_stats_table");
5080       return -99;
5081     }
5082
5083   print (vam->ofp,
5084          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
5085          "Interface", "sw_if_index",
5086          "sub id", "dot1ad", "tags", "outer id",
5087          "inner id", "exact", "default", "outer any", "inner any");
5088
5089   vec_foreach (sub, vam->sw_if_subif_table)
5090   {
5091     print (vam->ofp,
5092            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
5093            sub->interface_name,
5094            sub->sw_if_index,
5095            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
5096            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
5097            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
5098            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
5099     if (sub->vtr_op != L2_VTR_DISABLED)
5100       {
5101         print (vam->ofp,
5102                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
5103                "tag1: %d tag2: %d ]",
5104                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
5105                sub->vtr_tag1, sub->vtr_tag2);
5106       }
5107   }
5108
5109   return 0;
5110 }
5111
5112 static int
5113 name_sort_cmp (void *a1, void *a2)
5114 {
5115   name_sort_t *n1 = a1;
5116   name_sort_t *n2 = a2;
5117
5118   return strcmp ((char *) n1->name, (char *) n2->name);
5119 }
5120
5121 static int
5122 dump_interface_table (vat_main_t * vam)
5123 {
5124   hash_pair_t *p;
5125   name_sort_t *nses = 0, *ns;
5126
5127   if (vam->json_output)
5128     {
5129       clib_warning
5130         ("JSON output supported only for VPE API calls and dump_stats_table");
5131       return -99;
5132     }
5133
5134   /* *INDENT-OFF* */
5135   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5136   ({
5137     vec_add2 (nses, ns, 1);
5138     ns->name = (u8 *)(p->key);
5139     ns->value = (u32) p->value[0];
5140   }));
5141   /* *INDENT-ON* */
5142
5143   vec_sort_with_function (nses, name_sort_cmp);
5144
5145   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
5146   vec_foreach (ns, nses)
5147   {
5148     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
5149   }
5150   vec_free (nses);
5151   return 0;
5152 }
5153
5154 static int
5155 dump_ip_table (vat_main_t * vam, int is_ipv6)
5156 {
5157   const ip_details_t *det = NULL;
5158   const ip_address_details_t *address = NULL;
5159   u32 i = ~0;
5160
5161   print (vam->ofp, "%-12s", "sw_if_index");
5162
5163   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
5164   {
5165     i++;
5166     if (!det->present)
5167       {
5168         continue;
5169       }
5170     print (vam->ofp, "%-12d", i);
5171     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
5172     if (!det->addr)
5173       {
5174         continue;
5175       }
5176     vec_foreach (address, det->addr)
5177     {
5178       print (vam->ofp,
5179              "            %-30U%-13d",
5180              is_ipv6 ? format_ip6_address : format_ip4_address,
5181              address->ip, address->prefix_length);
5182     }
5183   }
5184
5185   return 0;
5186 }
5187
5188 static int
5189 dump_ipv4_table (vat_main_t * vam)
5190 {
5191   if (vam->json_output)
5192     {
5193       clib_warning
5194         ("JSON output supported only for VPE API calls and dump_stats_table");
5195       return -99;
5196     }
5197
5198   return dump_ip_table (vam, 0);
5199 }
5200
5201 static int
5202 dump_ipv6_table (vat_main_t * vam)
5203 {
5204   if (vam->json_output)
5205     {
5206       clib_warning
5207         ("JSON output supported only for VPE API calls and dump_stats_table");
5208       return -99;
5209     }
5210
5211   return dump_ip_table (vam, 1);
5212 }
5213
5214 static char *
5215 counter_type_to_str (u8 counter_type, u8 is_combined)
5216 {
5217   if (!is_combined)
5218     {
5219       switch (counter_type)
5220         {
5221         case VNET_INTERFACE_COUNTER_DROP:
5222           return "drop";
5223         case VNET_INTERFACE_COUNTER_PUNT:
5224           return "punt";
5225         case VNET_INTERFACE_COUNTER_IP4:
5226           return "ip4";
5227         case VNET_INTERFACE_COUNTER_IP6:
5228           return "ip6";
5229         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
5230           return "rx-no-buf";
5231         case VNET_INTERFACE_COUNTER_RX_MISS:
5232           return "rx-miss";
5233         case VNET_INTERFACE_COUNTER_RX_ERROR:
5234           return "rx-error";
5235         case VNET_INTERFACE_COUNTER_TX_ERROR:
5236           return "tx-error";
5237         default:
5238           return "INVALID-COUNTER-TYPE";
5239         }
5240     }
5241   else
5242     {
5243       switch (counter_type)
5244         {
5245         case VNET_INTERFACE_COUNTER_RX:
5246           return "rx";
5247         case VNET_INTERFACE_COUNTER_TX:
5248           return "tx";
5249         default:
5250           return "INVALID-COUNTER-TYPE";
5251         }
5252     }
5253 }
5254
5255 static int
5256 dump_stats_table (vat_main_t * vam)
5257 {
5258   vat_json_node_t node;
5259   vat_json_node_t *msg_array;
5260   vat_json_node_t *msg;
5261   vat_json_node_t *counter_array;
5262   vat_json_node_t *counter;
5263   interface_counter_t c;
5264   u64 packets;
5265   ip4_fib_counter_t *c4;
5266   ip6_fib_counter_t *c6;
5267   ip4_nbr_counter_t *n4;
5268   ip6_nbr_counter_t *n6;
5269   int i, j;
5270
5271   if (!vam->json_output)
5272     {
5273       clib_warning ("dump_stats_table supported only in JSON format");
5274       return -99;
5275     }
5276
5277   vat_json_init_object (&node);
5278
5279   /* interface counters */
5280   msg_array = vat_json_object_add (&node, "interface_counters");
5281   vat_json_init_array (msg_array);
5282   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
5283     {
5284       msg = vat_json_array_add (msg_array);
5285       vat_json_init_object (msg);
5286       vat_json_object_add_string_copy (msg, "vnet_counter_type",
5287                                        (u8 *) counter_type_to_str (i, 0));
5288       vat_json_object_add_int (msg, "is_combined", 0);
5289       counter_array = vat_json_object_add (msg, "data");
5290       vat_json_init_array (counter_array);
5291       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
5292         {
5293           packets = vam->simple_interface_counters[i][j];
5294           vat_json_array_add_uint (counter_array, packets);
5295         }
5296     }
5297   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
5298     {
5299       msg = vat_json_array_add (msg_array);
5300       vat_json_init_object (msg);
5301       vat_json_object_add_string_copy (msg, "vnet_counter_type",
5302                                        (u8 *) counter_type_to_str (i, 1));
5303       vat_json_object_add_int (msg, "is_combined", 1);
5304       counter_array = vat_json_object_add (msg, "data");
5305       vat_json_init_array (counter_array);
5306       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
5307         {
5308           c = vam->combined_interface_counters[i][j];
5309           counter = vat_json_array_add (counter_array);
5310           vat_json_init_object (counter);
5311           vat_json_object_add_uint (counter, "packets", c.packets);
5312           vat_json_object_add_uint (counter, "bytes", c.bytes);
5313         }
5314     }
5315
5316   /* ip4 fib counters */
5317   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
5318   vat_json_init_array (msg_array);
5319   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
5320     {
5321       msg = vat_json_array_add (msg_array);
5322       vat_json_init_object (msg);
5323       vat_json_object_add_uint (msg, "vrf_id",
5324                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
5325       counter_array = vat_json_object_add (msg, "c");
5326       vat_json_init_array (counter_array);
5327       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
5328         {
5329           counter = vat_json_array_add (counter_array);
5330           vat_json_init_object (counter);
5331           c4 = &vam->ip4_fib_counters[i][j];
5332           vat_json_object_add_ip4 (counter, "address", c4->address);
5333           vat_json_object_add_uint (counter, "address_length",
5334                                     c4->address_length);
5335           vat_json_object_add_uint (counter, "packets", c4->packets);
5336           vat_json_object_add_uint (counter, "bytes", c4->bytes);
5337         }
5338     }
5339
5340   /* ip6 fib counters */
5341   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
5342   vat_json_init_array (msg_array);
5343   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
5344     {
5345       msg = vat_json_array_add (msg_array);
5346       vat_json_init_object (msg);
5347       vat_json_object_add_uint (msg, "vrf_id",
5348                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
5349       counter_array = vat_json_object_add (msg, "c");
5350       vat_json_init_array (counter_array);
5351       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
5352         {
5353           counter = vat_json_array_add (counter_array);
5354           vat_json_init_object (counter);
5355           c6 = &vam->ip6_fib_counters[i][j];
5356           vat_json_object_add_ip6 (counter, "address", c6->address);
5357           vat_json_object_add_uint (counter, "address_length",
5358                                     c6->address_length);
5359           vat_json_object_add_uint (counter, "packets", c6->packets);
5360           vat_json_object_add_uint (counter, "bytes", c6->bytes);
5361         }
5362     }
5363
5364   /* ip4 nbr counters */
5365   msg_array = vat_json_object_add (&node, "ip4_nbr_counters");
5366   vat_json_init_array (msg_array);
5367   for (i = 0; i < vec_len (vam->ip4_nbr_counters); i++)
5368     {
5369       msg = vat_json_array_add (msg_array);
5370       vat_json_init_object (msg);
5371       vat_json_object_add_uint (msg, "sw_if_index", i);
5372       counter_array = vat_json_object_add (msg, "c");
5373       vat_json_init_array (counter_array);
5374       for (j = 0; j < vec_len (vam->ip4_nbr_counters[i]); j++)
5375         {
5376           counter = vat_json_array_add (counter_array);
5377           vat_json_init_object (counter);
5378           n4 = &vam->ip4_nbr_counters[i][j];
5379           vat_json_object_add_ip4 (counter, "address", n4->address);
5380           vat_json_object_add_uint (counter, "link-type", n4->linkt);
5381           vat_json_object_add_uint (counter, "packets", n4->packets);
5382           vat_json_object_add_uint (counter, "bytes", n4->bytes);
5383         }
5384     }
5385
5386   /* ip6 nbr counters */
5387   msg_array = vat_json_object_add (&node, "ip6_nbr_counters");
5388   vat_json_init_array (msg_array);
5389   for (i = 0; i < vec_len (vam->ip6_nbr_counters); i++)
5390     {
5391       msg = vat_json_array_add (msg_array);
5392       vat_json_init_object (msg);
5393       vat_json_object_add_uint (msg, "sw_if_index", i);
5394       counter_array = vat_json_object_add (msg, "c");
5395       vat_json_init_array (counter_array);
5396       for (j = 0; j < vec_len (vam->ip6_nbr_counters[i]); j++)
5397         {
5398           counter = vat_json_array_add (counter_array);
5399           vat_json_init_object (counter);
5400           n6 = &vam->ip6_nbr_counters[i][j];
5401           vat_json_object_add_ip6 (counter, "address", n6->address);
5402           vat_json_object_add_uint (counter, "packets", n6->packets);
5403           vat_json_object_add_uint (counter, "bytes", n6->bytes);
5404         }
5405     }
5406
5407   vat_json_print (vam->ofp, &node);
5408   vat_json_free (&node);
5409
5410   return 0;
5411 }
5412
5413 int
5414 exec (vat_main_t * vam)
5415 {
5416   api_main_t *am = &api_main;
5417   vl_api_cli_t *mp;
5418   f64 timeout;
5419   void *oldheap;
5420   u8 *cmd = 0;
5421   unformat_input_t *i = vam->input;
5422
5423   if (vec_len (i->buffer) == 0)
5424     return -1;
5425
5426   if (vam->exec_mode == 0 && unformat (i, "mode"))
5427     {
5428       vam->exec_mode = 1;
5429       return 0;
5430     }
5431   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
5432     {
5433       vam->exec_mode = 0;
5434       return 0;
5435     }
5436
5437
5438   M (CLI, mp);
5439
5440   /*
5441    * Copy cmd into shared memory.
5442    * In order for the CLI command to work, it
5443    * must be a vector ending in \n, not a C-string ending
5444    * in \n\0.
5445    */
5446   pthread_mutex_lock (&am->vlib_rp->mutex);
5447   oldheap = svm_push_data_heap (am->vlib_rp);
5448
5449   vec_validate (cmd, vec_len (vam->input->buffer) - 1);
5450   clib_memcpy (cmd, vam->input->buffer, vec_len (vam->input->buffer));
5451
5452   svm_pop_heap (oldheap);
5453   pthread_mutex_unlock (&am->vlib_rp->mutex);
5454
5455   mp->cmd_in_shmem = pointer_to_uword (cmd);
5456   S (mp);
5457   timeout = vat_time_now (vam) + 10.0;
5458
5459   while (vat_time_now (vam) < timeout)
5460     {
5461       if (vam->result_ready == 1)
5462         {
5463           u8 *free_me;
5464           if (vam->shmem_result != NULL)
5465             print (vam->ofp, "%s", vam->shmem_result);
5466           pthread_mutex_lock (&am->vlib_rp->mutex);
5467           oldheap = svm_push_data_heap (am->vlib_rp);
5468
5469           free_me = (u8 *) vam->shmem_result;
5470           vec_free (free_me);
5471
5472           svm_pop_heap (oldheap);
5473           pthread_mutex_unlock (&am->vlib_rp->mutex);
5474           return 0;
5475         }
5476     }
5477   return -99;
5478 }
5479
5480 /*
5481  * Future replacement of exec() that passes CLI buffers directly in
5482  * the API messages instead of an additional shared memory area.
5483  */
5484 static int
5485 exec_inband (vat_main_t * vam)
5486 {
5487   vl_api_cli_inband_t *mp;
5488   unformat_input_t *i = vam->input;
5489   int ret;
5490
5491   if (vec_len (i->buffer) == 0)
5492     return -1;
5493
5494   if (vam->exec_mode == 0 && unformat (i, "mode"))
5495     {
5496       vam->exec_mode = 1;
5497       return 0;
5498     }
5499   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
5500     {
5501       vam->exec_mode = 0;
5502       return 0;
5503     }
5504
5505   /*
5506    * In order for the CLI command to work, it
5507    * must be a vector ending in \n, not a C-string ending
5508    * in \n\0.
5509    */
5510   u32 len = vec_len (vam->input->buffer);
5511   M2 (CLI_INBAND, mp, len);
5512   clib_memcpy (mp->cmd, vam->input->buffer, len);
5513   mp->length = htonl (len);
5514
5515   S (mp);
5516   W2 (ret, print (vam->ofp, "%s", vam->cmd_reply));
5517   return ret;
5518 }
5519
5520 static int
5521 api_create_loopback (vat_main_t * vam)
5522 {
5523   unformat_input_t *i = vam->input;
5524   vl_api_create_loopback_t *mp;
5525   vl_api_create_loopback_instance_t *mp_lbi;
5526   u8 mac_address[6];
5527   u8 mac_set = 0;
5528   u8 is_specified = 0;
5529   u32 user_instance = 0;
5530   int ret;
5531
5532   memset (mac_address, 0, sizeof (mac_address));
5533
5534   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5535     {
5536       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5537         mac_set = 1;
5538       if (unformat (i, "instance %d", &user_instance))
5539         is_specified = 1;
5540       else
5541         break;
5542     }
5543
5544   if (is_specified)
5545     {
5546       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
5547       mp_lbi->is_specified = is_specified;
5548       if (is_specified)
5549         mp_lbi->user_instance = htonl (user_instance);
5550       if (mac_set)
5551         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
5552       S (mp_lbi);
5553     }
5554   else
5555     {
5556       /* Construct the API message */
5557       M (CREATE_LOOPBACK, mp);
5558       if (mac_set)
5559         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
5560       S (mp);
5561     }
5562
5563   W (ret);
5564   return ret;
5565 }
5566
5567 static int
5568 api_delete_loopback (vat_main_t * vam)
5569 {
5570   unformat_input_t *i = vam->input;
5571   vl_api_delete_loopback_t *mp;
5572   u32 sw_if_index = ~0;
5573   int ret;
5574
5575   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5576     {
5577       if (unformat (i, "sw_if_index %d", &sw_if_index))
5578         ;
5579       else
5580         break;
5581     }
5582
5583   if (sw_if_index == ~0)
5584     {
5585       errmsg ("missing sw_if_index");
5586       return -99;
5587     }
5588
5589   /* Construct the API message */
5590   M (DELETE_LOOPBACK, mp);
5591   mp->sw_if_index = ntohl (sw_if_index);
5592
5593   S (mp);
5594   W (ret);
5595   return ret;
5596 }
5597
5598 static int
5599 api_want_stats (vat_main_t * vam)
5600 {
5601   unformat_input_t *i = vam->input;
5602   vl_api_want_stats_t *mp;
5603   int enable = -1;
5604   int ret;
5605
5606   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5607     {
5608       if (unformat (i, "enable"))
5609         enable = 1;
5610       else if (unformat (i, "disable"))
5611         enable = 0;
5612       else
5613         break;
5614     }
5615
5616   if (enable == -1)
5617     {
5618       errmsg ("missing enable|disable");
5619       return -99;
5620     }
5621
5622   M (WANT_STATS, mp);
5623   mp->enable_disable = enable;
5624
5625   S (mp);
5626   W (ret);
5627   return ret;
5628 }
5629
5630 static int
5631 api_want_interface_events (vat_main_t * vam)
5632 {
5633   unformat_input_t *i = vam->input;
5634   vl_api_want_interface_events_t *mp;
5635   int enable = -1;
5636   int ret;
5637
5638   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5639     {
5640       if (unformat (i, "enable"))
5641         enable = 1;
5642       else if (unformat (i, "disable"))
5643         enable = 0;
5644       else
5645         break;
5646     }
5647
5648   if (enable == -1)
5649     {
5650       errmsg ("missing enable|disable");
5651       return -99;
5652     }
5653
5654   M (WANT_INTERFACE_EVENTS, mp);
5655   mp->enable_disable = enable;
5656
5657   vam->interface_event_display = enable;
5658
5659   S (mp);
5660   W (ret);
5661   return ret;
5662 }
5663
5664
5665 /* Note: non-static, called once to set up the initial intfc table */
5666 int
5667 api_sw_interface_dump (vat_main_t * vam)
5668 {
5669   vl_api_sw_interface_dump_t *mp;
5670   vl_api_control_ping_t *mp_ping;
5671   hash_pair_t *p;
5672   name_sort_t *nses = 0, *ns;
5673   sw_interface_subif_t *sub = NULL;
5674   int ret;
5675
5676   /* Toss the old name table */
5677   /* *INDENT-OFF* */
5678   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5679   ({
5680     vec_add2 (nses, ns, 1);
5681     ns->name = (u8 *)(p->key);
5682     ns->value = (u32) p->value[0];
5683   }));
5684   /* *INDENT-ON* */
5685
5686   hash_free (vam->sw_if_index_by_interface_name);
5687
5688   vec_foreach (ns, nses) vec_free (ns->name);
5689
5690   vec_free (nses);
5691
5692   vec_foreach (sub, vam->sw_if_subif_table)
5693   {
5694     vec_free (sub->interface_name);
5695   }
5696   vec_free (vam->sw_if_subif_table);
5697
5698   /* recreate the interface name hash table */
5699   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
5700
5701   /* Get list of ethernets */
5702   M (SW_INTERFACE_DUMP, mp);
5703   mp->name_filter_valid = 1;
5704   strncpy ((char *) mp->name_filter, "Ether", sizeof (mp->name_filter) - 1);
5705   S (mp);
5706
5707   /* and local / loopback interfaces */
5708   M (SW_INTERFACE_DUMP, mp);
5709   mp->name_filter_valid = 1;
5710   strncpy ((char *) mp->name_filter, "lo", sizeof (mp->name_filter) - 1);
5711   S (mp);
5712
5713   /* and packet-generator interfaces */
5714   M (SW_INTERFACE_DUMP, mp);
5715   mp->name_filter_valid = 1;
5716   strncpy ((char *) mp->name_filter, "pg", sizeof (mp->name_filter) - 1);
5717   S (mp);
5718
5719   /* and vxlan-gpe tunnel interfaces */
5720   M (SW_INTERFACE_DUMP, mp);
5721   mp->name_filter_valid = 1;
5722   strncpy ((char *) mp->name_filter, "vxlan_gpe",
5723            sizeof (mp->name_filter) - 1);
5724   S (mp);
5725
5726   /* and vxlan tunnel interfaces */
5727   M (SW_INTERFACE_DUMP, mp);
5728   mp->name_filter_valid = 1;
5729   strncpy ((char *) mp->name_filter, "vxlan", sizeof (mp->name_filter) - 1);
5730   S (mp);
5731
5732   /* and host (af_packet) interfaces */
5733   M (SW_INTERFACE_DUMP, mp);
5734   mp->name_filter_valid = 1;
5735   strncpy ((char *) mp->name_filter, "host", sizeof (mp->name_filter) - 1);
5736   S (mp);
5737
5738   /* and l2tpv3 tunnel interfaces */
5739   M (SW_INTERFACE_DUMP, mp);
5740   mp->name_filter_valid = 1;
5741   strncpy ((char *) mp->name_filter, "l2tpv3_tunnel",
5742            sizeof (mp->name_filter) - 1);
5743   S (mp);
5744
5745   /* and GRE tunnel interfaces */
5746   M (SW_INTERFACE_DUMP, mp);
5747   mp->name_filter_valid = 1;
5748   strncpy ((char *) mp->name_filter, "gre", sizeof (mp->name_filter) - 1);
5749   S (mp);
5750
5751   /* and LISP-GPE interfaces */
5752   M (SW_INTERFACE_DUMP, mp);
5753   mp->name_filter_valid = 1;
5754   strncpy ((char *) mp->name_filter, "lisp_gpe",
5755            sizeof (mp->name_filter) - 1);
5756   S (mp);
5757
5758   /* and IPSEC tunnel interfaces */
5759   M (SW_INTERFACE_DUMP, mp);
5760   mp->name_filter_valid = 1;
5761   strncpy ((char *) mp->name_filter, "ipsec", sizeof (mp->name_filter) - 1);
5762   S (mp);
5763
5764   /* Use a control ping for synchronization */
5765   M (CONTROL_PING, mp_ping);
5766   S (mp_ping);
5767
5768   W (ret);
5769   return ret;
5770 }
5771
5772 static int
5773 api_sw_interface_set_flags (vat_main_t * vam)
5774 {
5775   unformat_input_t *i = vam->input;
5776   vl_api_sw_interface_set_flags_t *mp;
5777   u32 sw_if_index;
5778   u8 sw_if_index_set = 0;
5779   u8 admin_up = 0;
5780   int ret;
5781
5782   /* Parse args required to build the message */
5783   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5784     {
5785       if (unformat (i, "admin-up"))
5786         admin_up = 1;
5787       else if (unformat (i, "admin-down"))
5788         admin_up = 0;
5789       else
5790         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5791         sw_if_index_set = 1;
5792       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5793         sw_if_index_set = 1;
5794       else
5795         break;
5796     }
5797
5798   if (sw_if_index_set == 0)
5799     {
5800       errmsg ("missing interface name or sw_if_index");
5801       return -99;
5802     }
5803
5804   /* Construct the API message */
5805   M (SW_INTERFACE_SET_FLAGS, mp);
5806   mp->sw_if_index = ntohl (sw_if_index);
5807   mp->admin_up_down = admin_up;
5808
5809   /* send it... */
5810   S (mp);
5811
5812   /* Wait for a reply, return the good/bad news... */
5813   W (ret);
5814   return ret;
5815 }
5816
5817 static int
5818 api_sw_interface_clear_stats (vat_main_t * vam)
5819 {
5820   unformat_input_t *i = vam->input;
5821   vl_api_sw_interface_clear_stats_t *mp;
5822   u32 sw_if_index;
5823   u8 sw_if_index_set = 0;
5824   int ret;
5825
5826   /* Parse args required to build the message */
5827   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5828     {
5829       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5830         sw_if_index_set = 1;
5831       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5832         sw_if_index_set = 1;
5833       else
5834         break;
5835     }
5836
5837   /* Construct the API message */
5838   M (SW_INTERFACE_CLEAR_STATS, mp);
5839
5840   if (sw_if_index_set == 1)
5841     mp->sw_if_index = ntohl (sw_if_index);
5842   else
5843     mp->sw_if_index = ~0;
5844
5845   /* send it... */
5846   S (mp);
5847
5848   /* Wait for a reply, return the good/bad news... */
5849   W (ret);
5850   return ret;
5851 }
5852
5853 static int
5854 api_sw_interface_add_del_address (vat_main_t * vam)
5855 {
5856   unformat_input_t *i = vam->input;
5857   vl_api_sw_interface_add_del_address_t *mp;
5858   u32 sw_if_index;
5859   u8 sw_if_index_set = 0;
5860   u8 is_add = 1, del_all = 0;
5861   u32 address_length = 0;
5862   u8 v4_address_set = 0;
5863   u8 v6_address_set = 0;
5864   ip4_address_t v4address;
5865   ip6_address_t v6address;
5866   int ret;
5867
5868   /* Parse args required to build the message */
5869   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5870     {
5871       if (unformat (i, "del-all"))
5872         del_all = 1;
5873       else if (unformat (i, "del"))
5874         is_add = 0;
5875       else
5876         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5877         sw_if_index_set = 1;
5878       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5879         sw_if_index_set = 1;
5880       else if (unformat (i, "%U/%d",
5881                          unformat_ip4_address, &v4address, &address_length))
5882         v4_address_set = 1;
5883       else if (unformat (i, "%U/%d",
5884                          unformat_ip6_address, &v6address, &address_length))
5885         v6_address_set = 1;
5886       else
5887         break;
5888     }
5889
5890   if (sw_if_index_set == 0)
5891     {
5892       errmsg ("missing interface name or sw_if_index");
5893       return -99;
5894     }
5895   if (v4_address_set && v6_address_set)
5896     {
5897       errmsg ("both v4 and v6 addresses set");
5898       return -99;
5899     }
5900   if (!v4_address_set && !v6_address_set && !del_all)
5901     {
5902       errmsg ("no addresses set");
5903       return -99;
5904     }
5905
5906   /* Construct the API message */
5907   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
5908
5909   mp->sw_if_index = ntohl (sw_if_index);
5910   mp->is_add = is_add;
5911   mp->del_all = del_all;
5912   if (v6_address_set)
5913     {
5914       mp->is_ipv6 = 1;
5915       clib_memcpy (mp->address, &v6address, sizeof (v6address));
5916     }
5917   else
5918     {
5919       clib_memcpy (mp->address, &v4address, sizeof (v4address));
5920     }
5921   mp->address_length = address_length;
5922
5923   /* send it... */
5924   S (mp);
5925
5926   /* Wait for a reply, return good/bad news  */
5927   W (ret);
5928   return ret;
5929 }
5930
5931 static int
5932 api_sw_interface_set_mpls_enable (vat_main_t * vam)
5933 {
5934   unformat_input_t *i = vam->input;
5935   vl_api_sw_interface_set_mpls_enable_t *mp;
5936   u32 sw_if_index;
5937   u8 sw_if_index_set = 0;
5938   u8 enable = 1;
5939   int ret;
5940
5941   /* Parse args required to build the message */
5942   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5943     {
5944       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5945         sw_if_index_set = 1;
5946       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5947         sw_if_index_set = 1;
5948       else if (unformat (i, "disable"))
5949         enable = 0;
5950       else if (unformat (i, "dis"))
5951         enable = 0;
5952       else
5953         break;
5954     }
5955
5956   if (sw_if_index_set == 0)
5957     {
5958       errmsg ("missing interface name or sw_if_index");
5959       return -99;
5960     }
5961
5962   /* Construct the API message */
5963   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
5964
5965   mp->sw_if_index = ntohl (sw_if_index);
5966   mp->enable = enable;
5967
5968   /* send it... */
5969   S (mp);
5970
5971   /* Wait for a reply... */
5972   W (ret);
5973   return ret;
5974 }
5975
5976 static int
5977 api_sw_interface_set_table (vat_main_t * vam)
5978 {
5979   unformat_input_t *i = vam->input;
5980   vl_api_sw_interface_set_table_t *mp;
5981   u32 sw_if_index, vrf_id = 0;
5982   u8 sw_if_index_set = 0;
5983   u8 is_ipv6 = 0;
5984   int ret;
5985
5986   /* Parse args required to build the message */
5987   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5988     {
5989       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5990         sw_if_index_set = 1;
5991       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5992         sw_if_index_set = 1;
5993       else if (unformat (i, "vrf %d", &vrf_id))
5994         ;
5995       else if (unformat (i, "ipv6"))
5996         is_ipv6 = 1;
5997       else
5998         break;
5999     }
6000
6001   if (sw_if_index_set == 0)
6002     {
6003       errmsg ("missing interface name or sw_if_index");
6004       return -99;
6005     }
6006
6007   /* Construct the API message */
6008   M (SW_INTERFACE_SET_TABLE, mp);
6009
6010   mp->sw_if_index = ntohl (sw_if_index);
6011   mp->is_ipv6 = is_ipv6;
6012   mp->vrf_id = ntohl (vrf_id);
6013
6014   /* send it... */
6015   S (mp);
6016
6017   /* Wait for a reply... */
6018   W (ret);
6019   return ret;
6020 }
6021
6022 static void vl_api_sw_interface_get_table_reply_t_handler
6023   (vl_api_sw_interface_get_table_reply_t * mp)
6024 {
6025   vat_main_t *vam = &vat_main;
6026
6027   print (vam->ofp, "%d", ntohl (mp->vrf_id));
6028
6029   vam->retval = ntohl (mp->retval);
6030   vam->result_ready = 1;
6031
6032 }
6033
6034 static void vl_api_sw_interface_get_table_reply_t_handler_json
6035   (vl_api_sw_interface_get_table_reply_t * mp)
6036 {
6037   vat_main_t *vam = &vat_main;
6038   vat_json_node_t node;
6039
6040   vat_json_init_object (&node);
6041   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
6042   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
6043
6044   vat_json_print (vam->ofp, &node);
6045   vat_json_free (&node);
6046
6047   vam->retval = ntohl (mp->retval);
6048   vam->result_ready = 1;
6049 }
6050
6051 static int
6052 api_sw_interface_get_table (vat_main_t * vam)
6053 {
6054   unformat_input_t *i = vam->input;
6055   vl_api_sw_interface_get_table_t *mp;
6056   u32 sw_if_index;
6057   u8 sw_if_index_set = 0;
6058   u8 is_ipv6 = 0;
6059   int ret;
6060
6061   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6062     {
6063       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6064         sw_if_index_set = 1;
6065       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6066         sw_if_index_set = 1;
6067       else if (unformat (i, "ipv6"))
6068         is_ipv6 = 1;
6069       else
6070         break;
6071     }
6072
6073   if (sw_if_index_set == 0)
6074     {
6075       errmsg ("missing interface name or sw_if_index");
6076       return -99;
6077     }
6078
6079   M (SW_INTERFACE_GET_TABLE, mp);
6080   mp->sw_if_index = htonl (sw_if_index);
6081   mp->is_ipv6 = is_ipv6;
6082
6083   S (mp);
6084   W (ret);
6085   return ret;
6086 }
6087
6088 static int
6089 api_sw_interface_set_vpath (vat_main_t * vam)
6090 {
6091   unformat_input_t *i = vam->input;
6092   vl_api_sw_interface_set_vpath_t *mp;
6093   u32 sw_if_index = 0;
6094   u8 sw_if_index_set = 0;
6095   u8 is_enable = 0;
6096   int ret;
6097
6098   /* Parse args required to build the message */
6099   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6100     {
6101       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6102         sw_if_index_set = 1;
6103       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6104         sw_if_index_set = 1;
6105       else if (unformat (i, "enable"))
6106         is_enable = 1;
6107       else if (unformat (i, "disable"))
6108         is_enable = 0;
6109       else
6110         break;
6111     }
6112
6113   if (sw_if_index_set == 0)
6114     {
6115       errmsg ("missing interface name or sw_if_index");
6116       return -99;
6117     }
6118
6119   /* Construct the API message */
6120   M (SW_INTERFACE_SET_VPATH, mp);
6121
6122   mp->sw_if_index = ntohl (sw_if_index);
6123   mp->enable = is_enable;
6124
6125   /* send it... */
6126   S (mp);
6127
6128   /* Wait for a reply... */
6129   W (ret);
6130   return ret;
6131 }
6132
6133 static int
6134 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
6135 {
6136   unformat_input_t *i = vam->input;
6137   vl_api_sw_interface_set_vxlan_bypass_t *mp;
6138   u32 sw_if_index = 0;
6139   u8 sw_if_index_set = 0;
6140   u8 is_enable = 1;
6141   u8 is_ipv6 = 0;
6142   int ret;
6143
6144   /* Parse args required to build the message */
6145   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6146     {
6147       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6148         sw_if_index_set = 1;
6149       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6150         sw_if_index_set = 1;
6151       else if (unformat (i, "enable"))
6152         is_enable = 1;
6153       else if (unformat (i, "disable"))
6154         is_enable = 0;
6155       else if (unformat (i, "ip4"))
6156         is_ipv6 = 0;
6157       else if (unformat (i, "ip6"))
6158         is_ipv6 = 1;
6159       else
6160         break;
6161     }
6162
6163   if (sw_if_index_set == 0)
6164     {
6165       errmsg ("missing interface name or sw_if_index");
6166       return -99;
6167     }
6168
6169   /* Construct the API message */
6170   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
6171
6172   mp->sw_if_index = ntohl (sw_if_index);
6173   mp->enable = is_enable;
6174   mp->is_ipv6 = is_ipv6;
6175
6176   /* send it... */
6177   S (mp);
6178
6179   /* Wait for a reply... */
6180   W (ret);
6181   return ret;
6182 }
6183
6184
6185 static int
6186 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
6187 {
6188   unformat_input_t *i = vam->input;
6189   vl_api_sw_interface_set_l2_xconnect_t *mp;
6190   u32 rx_sw_if_index;
6191   u8 rx_sw_if_index_set = 0;
6192   u32 tx_sw_if_index;
6193   u8 tx_sw_if_index_set = 0;
6194   u8 enable = 1;
6195   int ret;
6196
6197   /* Parse args required to build the message */
6198   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6199     {
6200       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
6201         rx_sw_if_index_set = 1;
6202       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
6203         tx_sw_if_index_set = 1;
6204       else if (unformat (i, "rx"))
6205         {
6206           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6207             {
6208               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6209                             &rx_sw_if_index))
6210                 rx_sw_if_index_set = 1;
6211             }
6212           else
6213             break;
6214         }
6215       else if (unformat (i, "tx"))
6216         {
6217           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6218             {
6219               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6220                             &tx_sw_if_index))
6221                 tx_sw_if_index_set = 1;
6222             }
6223           else
6224             break;
6225         }
6226       else if (unformat (i, "enable"))
6227         enable = 1;
6228       else if (unformat (i, "disable"))
6229         enable = 0;
6230       else
6231         break;
6232     }
6233
6234   if (rx_sw_if_index_set == 0)
6235     {
6236       errmsg ("missing rx interface name or rx_sw_if_index");
6237       return -99;
6238     }
6239
6240   if (enable && (tx_sw_if_index_set == 0))
6241     {
6242       errmsg ("missing tx interface name or tx_sw_if_index");
6243       return -99;
6244     }
6245
6246   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
6247
6248   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6249   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
6250   mp->enable = enable;
6251
6252   S (mp);
6253   W (ret);
6254   return ret;
6255 }
6256
6257 static int
6258 api_sw_interface_set_l2_bridge (vat_main_t * vam)
6259 {
6260   unformat_input_t *i = vam->input;
6261   vl_api_sw_interface_set_l2_bridge_t *mp;
6262   u32 rx_sw_if_index;
6263   u8 rx_sw_if_index_set = 0;
6264   u32 bd_id;
6265   u8 bd_id_set = 0;
6266   u8 bvi = 0;
6267   u32 shg = 0;
6268   u8 enable = 1;
6269   int ret;
6270
6271   /* Parse args required to build the message */
6272   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6273     {
6274       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
6275         rx_sw_if_index_set = 1;
6276       else if (unformat (i, "bd_id %d", &bd_id))
6277         bd_id_set = 1;
6278       else
6279         if (unformat
6280             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
6281         rx_sw_if_index_set = 1;
6282       else if (unformat (i, "shg %d", &shg))
6283         ;
6284       else if (unformat (i, "bvi"))
6285         bvi = 1;
6286       else if (unformat (i, "enable"))
6287         enable = 1;
6288       else if (unformat (i, "disable"))
6289         enable = 0;
6290       else
6291         break;
6292     }
6293
6294   if (rx_sw_if_index_set == 0)
6295     {
6296       errmsg ("missing rx interface name or sw_if_index");
6297       return -99;
6298     }
6299
6300   if (enable && (bd_id_set == 0))
6301     {
6302       errmsg ("missing bridge domain");
6303       return -99;
6304     }
6305
6306   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
6307
6308   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6309   mp->bd_id = ntohl (bd_id);
6310   mp->shg = (u8) shg;
6311   mp->bvi = bvi;
6312   mp->enable = enable;
6313
6314   S (mp);
6315   W (ret);
6316   return ret;
6317 }
6318
6319 static int
6320 api_bridge_domain_dump (vat_main_t * vam)
6321 {
6322   unformat_input_t *i = vam->input;
6323   vl_api_bridge_domain_dump_t *mp;
6324   vl_api_control_ping_t *mp_ping;
6325   u32 bd_id = ~0;
6326   int ret;
6327
6328   /* Parse args required to build the message */
6329   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6330     {
6331       if (unformat (i, "bd_id %d", &bd_id))
6332         ;
6333       else
6334         break;
6335     }
6336
6337   M (BRIDGE_DOMAIN_DUMP, mp);
6338   mp->bd_id = ntohl (bd_id);
6339   S (mp);
6340
6341   /* Use a control ping for synchronization */
6342   M (CONTROL_PING, mp_ping);
6343   S (mp_ping);
6344
6345   W (ret);
6346   return ret;
6347 }
6348
6349 static int
6350 api_bridge_domain_add_del (vat_main_t * vam)
6351 {
6352   unformat_input_t *i = vam->input;
6353   vl_api_bridge_domain_add_del_t *mp;
6354   u32 bd_id = ~0;
6355   u8 is_add = 1;
6356   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
6357   u32 mac_age = 0;
6358   int ret;
6359
6360   /* Parse args required to build the message */
6361   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6362     {
6363       if (unformat (i, "bd_id %d", &bd_id))
6364         ;
6365       else if (unformat (i, "flood %d", &flood))
6366         ;
6367       else if (unformat (i, "uu-flood %d", &uu_flood))
6368         ;
6369       else if (unformat (i, "forward %d", &forward))
6370         ;
6371       else if (unformat (i, "learn %d", &learn))
6372         ;
6373       else if (unformat (i, "arp-term %d", &arp_term))
6374         ;
6375       else if (unformat (i, "mac-age %d", &mac_age))
6376         ;
6377       else if (unformat (i, "del"))
6378         {
6379           is_add = 0;
6380           flood = uu_flood = forward = learn = 0;
6381         }
6382       else
6383         break;
6384     }
6385
6386   if (bd_id == ~0)
6387     {
6388       errmsg ("missing bridge domain");
6389       return -99;
6390     }
6391
6392   if (mac_age > 255)
6393     {
6394       errmsg ("mac age must be less than 256 ");
6395       return -99;
6396     }
6397
6398   M (BRIDGE_DOMAIN_ADD_DEL, mp);
6399
6400   mp->bd_id = ntohl (bd_id);
6401   mp->flood = flood;
6402   mp->uu_flood = uu_flood;
6403   mp->forward = forward;
6404   mp->learn = learn;
6405   mp->arp_term = arp_term;
6406   mp->is_add = is_add;
6407   mp->mac_age = (u8) mac_age;
6408
6409   S (mp);
6410   W (ret);
6411   return ret;
6412 }
6413
6414 static int
6415 api_l2fib_flush_bd (vat_main_t * vam)
6416 {
6417   unformat_input_t *i = vam->input;
6418   vl_api_l2fib_flush_bd_t *mp;
6419   u32 bd_id = ~0;
6420   int ret;
6421
6422   /* Parse args required to build the message */
6423   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6424     {
6425       if (unformat (i, "bd_id %d", &bd_id));
6426       else
6427         break;
6428     }
6429
6430   if (bd_id == ~0)
6431     {
6432       errmsg ("missing bridge domain");
6433       return -99;
6434     }
6435
6436   M (L2FIB_FLUSH_BD, mp);
6437
6438   mp->bd_id = htonl (bd_id);
6439
6440   S (mp);
6441   W (ret);
6442   return ret;
6443 }
6444
6445 static int
6446 api_l2fib_flush_int (vat_main_t * vam)
6447 {
6448   unformat_input_t *i = vam->input;
6449   vl_api_l2fib_flush_int_t *mp;
6450   u32 sw_if_index = ~0;
6451   int ret;
6452
6453   /* Parse args required to build the message */
6454   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6455     {
6456       if (unformat (i, "sw_if_index %d", &sw_if_index));
6457       else
6458         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
6459       else
6460         break;
6461     }
6462
6463   if (sw_if_index == ~0)
6464     {
6465       errmsg ("missing interface name or sw_if_index");
6466       return -99;
6467     }
6468
6469   M (L2FIB_FLUSH_INT, mp);
6470
6471   mp->sw_if_index = ntohl (sw_if_index);
6472
6473   S (mp);
6474   W (ret);
6475   return ret;
6476 }
6477
6478 static int
6479 api_l2fib_add_del (vat_main_t * vam)
6480 {
6481   unformat_input_t *i = vam->input;
6482   vl_api_l2fib_add_del_t *mp;
6483   f64 timeout;
6484   u64 mac = 0;
6485   u8 mac_set = 0;
6486   u32 bd_id;
6487   u8 bd_id_set = 0;
6488   u32 sw_if_index = ~0;
6489   u8 sw_if_index_set = 0;
6490   u8 is_add = 1;
6491   u8 static_mac = 0;
6492   u8 filter_mac = 0;
6493   u8 bvi_mac = 0;
6494   int count = 1;
6495   f64 before = 0;
6496   int j;
6497
6498   /* Parse args required to build the message */
6499   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6500     {
6501       if (unformat (i, "mac %U", unformat_ethernet_address, &mac))
6502         mac_set = 1;
6503       else if (unformat (i, "bd_id %d", &bd_id))
6504         bd_id_set = 1;
6505       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6506         sw_if_index_set = 1;
6507       else if (unformat (i, "sw_if"))
6508         {
6509           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6510             {
6511               if (unformat
6512                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6513                 sw_if_index_set = 1;
6514             }
6515           else
6516             break;
6517         }
6518       else if (unformat (i, "static"))
6519         static_mac = 1;
6520       else if (unformat (i, "filter"))
6521         {
6522           filter_mac = 1;
6523           static_mac = 1;
6524         }
6525       else if (unformat (i, "bvi"))
6526         {
6527           bvi_mac = 1;
6528           static_mac = 1;
6529         }
6530       else if (unformat (i, "del"))
6531         is_add = 0;
6532       else if (unformat (i, "count %d", &count))
6533         ;
6534       else
6535         break;
6536     }
6537
6538   if (mac_set == 0)
6539     {
6540       errmsg ("missing mac address");
6541       return -99;
6542     }
6543
6544   if (bd_id_set == 0)
6545     {
6546       errmsg ("missing bridge domain");
6547       return -99;
6548     }
6549
6550   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
6551     {
6552       errmsg ("missing interface name or sw_if_index");
6553       return -99;
6554     }
6555
6556   if (count > 1)
6557     {
6558       /* Turn on async mode */
6559       vam->async_mode = 1;
6560       vam->async_errors = 0;
6561       before = vat_time_now (vam);
6562     }
6563
6564   for (j = 0; j < count; j++)
6565     {
6566       M (L2FIB_ADD_DEL, mp);
6567
6568       mp->mac = mac;
6569       mp->bd_id = ntohl (bd_id);
6570       mp->is_add = is_add;
6571
6572       if (is_add)
6573         {
6574           mp->sw_if_index = ntohl (sw_if_index);
6575           mp->static_mac = static_mac;
6576           mp->filter_mac = filter_mac;
6577           mp->bvi_mac = bvi_mac;
6578         }
6579       increment_mac_address (&mac);
6580       /* send it... */
6581       S (mp);
6582     }
6583
6584   if (count > 1)
6585     {
6586       vl_api_control_ping_t *mp_ping;
6587       f64 after;
6588
6589       /* Shut off async mode */
6590       vam->async_mode = 0;
6591
6592       M (CONTROL_PING, mp_ping);
6593       S (mp_ping);
6594
6595       timeout = vat_time_now (vam) + 1.0;
6596       while (vat_time_now (vam) < timeout)
6597         if (vam->result_ready == 1)
6598           goto out;
6599       vam->retval = -99;
6600
6601     out:
6602       if (vam->retval == -99)
6603         errmsg ("timeout");
6604
6605       if (vam->async_errors > 0)
6606         {
6607           errmsg ("%d asynchronous errors", vam->async_errors);
6608           vam->retval = -98;
6609         }
6610       vam->async_errors = 0;
6611       after = vat_time_now (vam);
6612
6613       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6614              count, after - before, count / (after - before));
6615     }
6616   else
6617     {
6618       int ret;
6619
6620       /* Wait for a reply... */
6621       W (ret);
6622       return ret;
6623     }
6624   /* Return the good/bad news */
6625   return (vam->retval);
6626 }
6627
6628 static int
6629 api_bridge_domain_set_mac_age (vat_main_t * vam)
6630 {
6631   unformat_input_t *i = vam->input;
6632   vl_api_bridge_domain_set_mac_age_t *mp;
6633   u32 bd_id = ~0;
6634   u32 mac_age = 0;
6635   int ret;
6636
6637   /* Parse args required to build the message */
6638   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6639     {
6640       if (unformat (i, "bd_id %d", &bd_id));
6641       else if (unformat (i, "mac-age %d", &mac_age));
6642       else
6643         break;
6644     }
6645
6646   if (bd_id == ~0)
6647     {
6648       errmsg ("missing bridge domain");
6649       return -99;
6650     }
6651
6652   if (mac_age > 255)
6653     {
6654       errmsg ("mac age must be less than 256 ");
6655       return -99;
6656     }
6657
6658   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
6659
6660   mp->bd_id = htonl (bd_id);
6661   mp->mac_age = (u8) mac_age;
6662
6663   S (mp);
6664   W (ret);
6665   return ret;
6666 }
6667
6668 static int
6669 api_l2_flags (vat_main_t * vam)
6670 {
6671   unformat_input_t *i = vam->input;
6672   vl_api_l2_flags_t *mp;
6673   u32 sw_if_index;
6674   u32 flags = 0;
6675   u8 sw_if_index_set = 0;
6676   u8 is_set = 0;
6677   int ret;
6678
6679   /* Parse args required to build the message */
6680   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6681     {
6682       if (unformat (i, "sw_if_index %d", &sw_if_index))
6683         sw_if_index_set = 1;
6684       else if (unformat (i, "sw_if"))
6685         {
6686           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6687             {
6688               if (unformat
6689                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6690                 sw_if_index_set = 1;
6691             }
6692           else
6693             break;
6694         }
6695       else if (unformat (i, "learn"))
6696         flags |= L2_LEARN;
6697       else if (unformat (i, "forward"))
6698         flags |= L2_FWD;
6699       else if (unformat (i, "flood"))
6700         flags |= L2_FLOOD;
6701       else if (unformat (i, "uu-flood"))
6702         flags |= L2_UU_FLOOD;
6703       else if (unformat (i, "arp-term"))
6704         flags |= L2_ARP_TERM;
6705       else if (unformat (i, "off"))
6706         is_set = 0;
6707       else if (unformat (i, "disable"))
6708         is_set = 0;
6709       else
6710         break;
6711     }
6712
6713   if (sw_if_index_set == 0)
6714     {
6715       errmsg ("missing interface name or sw_if_index");
6716       return -99;
6717     }
6718
6719   M (L2_FLAGS, mp);
6720
6721   mp->sw_if_index = ntohl (sw_if_index);
6722   mp->feature_bitmap = ntohl (flags);
6723   mp->is_set = is_set;
6724
6725   S (mp);
6726   W (ret);
6727   return ret;
6728 }
6729
6730 static int
6731 api_bridge_flags (vat_main_t * vam)
6732 {
6733   unformat_input_t *i = vam->input;
6734   vl_api_bridge_flags_t *mp;
6735   u32 bd_id;
6736   u8 bd_id_set = 0;
6737   u8 is_set = 1;
6738   u32 flags = 0;
6739   int ret;
6740
6741   /* Parse args required to build the message */
6742   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6743     {
6744       if (unformat (i, "bd_id %d", &bd_id))
6745         bd_id_set = 1;
6746       else if (unformat (i, "learn"))
6747         flags |= L2_LEARN;
6748       else if (unformat (i, "forward"))
6749         flags |= L2_FWD;
6750       else if (unformat (i, "flood"))
6751         flags |= L2_FLOOD;
6752       else if (unformat (i, "uu-flood"))
6753         flags |= L2_UU_FLOOD;
6754       else if (unformat (i, "arp-term"))
6755         flags |= L2_ARP_TERM;
6756       else if (unformat (i, "off"))
6757         is_set = 0;
6758       else if (unformat (i, "disable"))
6759         is_set = 0;
6760       else
6761         break;
6762     }
6763
6764   if (bd_id_set == 0)
6765     {
6766       errmsg ("missing bridge domain");
6767       return -99;
6768     }
6769
6770   M (BRIDGE_FLAGS, mp);
6771
6772   mp->bd_id = ntohl (bd_id);
6773   mp->feature_bitmap = ntohl (flags);
6774   mp->is_set = is_set;
6775
6776   S (mp);
6777   W (ret);
6778   return ret;
6779 }
6780
6781 static int
6782 api_bd_ip_mac_add_del (vat_main_t * vam)
6783 {
6784   unformat_input_t *i = vam->input;
6785   vl_api_bd_ip_mac_add_del_t *mp;
6786   u32 bd_id;
6787   u8 is_ipv6 = 0;
6788   u8 is_add = 1;
6789   u8 bd_id_set = 0;
6790   u8 ip_set = 0;
6791   u8 mac_set = 0;
6792   ip4_address_t v4addr;
6793   ip6_address_t v6addr;
6794   u8 macaddr[6];
6795   int ret;
6796
6797
6798   /* Parse args required to build the message */
6799   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6800     {
6801       if (unformat (i, "bd_id %d", &bd_id))
6802         {
6803           bd_id_set++;
6804         }
6805       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
6806         {
6807           ip_set++;
6808         }
6809       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
6810         {
6811           ip_set++;
6812           is_ipv6++;
6813         }
6814       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
6815         {
6816           mac_set++;
6817         }
6818       else if (unformat (i, "del"))
6819         is_add = 0;
6820       else
6821         break;
6822     }
6823
6824   if (bd_id_set == 0)
6825     {
6826       errmsg ("missing bridge domain");
6827       return -99;
6828     }
6829   else if (ip_set == 0)
6830     {
6831       errmsg ("missing IP address");
6832       return -99;
6833     }
6834   else if (mac_set == 0)
6835     {
6836       errmsg ("missing MAC address");
6837       return -99;
6838     }
6839
6840   M (BD_IP_MAC_ADD_DEL, mp);
6841
6842   mp->bd_id = ntohl (bd_id);
6843   mp->is_ipv6 = is_ipv6;
6844   mp->is_add = is_add;
6845   if (is_ipv6)
6846     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
6847   else
6848     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
6849   clib_memcpy (mp->mac_address, macaddr, 6);
6850   S (mp);
6851   W (ret);
6852   return ret;
6853 }
6854
6855 static int
6856 api_tap_connect (vat_main_t * vam)
6857 {
6858   unformat_input_t *i = vam->input;
6859   vl_api_tap_connect_t *mp;
6860   u8 mac_address[6];
6861   u8 random_mac = 1;
6862   u8 name_set = 0;
6863   u8 *tap_name;
6864   u8 *tag = 0;
6865   ip4_address_t ip4_address;
6866   u32 ip4_mask_width;
6867   int ip4_address_set = 0;
6868   ip6_address_t ip6_address;
6869   u32 ip6_mask_width;
6870   int ip6_address_set = 0;
6871   int ret;
6872
6873   memset (mac_address, 0, sizeof (mac_address));
6874
6875   /* Parse args required to build the message */
6876   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6877     {
6878       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6879         {
6880           random_mac = 0;
6881         }
6882       else if (unformat (i, "random-mac"))
6883         random_mac = 1;
6884       else if (unformat (i, "tapname %s", &tap_name))
6885         name_set = 1;
6886       else if (unformat (i, "tag %s", &tag))
6887         ;
6888       else if (unformat (i, "address %U/%d",
6889                          unformat_ip4_address, &ip4_address, &ip4_mask_width))
6890         ip4_address_set = 1;
6891       else if (unformat (i, "address %U/%d",
6892                          unformat_ip6_address, &ip6_address, &ip6_mask_width))
6893         ip6_address_set = 1;
6894       else
6895         break;
6896     }
6897
6898   if (name_set == 0)
6899     {
6900       errmsg ("missing tap name");
6901       return -99;
6902     }
6903   if (vec_len (tap_name) > 63)
6904     {
6905       errmsg ("tap name too long");
6906       return -99;
6907     }
6908   vec_add1 (tap_name, 0);
6909
6910   if (vec_len (tag) > 63)
6911     {
6912       errmsg ("tag too long");
6913       return -99;
6914     }
6915
6916   /* Construct the API message */
6917   M (TAP_CONNECT, mp);
6918
6919   mp->use_random_mac = random_mac;
6920   clib_memcpy (mp->mac_address, mac_address, 6);
6921   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
6922   if (tag)
6923     clib_memcpy (mp->tag, tag, vec_len (tag));
6924
6925   if (ip4_address_set)
6926     {
6927       mp->ip4_address_set = 1;
6928       clib_memcpy (mp->ip4_address, &ip4_address, sizeof (mp->ip4_address));
6929       mp->ip4_mask_width = ip4_mask_width;
6930     }
6931   if (ip6_address_set)
6932     {
6933       mp->ip6_address_set = 1;
6934       clib_memcpy (mp->ip6_address, &ip6_address, sizeof (mp->ip6_address));
6935       mp->ip6_mask_width = ip6_mask_width;
6936     }
6937
6938   vec_free (tap_name);
6939   vec_free (tag);
6940
6941   /* send it... */
6942   S (mp);
6943
6944   /* Wait for a reply... */
6945   W (ret);
6946   return ret;
6947 }
6948
6949 static int
6950 api_tap_modify (vat_main_t * vam)
6951 {
6952   unformat_input_t *i = vam->input;
6953   vl_api_tap_modify_t *mp;
6954   u8 mac_address[6];
6955   u8 random_mac = 1;
6956   u8 name_set = 0;
6957   u8 *tap_name;
6958   u32 sw_if_index = ~0;
6959   u8 sw_if_index_set = 0;
6960   int ret;
6961
6962   memset (mac_address, 0, sizeof (mac_address));
6963
6964   /* Parse args required to build the message */
6965   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6966     {
6967       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6968         sw_if_index_set = 1;
6969       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6970         sw_if_index_set = 1;
6971       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6972         {
6973           random_mac = 0;
6974         }
6975       else if (unformat (i, "random-mac"))
6976         random_mac = 1;
6977       else if (unformat (i, "tapname %s", &tap_name))
6978         name_set = 1;
6979       else
6980         break;
6981     }
6982
6983   if (sw_if_index_set == 0)
6984     {
6985       errmsg ("missing vpp interface name");
6986       return -99;
6987     }
6988   if (name_set == 0)
6989     {
6990       errmsg ("missing tap name");
6991       return -99;
6992     }
6993   if (vec_len (tap_name) > 63)
6994     {
6995       errmsg ("tap name too long");
6996     }
6997   vec_add1 (tap_name, 0);
6998
6999   /* Construct the API message */
7000   M (TAP_MODIFY, mp);
7001
7002   mp->use_random_mac = random_mac;
7003   mp->sw_if_index = ntohl (sw_if_index);
7004   clib_memcpy (mp->mac_address, mac_address, 6);
7005   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
7006   vec_free (tap_name);
7007
7008   /* send it... */
7009   S (mp);
7010
7011   /* Wait for a reply... */
7012   W (ret);
7013   return ret;
7014 }
7015
7016 static int
7017 api_tap_delete (vat_main_t * vam)
7018 {
7019   unformat_input_t *i = vam->input;
7020   vl_api_tap_delete_t *mp;
7021   u32 sw_if_index = ~0;
7022   u8 sw_if_index_set = 0;
7023   int ret;
7024
7025   /* Parse args required to build the message */
7026   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7027     {
7028       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7029         sw_if_index_set = 1;
7030       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7031         sw_if_index_set = 1;
7032       else
7033         break;
7034     }
7035
7036   if (sw_if_index_set == 0)
7037     {
7038       errmsg ("missing vpp interface name");
7039       return -99;
7040     }
7041
7042   /* Construct the API message */
7043   M (TAP_DELETE, mp);
7044
7045   mp->sw_if_index = ntohl (sw_if_index);
7046
7047   /* send it... */
7048   S (mp);
7049
7050   /* Wait for a reply... */
7051   W (ret);
7052   return ret;
7053 }
7054
7055 static int
7056 api_ip_table_add_del (vat_main_t * vam)
7057 {
7058   unformat_input_t *i = vam->input;
7059   vl_api_ip_table_add_del_t *mp;
7060   u32 table_id = ~0;
7061   u8 is_ipv6 = 0;
7062   u8 is_add = 1;
7063   int ret = 0;
7064
7065   /* Parse args required to build the message */
7066   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7067     {
7068       if (unformat (i, "ipv6"))
7069         is_ipv6 = 1;
7070       else if (unformat (i, "del"))
7071         is_add = 0;
7072       else if (unformat (i, "add"))
7073         is_add = 1;
7074       else if (unformat (i, "table %d", &table_id))
7075         ;
7076       else
7077         {
7078           clib_warning ("parse error '%U'", format_unformat_error, i);
7079           return -99;
7080         }
7081     }
7082
7083   if (~0 == table_id)
7084     {
7085       errmsg ("missing table-ID");
7086       return -99;
7087     }
7088
7089   /* Construct the API message */
7090   M (IP_TABLE_ADD_DEL, mp);
7091
7092   mp->table_id = ntohl (table_id);
7093   mp->is_ipv6 = is_ipv6;
7094   mp->is_add = is_add;
7095
7096   /* send it... */
7097   S (mp);
7098
7099   /* Wait for a reply... */
7100   W (ret);
7101
7102   return ret;
7103 }
7104
7105 static int
7106 api_ip_add_del_route (vat_main_t * vam)
7107 {
7108   unformat_input_t *i = vam->input;
7109   vl_api_ip_add_del_route_t *mp;
7110   u32 sw_if_index = ~0, vrf_id = 0;
7111   u8 is_ipv6 = 0;
7112   u8 is_local = 0, is_drop = 0;
7113   u8 is_unreach = 0, is_prohibit = 0;
7114   u8 create_vrf_if_needed = 0;
7115   u8 is_add = 1;
7116   u32 next_hop_weight = 1;
7117   u8 not_last = 0;
7118   u8 is_multipath = 0;
7119   u8 address_set = 0;
7120   u8 address_length_set = 0;
7121   u32 next_hop_table_id = 0;
7122   u32 resolve_attempts = 0;
7123   u32 dst_address_length = 0;
7124   u8 next_hop_set = 0;
7125   ip4_address_t v4_dst_address, v4_next_hop_address;
7126   ip6_address_t v6_dst_address, v6_next_hop_address;
7127   int count = 1;
7128   int j;
7129   f64 before = 0;
7130   u32 random_add_del = 0;
7131   u32 *random_vector = 0;
7132   uword *random_hash;
7133   u32 random_seed = 0xdeaddabe;
7134   u32 classify_table_index = ~0;
7135   u8 is_classify = 0;
7136   u8 resolve_host = 0, resolve_attached = 0;
7137   mpls_label_t *next_hop_out_label_stack = NULL;
7138   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
7139   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
7140
7141   /* Parse args required to build the message */
7142   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7143     {
7144       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7145         ;
7146       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7147         ;
7148       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
7149         {
7150           address_set = 1;
7151           is_ipv6 = 0;
7152         }
7153       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
7154         {
7155           address_set = 1;
7156           is_ipv6 = 1;
7157         }
7158       else if (unformat (i, "/%d", &dst_address_length))
7159         {
7160           address_length_set = 1;
7161         }
7162
7163       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
7164                                          &v4_next_hop_address))
7165         {
7166           next_hop_set = 1;
7167         }
7168       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
7169                                          &v6_next_hop_address))
7170         {
7171           next_hop_set = 1;
7172         }
7173       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
7174         ;
7175       else if (unformat (i, "weight %d", &next_hop_weight))
7176         ;
7177       else if (unformat (i, "drop"))
7178         {
7179           is_drop = 1;
7180         }
7181       else if (unformat (i, "null-send-unreach"))
7182         {
7183           is_unreach = 1;
7184         }
7185       else if (unformat (i, "null-send-prohibit"))
7186         {
7187           is_prohibit = 1;
7188         }
7189       else if (unformat (i, "local"))
7190         {
7191           is_local = 1;
7192         }
7193       else if (unformat (i, "classify %d", &classify_table_index))
7194         {
7195           is_classify = 1;
7196         }
7197       else if (unformat (i, "del"))
7198         is_add = 0;
7199       else if (unformat (i, "add"))
7200         is_add = 1;
7201       else if (unformat (i, "not-last"))
7202         not_last = 1;
7203       else if (unformat (i, "resolve-via-host"))
7204         resolve_host = 1;
7205       else if (unformat (i, "resolve-via-attached"))
7206         resolve_attached = 1;
7207       else if (unformat (i, "multipath"))
7208         is_multipath = 1;
7209       else if (unformat (i, "vrf %d", &vrf_id))
7210         ;
7211       else if (unformat (i, "create-vrf"))
7212         create_vrf_if_needed = 1;
7213       else if (unformat (i, "count %d", &count))
7214         ;
7215       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
7216         ;
7217       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
7218         ;
7219       else if (unformat (i, "out-label %d", &next_hop_out_label))
7220         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
7221       else if (unformat (i, "via-label %d", &next_hop_via_label))
7222         ;
7223       else if (unformat (i, "random"))
7224         random_add_del = 1;
7225       else if (unformat (i, "seed %d", &random_seed))
7226         ;
7227       else
7228         {
7229           clib_warning ("parse error '%U'", format_unformat_error, i);
7230           return -99;
7231         }
7232     }
7233
7234   if (!next_hop_set && !is_drop && !is_local &&
7235       !is_classify && !is_unreach && !is_prohibit &&
7236       MPLS_LABEL_INVALID == next_hop_via_label)
7237     {
7238       errmsg
7239         ("next hop / local / drop / unreach / prohibit / classify not set");
7240       return -99;
7241     }
7242
7243   if (next_hop_set && MPLS_LABEL_INVALID != next_hop_via_label)
7244     {
7245       errmsg ("next hop and next-hop via label set");
7246       return -99;
7247     }
7248   if (address_set == 0)
7249     {
7250       errmsg ("missing addresses");
7251       return -99;
7252     }
7253
7254   if (address_length_set == 0)
7255     {
7256       errmsg ("missing address length");
7257       return -99;
7258     }
7259
7260   /* Generate a pile of unique, random routes */
7261   if (random_add_del)
7262     {
7263       u32 this_random_address;
7264       random_hash = hash_create (count, sizeof (uword));
7265
7266       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
7267       for (j = 0; j <= count; j++)
7268         {
7269           do
7270             {
7271               this_random_address = random_u32 (&random_seed);
7272               this_random_address =
7273                 clib_host_to_net_u32 (this_random_address);
7274             }
7275           while (hash_get (random_hash, this_random_address));
7276           vec_add1 (random_vector, this_random_address);
7277           hash_set (random_hash, this_random_address, 1);
7278         }
7279       hash_free (random_hash);
7280       v4_dst_address.as_u32 = random_vector[0];
7281     }
7282
7283   if (count > 1)
7284     {
7285       /* Turn on async mode */
7286       vam->async_mode = 1;
7287       vam->async_errors = 0;
7288       before = vat_time_now (vam);
7289     }
7290
7291   for (j = 0; j < count; j++)
7292     {
7293       /* Construct the API message */
7294       M2 (IP_ADD_DEL_ROUTE, mp,
7295           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
7296
7297       mp->next_hop_sw_if_index = ntohl (sw_if_index);
7298       mp->table_id = ntohl (vrf_id);
7299       mp->create_vrf_if_needed = create_vrf_if_needed;
7300
7301       mp->is_add = is_add;
7302       mp->is_drop = is_drop;
7303       mp->is_unreach = is_unreach;
7304       mp->is_prohibit = is_prohibit;
7305       mp->is_ipv6 = is_ipv6;
7306       mp->is_local = is_local;
7307       mp->is_classify = is_classify;
7308       mp->is_multipath = is_multipath;
7309       mp->is_resolve_host = resolve_host;
7310       mp->is_resolve_attached = resolve_attached;
7311       mp->not_last = not_last;
7312       mp->next_hop_weight = next_hop_weight;
7313       mp->dst_address_length = dst_address_length;
7314       mp->next_hop_table_id = ntohl (next_hop_table_id);
7315       mp->classify_table_index = ntohl (classify_table_index);
7316       mp->next_hop_via_label = ntohl (next_hop_via_label);
7317       mp->next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
7318       if (0 != mp->next_hop_n_out_labels)
7319         {
7320           memcpy (mp->next_hop_out_label_stack,
7321                   next_hop_out_label_stack,
7322                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
7323           vec_free (next_hop_out_label_stack);
7324         }
7325
7326       if (is_ipv6)
7327         {
7328           clib_memcpy (mp->dst_address, &v6_dst_address,
7329                        sizeof (v6_dst_address));
7330           if (next_hop_set)
7331             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
7332                          sizeof (v6_next_hop_address));
7333           increment_v6_address (&v6_dst_address);
7334         }
7335       else
7336         {
7337           clib_memcpy (mp->dst_address, &v4_dst_address,
7338                        sizeof (v4_dst_address));
7339           if (next_hop_set)
7340             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
7341                          sizeof (v4_next_hop_address));
7342           if (random_add_del)
7343             v4_dst_address.as_u32 = random_vector[j + 1];
7344           else
7345             increment_v4_address (&v4_dst_address);
7346         }
7347       /* send it... */
7348       S (mp);
7349       /* If we receive SIGTERM, stop now... */
7350       if (vam->do_exit)
7351         break;
7352     }
7353
7354   /* When testing multiple add/del ops, use a control-ping to sync */
7355   if (count > 1)
7356     {
7357       vl_api_control_ping_t *mp_ping;
7358       f64 after;
7359       f64 timeout;
7360
7361       /* Shut off async mode */
7362       vam->async_mode = 0;
7363
7364       M (CONTROL_PING, mp_ping);
7365       S (mp_ping);
7366
7367       timeout = vat_time_now (vam) + 1.0;
7368       while (vat_time_now (vam) < timeout)
7369         if (vam->result_ready == 1)
7370           goto out;
7371       vam->retval = -99;
7372
7373     out:
7374       if (vam->retval == -99)
7375         errmsg ("timeout");
7376
7377       if (vam->async_errors > 0)
7378         {
7379           errmsg ("%d asynchronous errors", vam->async_errors);
7380           vam->retval = -98;
7381         }
7382       vam->async_errors = 0;
7383       after = vat_time_now (vam);
7384
7385       /* slim chance, but we might have eaten SIGTERM on the first iteration */
7386       if (j > 0)
7387         count = j;
7388
7389       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
7390              count, after - before, count / (after - before));
7391     }
7392   else
7393     {
7394       int ret;
7395
7396       /* Wait for a reply... */
7397       W (ret);
7398       return ret;
7399     }
7400
7401   /* Return the good/bad news */
7402   return (vam->retval);
7403 }
7404
7405 static int
7406 api_ip_mroute_add_del (vat_main_t * vam)
7407 {
7408   unformat_input_t *i = vam->input;
7409   vl_api_ip_mroute_add_del_t *mp;
7410   u32 sw_if_index = ~0, vrf_id = 0;
7411   u8 is_ipv6 = 0;
7412   u8 is_local = 0;
7413   u8 create_vrf_if_needed = 0;
7414   u8 is_add = 1;
7415   u8 address_set = 0;
7416   u32 grp_address_length = 0;
7417   ip4_address_t v4_grp_address, v4_src_address;
7418   ip6_address_t v6_grp_address, v6_src_address;
7419   mfib_itf_flags_t iflags = 0;
7420   mfib_entry_flags_t eflags = 0;
7421   int ret;
7422
7423   /* Parse args required to build the message */
7424   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7425     {
7426       if (unformat (i, "sw_if_index %d", &sw_if_index))
7427         ;
7428       else if (unformat (i, "%U %U",
7429                          unformat_ip4_address, &v4_src_address,
7430                          unformat_ip4_address, &v4_grp_address))
7431         {
7432           grp_address_length = 64;
7433           address_set = 1;
7434           is_ipv6 = 0;
7435         }
7436       else if (unformat (i, "%U %U",
7437                          unformat_ip6_address, &v6_src_address,
7438                          unformat_ip6_address, &v6_grp_address))
7439         {
7440           grp_address_length = 256;
7441           address_set = 1;
7442           is_ipv6 = 1;
7443         }
7444       else if (unformat (i, "%U", unformat_ip4_address, &v4_grp_address))
7445         {
7446           memset (&v4_src_address, 0, sizeof (v4_src_address));
7447           grp_address_length = 32;
7448           address_set = 1;
7449           is_ipv6 = 0;
7450         }
7451       else if (unformat (i, "%U", unformat_ip6_address, &v6_grp_address))
7452         {
7453           memset (&v6_src_address, 0, sizeof (v6_src_address));
7454           grp_address_length = 128;
7455           address_set = 1;
7456           is_ipv6 = 1;
7457         }
7458       else if (unformat (i, "/%d", &grp_address_length))
7459         ;
7460       else if (unformat (i, "local"))
7461         {
7462           is_local = 1;
7463         }
7464       else if (unformat (i, "del"))
7465         is_add = 0;
7466       else if (unformat (i, "add"))
7467         is_add = 1;
7468       else if (unformat (i, "vrf %d", &vrf_id))
7469         ;
7470       else if (unformat (i, "create-vrf"))
7471         create_vrf_if_needed = 1;
7472       else if (unformat (i, "%U", unformat_mfib_itf_flags, &iflags))
7473         ;
7474       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
7475         ;
7476       else
7477         {
7478           clib_warning ("parse error '%U'", format_unformat_error, i);
7479           return -99;
7480         }
7481     }
7482
7483   if (address_set == 0)
7484     {
7485       errmsg ("missing addresses\n");
7486       return -99;
7487     }
7488
7489   /* Construct the API message */
7490   M (IP_MROUTE_ADD_DEL, mp);
7491
7492   mp->next_hop_sw_if_index = ntohl (sw_if_index);
7493   mp->table_id = ntohl (vrf_id);
7494   mp->create_vrf_if_needed = create_vrf_if_needed;
7495
7496   mp->is_add = is_add;
7497   mp->is_ipv6 = is_ipv6;
7498   mp->is_local = is_local;
7499   mp->itf_flags = ntohl (iflags);
7500   mp->entry_flags = ntohl (eflags);
7501   mp->grp_address_length = grp_address_length;
7502   mp->grp_address_length = ntohs (mp->grp_address_length);
7503
7504   if (is_ipv6)
7505     {
7506       clib_memcpy (mp->grp_address, &v6_grp_address, sizeof (v6_grp_address));
7507       clib_memcpy (mp->src_address, &v6_src_address, sizeof (v6_src_address));
7508     }
7509   else
7510     {
7511       clib_memcpy (mp->grp_address, &v4_grp_address, sizeof (v4_grp_address));
7512       clib_memcpy (mp->src_address, &v4_src_address, sizeof (v4_src_address));
7513
7514     }
7515
7516   /* send it... */
7517   S (mp);
7518   /* Wait for a reply... */
7519   W (ret);
7520   return ret;
7521 }
7522
7523 static int
7524 api_mpls_table_add_del (vat_main_t * vam)
7525 {
7526   unformat_input_t *i = vam->input;
7527   vl_api_mpls_table_add_del_t *mp;
7528   u32 table_id = ~0;
7529   u8 is_add = 1;
7530   int ret = 0;
7531
7532   /* Parse args required to build the message */
7533   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7534     {
7535       if (unformat (i, "table %d", &table_id))
7536         ;
7537       else if (unformat (i, "del"))
7538         is_add = 0;
7539       else if (unformat (i, "add"))
7540         is_add = 1;
7541       else
7542         {
7543           clib_warning ("parse error '%U'", format_unformat_error, i);
7544           return -99;
7545         }
7546     }
7547
7548   if (~0 == table_id)
7549     {
7550       errmsg ("missing table-ID");
7551       return -99;
7552     }
7553
7554   /* Construct the API message */
7555   M (MPLS_TABLE_ADD_DEL, mp);
7556
7557   mp->mt_table_id = ntohl (table_id);
7558   mp->mt_is_add = is_add;
7559
7560   /* send it... */
7561   S (mp);
7562
7563   /* Wait for a reply... */
7564   W (ret);
7565
7566   return ret;
7567 }
7568
7569 static int
7570 api_mpls_route_add_del (vat_main_t * vam)
7571 {
7572   unformat_input_t *i = vam->input;
7573   vl_api_mpls_route_add_del_t *mp;
7574   u32 sw_if_index = ~0, table_id = 0;
7575   u8 create_table_if_needed = 0;
7576   u8 is_add = 1;
7577   u32 next_hop_weight = 1;
7578   u8 is_multipath = 0;
7579   u32 next_hop_table_id = 0;
7580   u8 next_hop_set = 0;
7581   ip4_address_t v4_next_hop_address = {
7582     .as_u32 = 0,
7583   };
7584   ip6_address_t v6_next_hop_address = { {0} };
7585   int count = 1;
7586   int j;
7587   f64 before = 0;
7588   u32 classify_table_index = ~0;
7589   u8 is_classify = 0;
7590   u8 resolve_host = 0, resolve_attached = 0;
7591   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
7592   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
7593   mpls_label_t *next_hop_out_label_stack = NULL;
7594   mpls_label_t local_label = MPLS_LABEL_INVALID;
7595   u8 is_eos = 0;
7596   dpo_proto_t next_hop_proto = DPO_PROTO_IP4;
7597
7598   /* Parse args required to build the message */
7599   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7600     {
7601       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7602         ;
7603       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7604         ;
7605       else if (unformat (i, "%d", &local_label))
7606         ;
7607       else if (unformat (i, "eos"))
7608         is_eos = 1;
7609       else if (unformat (i, "non-eos"))
7610         is_eos = 0;
7611       else if (unformat (i, "via %U", unformat_ip4_address,
7612                          &v4_next_hop_address))
7613         {
7614           next_hop_set = 1;
7615           next_hop_proto = DPO_PROTO_IP4;
7616         }
7617       else if (unformat (i, "via %U", unformat_ip6_address,
7618                          &v6_next_hop_address))
7619         {
7620           next_hop_set = 1;
7621           next_hop_proto = DPO_PROTO_IP6;
7622         }
7623       else if (unformat (i, "weight %d", &next_hop_weight))
7624         ;
7625       else if (unformat (i, "create-table"))
7626         create_table_if_needed = 1;
7627       else if (unformat (i, "classify %d", &classify_table_index))
7628         {
7629           is_classify = 1;
7630         }
7631       else if (unformat (i, "del"))
7632         is_add = 0;
7633       else if (unformat (i, "add"))
7634         is_add = 1;
7635       else if (unformat (i, "resolve-via-host"))
7636         resolve_host = 1;
7637       else if (unformat (i, "resolve-via-attached"))
7638         resolve_attached = 1;
7639       else if (unformat (i, "multipath"))
7640         is_multipath = 1;
7641       else if (unformat (i, "count %d", &count))
7642         ;
7643       else if (unformat (i, "lookup-in-ip4-table %d", &next_hop_table_id))
7644         {
7645           next_hop_set = 1;
7646           next_hop_proto = DPO_PROTO_IP4;
7647         }
7648       else if (unformat (i, "lookup-in-ip6-table %d", &next_hop_table_id))
7649         {
7650           next_hop_set = 1;
7651           next_hop_proto = DPO_PROTO_IP6;
7652         }
7653       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
7654         ;
7655       else if (unformat (i, "via-label %d", &next_hop_via_label))
7656         ;
7657       else if (unformat (i, "out-label %d", &next_hop_out_label))
7658         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
7659       else
7660         {
7661           clib_warning ("parse error '%U'", format_unformat_error, i);
7662           return -99;
7663         }
7664     }
7665
7666   if (!next_hop_set && !is_classify)
7667     {
7668       errmsg ("next hop / classify not set");
7669       return -99;
7670     }
7671
7672   if (MPLS_LABEL_INVALID == local_label)
7673     {
7674       errmsg ("missing label");
7675       return -99;
7676     }
7677
7678   if (count > 1)
7679     {
7680       /* Turn on async mode */
7681       vam->async_mode = 1;
7682       vam->async_errors = 0;
7683       before = vat_time_now (vam);
7684     }
7685
7686   for (j = 0; j < count; j++)
7687     {
7688       /* Construct the API message */
7689       M2 (MPLS_ROUTE_ADD_DEL, mp,
7690           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
7691
7692       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
7693       mp->mr_table_id = ntohl (table_id);
7694       mp->mr_create_table_if_needed = create_table_if_needed;
7695
7696       mp->mr_is_add = is_add;
7697       mp->mr_next_hop_proto = next_hop_proto;
7698       mp->mr_is_classify = is_classify;
7699       mp->mr_is_multipath = is_multipath;
7700       mp->mr_is_resolve_host = resolve_host;
7701       mp->mr_is_resolve_attached = resolve_attached;
7702       mp->mr_next_hop_weight = next_hop_weight;
7703       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
7704       mp->mr_classify_table_index = ntohl (classify_table_index);
7705       mp->mr_next_hop_via_label = ntohl (next_hop_via_label);
7706       mp->mr_label = ntohl (local_label);
7707       mp->mr_eos = is_eos;
7708
7709       mp->mr_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
7710       if (0 != mp->mr_next_hop_n_out_labels)
7711         {
7712           memcpy (mp->mr_next_hop_out_label_stack,
7713                   next_hop_out_label_stack,
7714                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
7715           vec_free (next_hop_out_label_stack);
7716         }
7717
7718       if (next_hop_set)
7719         {
7720           if (DPO_PROTO_IP4 == next_hop_proto)
7721             {
7722               clib_memcpy (mp->mr_next_hop,
7723                            &v4_next_hop_address,
7724                            sizeof (v4_next_hop_address));
7725             }
7726           else if (DPO_PROTO_IP6 == next_hop_proto)
7727
7728             {
7729               clib_memcpy (mp->mr_next_hop,
7730                            &v6_next_hop_address,
7731                            sizeof (v6_next_hop_address));
7732             }
7733         }
7734       local_label++;
7735
7736       /* send it... */
7737       S (mp);
7738       /* If we receive SIGTERM, stop now... */
7739       if (vam->do_exit)
7740         break;
7741     }
7742
7743   /* When testing multiple add/del ops, use a control-ping to sync */
7744   if (count > 1)
7745     {
7746       vl_api_control_ping_t *mp_ping;
7747       f64 after;
7748       f64 timeout;
7749
7750       /* Shut off async mode */
7751       vam->async_mode = 0;
7752
7753       M (CONTROL_PING, mp_ping);
7754       S (mp_ping);
7755
7756       timeout = vat_time_now (vam) + 1.0;
7757       while (vat_time_now (vam) < timeout)
7758         if (vam->result_ready == 1)
7759           goto out;
7760       vam->retval = -99;
7761
7762     out:
7763       if (vam->retval == -99)
7764         errmsg ("timeout");
7765
7766       if (vam->async_errors > 0)
7767         {
7768           errmsg ("%d asynchronous errors", vam->async_errors);
7769           vam->retval = -98;
7770         }
7771       vam->async_errors = 0;
7772       after = vat_time_now (vam);
7773
7774       /* slim chance, but we might have eaten SIGTERM on the first iteration */
7775       if (j > 0)
7776         count = j;
7777
7778       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
7779              count, after - before, count / (after - before));
7780     }
7781   else
7782     {
7783       int ret;
7784
7785       /* Wait for a reply... */
7786       W (ret);
7787       return ret;
7788     }
7789
7790   /* Return the good/bad news */
7791   return (vam->retval);
7792 }
7793
7794 static int
7795 api_mpls_ip_bind_unbind (vat_main_t * vam)
7796 {
7797   unformat_input_t *i = vam->input;
7798   vl_api_mpls_ip_bind_unbind_t *mp;
7799   u32 ip_table_id = 0;
7800   u8 create_table_if_needed = 0;
7801   u8 is_bind = 1;
7802   u8 is_ip4 = 1;
7803   ip4_address_t v4_address;
7804   ip6_address_t v6_address;
7805   u32 address_length;
7806   u8 address_set = 0;
7807   mpls_label_t local_label = MPLS_LABEL_INVALID;
7808   int ret;
7809
7810   /* Parse args required to build the message */
7811   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7812     {
7813       if (unformat (i, "%U/%d", unformat_ip4_address,
7814                     &v4_address, &address_length))
7815         {
7816           is_ip4 = 1;
7817           address_set = 1;
7818         }
7819       else if (unformat (i, "%U/%d", unformat_ip6_address,
7820                          &v6_address, &address_length))
7821         {
7822           is_ip4 = 0;
7823           address_set = 1;
7824         }
7825       else if (unformat (i, "%d", &local_label))
7826         ;
7827       else if (unformat (i, "create-table"))
7828         create_table_if_needed = 1;
7829       else if (unformat (i, "table-id %d", &ip_table_id))
7830         ;
7831       else if (unformat (i, "unbind"))
7832         is_bind = 0;
7833       else if (unformat (i, "bind"))
7834         is_bind = 1;
7835       else
7836         {
7837           clib_warning ("parse error '%U'", format_unformat_error, i);
7838           return -99;
7839         }
7840     }
7841
7842   if (!address_set)
7843     {
7844       errmsg ("IP addres not set");
7845       return -99;
7846     }
7847
7848   if (MPLS_LABEL_INVALID == local_label)
7849     {
7850       errmsg ("missing label");
7851       return -99;
7852     }
7853
7854   /* Construct the API message */
7855   M (MPLS_IP_BIND_UNBIND, mp);
7856
7857   mp->mb_create_table_if_needed = create_table_if_needed;
7858   mp->mb_is_bind = is_bind;
7859   mp->mb_is_ip4 = is_ip4;
7860   mp->mb_ip_table_id = ntohl (ip_table_id);
7861   mp->mb_mpls_table_id = 0;
7862   mp->mb_label = ntohl (local_label);
7863   mp->mb_address_length = address_length;
7864
7865   if (is_ip4)
7866     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
7867   else
7868     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
7869
7870   /* send it... */
7871   S (mp);
7872
7873   /* Wait for a reply... */
7874   W (ret);
7875   return ret;
7876 }
7877
7878 static int
7879 api_proxy_arp_add_del (vat_main_t * vam)
7880 {
7881   unformat_input_t *i = vam->input;
7882   vl_api_proxy_arp_add_del_t *mp;
7883   u32 vrf_id = 0;
7884   u8 is_add = 1;
7885   ip4_address_t lo, hi;
7886   u8 range_set = 0;
7887   int ret;
7888
7889   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7890     {
7891       if (unformat (i, "vrf %d", &vrf_id))
7892         ;
7893       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
7894                          unformat_ip4_address, &hi))
7895         range_set = 1;
7896       else if (unformat (i, "del"))
7897         is_add = 0;
7898       else
7899         {
7900           clib_warning ("parse error '%U'", format_unformat_error, i);
7901           return -99;
7902         }
7903     }
7904
7905   if (range_set == 0)
7906     {
7907       errmsg ("address range not set");
7908       return -99;
7909     }
7910
7911   M (PROXY_ARP_ADD_DEL, mp);
7912
7913   mp->vrf_id = ntohl (vrf_id);
7914   mp->is_add = is_add;
7915   clib_memcpy (mp->low_address, &lo, sizeof (mp->low_address));
7916   clib_memcpy (mp->hi_address, &hi, sizeof (mp->hi_address));
7917
7918   S (mp);
7919   W (ret);
7920   return ret;
7921 }
7922
7923 static int
7924 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
7925 {
7926   unformat_input_t *i = vam->input;
7927   vl_api_proxy_arp_intfc_enable_disable_t *mp;
7928   u32 sw_if_index;
7929   u8 enable = 1;
7930   u8 sw_if_index_set = 0;
7931   int ret;
7932
7933   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7934     {
7935       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7936         sw_if_index_set = 1;
7937       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7938         sw_if_index_set = 1;
7939       else if (unformat (i, "enable"))
7940         enable = 1;
7941       else if (unformat (i, "disable"))
7942         enable = 0;
7943       else
7944         {
7945           clib_warning ("parse error '%U'", format_unformat_error, i);
7946           return -99;
7947         }
7948     }
7949
7950   if (sw_if_index_set == 0)
7951     {
7952       errmsg ("missing interface name or sw_if_index");
7953       return -99;
7954     }
7955
7956   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
7957
7958   mp->sw_if_index = ntohl (sw_if_index);
7959   mp->enable_disable = enable;
7960
7961   S (mp);
7962   W (ret);
7963   return ret;
7964 }
7965
7966 static int
7967 api_mpls_tunnel_add_del (vat_main_t * vam)
7968 {
7969   unformat_input_t *i = vam->input;
7970   vl_api_mpls_tunnel_add_del_t *mp;
7971
7972   u8 is_add = 1;
7973   u8 l2_only = 0;
7974   u32 sw_if_index = ~0;
7975   u32 next_hop_sw_if_index = ~0;
7976   u32 next_hop_proto_is_ip4 = 1;
7977
7978   u32 next_hop_table_id = 0;
7979   ip4_address_t v4_next_hop_address = {
7980     .as_u32 = 0,
7981   };
7982   ip6_address_t v6_next_hop_address = { {0} };
7983   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID, *labels = NULL;
7984   int ret;
7985
7986   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7987     {
7988       if (unformat (i, "add"))
7989         is_add = 1;
7990       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
7991         is_add = 0;
7992       else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
7993         ;
7994       else if (unformat (i, "via %U",
7995                          unformat_ip4_address, &v4_next_hop_address))
7996         {
7997           next_hop_proto_is_ip4 = 1;
7998         }
7999       else if (unformat (i, "via %U",
8000                          unformat_ip6_address, &v6_next_hop_address))
8001         {
8002           next_hop_proto_is_ip4 = 0;
8003         }
8004       else if (unformat (i, "l2-only"))
8005         l2_only = 1;
8006       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
8007         ;
8008       else if (unformat (i, "out-label %d", &next_hop_out_label))
8009         vec_add1 (labels, ntohl (next_hop_out_label));
8010       else
8011         {
8012           clib_warning ("parse error '%U'", format_unformat_error, i);
8013           return -99;
8014         }
8015     }
8016
8017   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (mpls_label_t) * vec_len (labels));
8018
8019   mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
8020   mp->mt_sw_if_index = ntohl (sw_if_index);
8021   mp->mt_is_add = is_add;
8022   mp->mt_l2_only = l2_only;
8023   mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
8024   mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
8025
8026   mp->mt_next_hop_n_out_labels = vec_len (labels);
8027
8028   if (0 != mp->mt_next_hop_n_out_labels)
8029     {
8030       clib_memcpy (mp->mt_next_hop_out_label_stack, labels,
8031                    sizeof (mpls_label_t) * mp->mt_next_hop_n_out_labels);
8032       vec_free (labels);
8033     }
8034
8035   if (next_hop_proto_is_ip4)
8036     {
8037       clib_memcpy (mp->mt_next_hop,
8038                    &v4_next_hop_address, sizeof (v4_next_hop_address));
8039     }
8040   else
8041     {
8042       clib_memcpy (mp->mt_next_hop,
8043                    &v6_next_hop_address, sizeof (v6_next_hop_address));
8044     }
8045
8046   S (mp);
8047   W (ret);
8048   return ret;
8049 }
8050
8051 static int
8052 api_sw_interface_set_unnumbered (vat_main_t * vam)
8053 {
8054   unformat_input_t *i = vam->input;
8055   vl_api_sw_interface_set_unnumbered_t *mp;
8056   u32 sw_if_index;
8057   u32 unnum_sw_index = ~0;
8058   u8 is_add = 1;
8059   u8 sw_if_index_set = 0;
8060   int ret;
8061
8062   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8063     {
8064       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8065         sw_if_index_set = 1;
8066       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8067         sw_if_index_set = 1;
8068       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
8069         ;
8070       else if (unformat (i, "del"))
8071         is_add = 0;
8072       else
8073         {
8074           clib_warning ("parse error '%U'", format_unformat_error, i);
8075           return -99;
8076         }
8077     }
8078
8079   if (sw_if_index_set == 0)
8080     {
8081       errmsg ("missing interface name or sw_if_index");
8082       return -99;
8083     }
8084
8085   M (SW_INTERFACE_SET_UNNUMBERED, mp);
8086
8087   mp->sw_if_index = ntohl (sw_if_index);
8088   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
8089   mp->is_add = is_add;
8090
8091   S (mp);
8092   W (ret);
8093   return ret;
8094 }
8095
8096 static int
8097 api_ip_neighbor_add_del (vat_main_t * vam)
8098 {
8099   unformat_input_t *i = vam->input;
8100   vl_api_ip_neighbor_add_del_t *mp;
8101   u32 sw_if_index;
8102   u8 sw_if_index_set = 0;
8103   u8 is_add = 1;
8104   u8 is_static = 0;
8105   u8 is_no_fib_entry = 0;
8106   u8 mac_address[6];
8107   u8 mac_set = 0;
8108   u8 v4_address_set = 0;
8109   u8 v6_address_set = 0;
8110   ip4_address_t v4address;
8111   ip6_address_t v6address;
8112   int ret;
8113
8114   memset (mac_address, 0, sizeof (mac_address));
8115
8116   /* Parse args required to build the message */
8117   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8118     {
8119       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
8120         {
8121           mac_set = 1;
8122         }
8123       else if (unformat (i, "del"))
8124         is_add = 0;
8125       else
8126         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8127         sw_if_index_set = 1;
8128       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8129         sw_if_index_set = 1;
8130       else if (unformat (i, "is_static"))
8131         is_static = 1;
8132       else if (unformat (i, "no-fib-entry"))
8133         is_no_fib_entry = 1;
8134       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
8135         v4_address_set = 1;
8136       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
8137         v6_address_set = 1;
8138       else
8139         {
8140           clib_warning ("parse error '%U'", format_unformat_error, i);
8141           return -99;
8142         }
8143     }
8144
8145   if (sw_if_index_set == 0)
8146     {
8147       errmsg ("missing interface name or sw_if_index");
8148       return -99;
8149     }
8150   if (v4_address_set && v6_address_set)
8151     {
8152       errmsg ("both v4 and v6 addresses set");
8153       return -99;
8154     }
8155   if (!v4_address_set && !v6_address_set)
8156     {
8157       errmsg ("no address set");
8158       return -99;
8159     }
8160
8161   /* Construct the API message */
8162   M (IP_NEIGHBOR_ADD_DEL, mp);
8163
8164   mp->sw_if_index = ntohl (sw_if_index);
8165   mp->is_add = is_add;
8166   mp->is_static = is_static;
8167   mp->is_no_adj_fib = is_no_fib_entry;
8168   if (mac_set)
8169     clib_memcpy (mp->mac_address, mac_address, 6);
8170   if (v6_address_set)
8171     {
8172       mp->is_ipv6 = 1;
8173       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
8174     }
8175   else
8176     {
8177       /* mp->is_ipv6 = 0; via memset in M macro above */
8178       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
8179     }
8180
8181   /* send it... */
8182   S (mp);
8183
8184   /* Wait for a reply, return good/bad news  */
8185   W (ret);
8186   return ret;
8187 }
8188
8189 static int
8190 api_reset_vrf (vat_main_t * vam)
8191 {
8192   unformat_input_t *i = vam->input;
8193   vl_api_reset_vrf_t *mp;
8194   u32 vrf_id = 0;
8195   u8 is_ipv6 = 0;
8196   u8 vrf_id_set = 0;
8197   int ret;
8198
8199   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8200     {
8201       if (unformat (i, "vrf %d", &vrf_id))
8202         vrf_id_set = 1;
8203       else if (unformat (i, "ipv6"))
8204         is_ipv6 = 1;
8205       else
8206         {
8207           clib_warning ("parse error '%U'", format_unformat_error, i);
8208           return -99;
8209         }
8210     }
8211
8212   if (vrf_id_set == 0)
8213     {
8214       errmsg ("missing vrf id");
8215       return -99;
8216     }
8217
8218   M (RESET_VRF, mp);
8219
8220   mp->vrf_id = ntohl (vrf_id);
8221   mp->is_ipv6 = is_ipv6;
8222
8223   S (mp);
8224   W (ret);
8225   return ret;
8226 }
8227
8228 static int
8229 api_create_vlan_subif (vat_main_t * vam)
8230 {
8231   unformat_input_t *i = vam->input;
8232   vl_api_create_vlan_subif_t *mp;
8233   u32 sw_if_index;
8234   u8 sw_if_index_set = 0;
8235   u32 vlan_id;
8236   u8 vlan_id_set = 0;
8237   int ret;
8238
8239   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8240     {
8241       if (unformat (i, "sw_if_index %d", &sw_if_index))
8242         sw_if_index_set = 1;
8243       else
8244         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8245         sw_if_index_set = 1;
8246       else if (unformat (i, "vlan %d", &vlan_id))
8247         vlan_id_set = 1;
8248       else
8249         {
8250           clib_warning ("parse error '%U'", format_unformat_error, i);
8251           return -99;
8252         }
8253     }
8254
8255   if (sw_if_index_set == 0)
8256     {
8257       errmsg ("missing interface name or sw_if_index");
8258       return -99;
8259     }
8260
8261   if (vlan_id_set == 0)
8262     {
8263       errmsg ("missing vlan_id");
8264       return -99;
8265     }
8266   M (CREATE_VLAN_SUBIF, mp);
8267
8268   mp->sw_if_index = ntohl (sw_if_index);
8269   mp->vlan_id = ntohl (vlan_id);
8270
8271   S (mp);
8272   W (ret);
8273   return ret;
8274 }
8275
8276 #define foreach_create_subif_bit                \
8277 _(no_tags)                                      \
8278 _(one_tag)                                      \
8279 _(two_tags)                                     \
8280 _(dot1ad)                                       \
8281 _(exact_match)                                  \
8282 _(default_sub)                                  \
8283 _(outer_vlan_id_any)                            \
8284 _(inner_vlan_id_any)
8285
8286 static int
8287 api_create_subif (vat_main_t * vam)
8288 {
8289   unformat_input_t *i = vam->input;
8290   vl_api_create_subif_t *mp;
8291   u32 sw_if_index;
8292   u8 sw_if_index_set = 0;
8293   u32 sub_id;
8294   u8 sub_id_set = 0;
8295   u32 no_tags = 0;
8296   u32 one_tag = 0;
8297   u32 two_tags = 0;
8298   u32 dot1ad = 0;
8299   u32 exact_match = 0;
8300   u32 default_sub = 0;
8301   u32 outer_vlan_id_any = 0;
8302   u32 inner_vlan_id_any = 0;
8303   u32 tmp;
8304   u16 outer_vlan_id = 0;
8305   u16 inner_vlan_id = 0;
8306   int ret;
8307
8308   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8309     {
8310       if (unformat (i, "sw_if_index %d", &sw_if_index))
8311         sw_if_index_set = 1;
8312       else
8313         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8314         sw_if_index_set = 1;
8315       else if (unformat (i, "sub_id %d", &sub_id))
8316         sub_id_set = 1;
8317       else if (unformat (i, "outer_vlan_id %d", &tmp))
8318         outer_vlan_id = tmp;
8319       else if (unformat (i, "inner_vlan_id %d", &tmp))
8320         inner_vlan_id = tmp;
8321
8322 #define _(a) else if (unformat (i, #a)) a = 1 ;
8323       foreach_create_subif_bit
8324 #undef _
8325         else
8326         {
8327           clib_warning ("parse error '%U'", format_unformat_error, i);
8328           return -99;
8329         }
8330     }
8331
8332   if (sw_if_index_set == 0)
8333     {
8334       errmsg ("missing interface name or sw_if_index");
8335       return -99;
8336     }
8337
8338   if (sub_id_set == 0)
8339     {
8340       errmsg ("missing sub_id");
8341       return -99;
8342     }
8343   M (CREATE_SUBIF, mp);
8344
8345   mp->sw_if_index = ntohl (sw_if_index);
8346   mp->sub_id = ntohl (sub_id);
8347
8348 #define _(a) mp->a = a;
8349   foreach_create_subif_bit;
8350 #undef _
8351
8352   mp->outer_vlan_id = ntohs (outer_vlan_id);
8353   mp->inner_vlan_id = ntohs (inner_vlan_id);
8354
8355   S (mp);
8356   W (ret);
8357   return ret;
8358 }
8359
8360 static int
8361 api_oam_add_del (vat_main_t * vam)
8362 {
8363   unformat_input_t *i = vam->input;
8364   vl_api_oam_add_del_t *mp;
8365   u32 vrf_id = 0;
8366   u8 is_add = 1;
8367   ip4_address_t src, dst;
8368   u8 src_set = 0;
8369   u8 dst_set = 0;
8370   int ret;
8371
8372   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8373     {
8374       if (unformat (i, "vrf %d", &vrf_id))
8375         ;
8376       else if (unformat (i, "src %U", unformat_ip4_address, &src))
8377         src_set = 1;
8378       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
8379         dst_set = 1;
8380       else if (unformat (i, "del"))
8381         is_add = 0;
8382       else
8383         {
8384           clib_warning ("parse error '%U'", format_unformat_error, i);
8385           return -99;
8386         }
8387     }
8388
8389   if (src_set == 0)
8390     {
8391       errmsg ("missing src addr");
8392       return -99;
8393     }
8394
8395   if (dst_set == 0)
8396     {
8397       errmsg ("missing dst addr");
8398       return -99;
8399     }
8400
8401   M (OAM_ADD_DEL, mp);
8402
8403   mp->vrf_id = ntohl (vrf_id);
8404   mp->is_add = is_add;
8405   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
8406   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
8407
8408   S (mp);
8409   W (ret);
8410   return ret;
8411 }
8412
8413 static int
8414 api_reset_fib (vat_main_t * vam)
8415 {
8416   unformat_input_t *i = vam->input;
8417   vl_api_reset_fib_t *mp;
8418   u32 vrf_id = 0;
8419   u8 is_ipv6 = 0;
8420   u8 vrf_id_set = 0;
8421
8422   int ret;
8423   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8424     {
8425       if (unformat (i, "vrf %d", &vrf_id))
8426         vrf_id_set = 1;
8427       else if (unformat (i, "ipv6"))
8428         is_ipv6 = 1;
8429       else
8430         {
8431           clib_warning ("parse error '%U'", format_unformat_error, i);
8432           return -99;
8433         }
8434     }
8435
8436   if (vrf_id_set == 0)
8437     {
8438       errmsg ("missing vrf id");
8439       return -99;
8440     }
8441
8442   M (RESET_FIB, mp);
8443
8444   mp->vrf_id = ntohl (vrf_id);
8445   mp->is_ipv6 = is_ipv6;
8446
8447   S (mp);
8448   W (ret);
8449   return ret;
8450 }
8451
8452 static int
8453 api_dhcp_proxy_config (vat_main_t * vam)
8454 {
8455   unformat_input_t *i = vam->input;
8456   vl_api_dhcp_proxy_config_t *mp;
8457   u32 rx_vrf_id = 0;
8458   u32 server_vrf_id = 0;
8459   u8 is_add = 1;
8460   u8 v4_address_set = 0;
8461   u8 v6_address_set = 0;
8462   ip4_address_t v4address;
8463   ip6_address_t v6address;
8464   u8 v4_src_address_set = 0;
8465   u8 v6_src_address_set = 0;
8466   ip4_address_t v4srcaddress;
8467   ip6_address_t v6srcaddress;
8468   int ret;
8469
8470   /* Parse args required to build the message */
8471   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8472     {
8473       if (unformat (i, "del"))
8474         is_add = 0;
8475       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
8476         ;
8477       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
8478         ;
8479       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
8480         v4_address_set = 1;
8481       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
8482         v6_address_set = 1;
8483       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
8484         v4_src_address_set = 1;
8485       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
8486         v6_src_address_set = 1;
8487       else
8488         break;
8489     }
8490
8491   if (v4_address_set && v6_address_set)
8492     {
8493       errmsg ("both v4 and v6 server addresses set");
8494       return -99;
8495     }
8496   if (!v4_address_set && !v6_address_set)
8497     {
8498       errmsg ("no server addresses set");
8499       return -99;
8500     }
8501
8502   if (v4_src_address_set && v6_src_address_set)
8503     {
8504       errmsg ("both v4 and v6  src addresses set");
8505       return -99;
8506     }
8507   if (!v4_src_address_set && !v6_src_address_set)
8508     {
8509       errmsg ("no src addresses set");
8510       return -99;
8511     }
8512
8513   if (!(v4_src_address_set && v4_address_set) &&
8514       !(v6_src_address_set && v6_address_set))
8515     {
8516       errmsg ("no matching server and src addresses set");
8517       return -99;
8518     }
8519
8520   /* Construct the API message */
8521   M (DHCP_PROXY_CONFIG, mp);
8522
8523   mp->is_add = is_add;
8524   mp->rx_vrf_id = ntohl (rx_vrf_id);
8525   mp->server_vrf_id = ntohl (server_vrf_id);
8526   if (v6_address_set)
8527     {
8528       mp->is_ipv6 = 1;
8529       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
8530       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
8531     }
8532   else
8533     {
8534       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
8535       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
8536     }
8537
8538   /* send it... */
8539   S (mp);
8540
8541   /* Wait for a reply, return good/bad news  */
8542   W (ret);
8543   return ret;
8544 }
8545
8546 #define vl_api_dhcp_proxy_details_t_endian vl_noop_handler
8547 #define vl_api_dhcp_proxy_details_t_print vl_noop_handler
8548
8549 static void
8550 vl_api_dhcp_proxy_details_t_handler (vl_api_dhcp_proxy_details_t * mp)
8551 {
8552   vat_main_t *vam = &vat_main;
8553   u32 i, count = mp->count;
8554   vl_api_dhcp_server_t *s;
8555
8556   if (mp->is_ipv6)
8557     print (vam->ofp,
8558            "RX Table-ID %d, Source Address %U, VSS FIB-ID %d, VSS OUI %d",
8559            ntohl (mp->rx_vrf_id),
8560            format_ip6_address, mp->dhcp_src_address,
8561            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
8562   else
8563     print (vam->ofp,
8564            "RX Table-ID %d, Source Address %U, VSS FIB-ID %d, VSS OUI %d",
8565            ntohl (mp->rx_vrf_id),
8566            format_ip4_address, mp->dhcp_src_address,
8567            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
8568
8569   for (i = 0; i < count; i++)
8570     {
8571       s = &mp->servers[i];
8572
8573       if (mp->is_ipv6)
8574         print (vam->ofp,
8575                " Server Table-ID %d, Server Address %U",
8576                ntohl (s->server_vrf_id), format_ip6_address, s->dhcp_server);
8577       else
8578         print (vam->ofp,
8579                " Server Table-ID %d, Server Address %U",
8580                ntohl (s->server_vrf_id), format_ip4_address, s->dhcp_server);
8581     }
8582 }
8583
8584 static void vl_api_dhcp_proxy_details_t_handler_json
8585   (vl_api_dhcp_proxy_details_t * mp)
8586 {
8587   vat_main_t *vam = &vat_main;
8588   vat_json_node_t *node = NULL;
8589   u32 i, count = mp->count;
8590   struct in_addr ip4;
8591   struct in6_addr ip6;
8592   vl_api_dhcp_server_t *s;
8593
8594   if (VAT_JSON_ARRAY != vam->json_tree.type)
8595     {
8596       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
8597       vat_json_init_array (&vam->json_tree);
8598     }
8599   node = vat_json_array_add (&vam->json_tree);
8600
8601   vat_json_init_object (node);
8602   vat_json_object_add_uint (node, "rx-table-id", ntohl (mp->rx_vrf_id));
8603   vat_json_object_add_uint (node, "vss-fib-id", ntohl (mp->vss_fib_id));
8604   vat_json_object_add_uint (node, "vss-oui", ntohl (mp->vss_oui));
8605
8606   if (mp->is_ipv6)
8607     {
8608       clib_memcpy (&ip6, &mp->dhcp_src_address, sizeof (ip6));
8609       vat_json_object_add_ip6 (node, "src_address", ip6);
8610     }
8611   else
8612     {
8613       clib_memcpy (&ip4, &mp->dhcp_src_address, sizeof (ip4));
8614       vat_json_object_add_ip4 (node, "src_address", ip4);
8615     }
8616
8617   for (i = 0; i < count; i++)
8618     {
8619       s = &mp->servers[i];
8620
8621       vat_json_object_add_uint (node, "server-table-id",
8622                                 ntohl (s->server_vrf_id));
8623
8624       if (mp->is_ipv6)
8625         {
8626           clib_memcpy (&ip4, &s->dhcp_server, sizeof (ip4));
8627           vat_json_object_add_ip4 (node, "src_address", ip4);
8628         }
8629       else
8630         {
8631           clib_memcpy (&ip6, &s->dhcp_server, sizeof (ip6));
8632           vat_json_object_add_ip6 (node, "server_address", ip6);
8633         }
8634     }
8635 }
8636
8637 static int
8638 api_dhcp_proxy_dump (vat_main_t * vam)
8639 {
8640   unformat_input_t *i = vam->input;
8641   vl_api_control_ping_t *mp_ping;
8642   vl_api_dhcp_proxy_dump_t *mp;
8643   u8 is_ipv6 = 0;
8644   int ret;
8645
8646   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8647     {
8648       if (unformat (i, "ipv6"))
8649         is_ipv6 = 1;
8650       else
8651         {
8652           clib_warning ("parse error '%U'", format_unformat_error, i);
8653           return -99;
8654         }
8655     }
8656
8657   M (DHCP_PROXY_DUMP, mp);
8658
8659   mp->is_ip6 = is_ipv6;
8660   S (mp);
8661
8662   /* Use a control ping for synchronization */
8663   M (CONTROL_PING, mp_ping);
8664   S (mp_ping);
8665
8666   W (ret);
8667   return ret;
8668 }
8669
8670 static int
8671 api_dhcp_proxy_set_vss (vat_main_t * vam)
8672 {
8673   unformat_input_t *i = vam->input;
8674   vl_api_dhcp_proxy_set_vss_t *mp;
8675   u8 is_ipv6 = 0;
8676   u8 is_add = 1;
8677   u32 tbl_id;
8678   u8 tbl_id_set = 0;
8679   u32 oui;
8680   u8 oui_set = 0;
8681   u32 fib_id;
8682   u8 fib_id_set = 0;
8683   int ret;
8684
8685   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8686     {
8687       if (unformat (i, "tbl_id %d", &tbl_id))
8688         tbl_id_set = 1;
8689       if (unformat (i, "fib_id %d", &fib_id))
8690         fib_id_set = 1;
8691       if (unformat (i, "oui %d", &oui))
8692         oui_set = 1;
8693       else if (unformat (i, "ipv6"))
8694         is_ipv6 = 1;
8695       else if (unformat (i, "del"))
8696         is_add = 0;
8697       else
8698         {
8699           clib_warning ("parse error '%U'", format_unformat_error, i);
8700           return -99;
8701         }
8702     }
8703
8704   if (tbl_id_set == 0)
8705     {
8706       errmsg ("missing tbl id");
8707       return -99;
8708     }
8709
8710   if (fib_id_set == 0)
8711     {
8712       errmsg ("missing fib id");
8713       return -99;
8714     }
8715   if (oui_set == 0)
8716     {
8717       errmsg ("missing oui");
8718       return -99;
8719     }
8720
8721   M (DHCP_PROXY_SET_VSS, mp);
8722   mp->tbl_id = ntohl (tbl_id);
8723   mp->fib_id = ntohl (fib_id);
8724   mp->oui = ntohl (oui);
8725   mp->is_ipv6 = is_ipv6;
8726   mp->is_add = is_add;
8727
8728   S (mp);
8729   W (ret);
8730   return ret;
8731 }
8732
8733 static int
8734 api_dhcp_client_config (vat_main_t * vam)
8735 {
8736   unformat_input_t *i = vam->input;
8737   vl_api_dhcp_client_config_t *mp;
8738   u32 sw_if_index;
8739   u8 sw_if_index_set = 0;
8740   u8 is_add = 1;
8741   u8 *hostname = 0;
8742   u8 disable_event = 0;
8743   int ret;
8744
8745   /* Parse args required to build the message */
8746   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8747     {
8748       if (unformat (i, "del"))
8749         is_add = 0;
8750       else
8751         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8752         sw_if_index_set = 1;
8753       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8754         sw_if_index_set = 1;
8755       else if (unformat (i, "hostname %s", &hostname))
8756         ;
8757       else if (unformat (i, "disable_event"))
8758         disable_event = 1;
8759       else
8760         break;
8761     }
8762
8763   if (sw_if_index_set == 0)
8764     {
8765       errmsg ("missing interface name or sw_if_index");
8766       return -99;
8767     }
8768
8769   if (vec_len (hostname) > 63)
8770     {
8771       errmsg ("hostname too long");
8772     }
8773   vec_add1 (hostname, 0);
8774
8775   /* Construct the API message */
8776   M (DHCP_CLIENT_CONFIG, mp);
8777
8778   mp->sw_if_index = htonl (sw_if_index);
8779   clib_memcpy (mp->hostname, hostname, vec_len (hostname));
8780   vec_free (hostname);
8781   mp->is_add = is_add;
8782   mp->want_dhcp_event = disable_event ? 0 : 1;
8783   mp->pid = htonl (getpid ());
8784
8785   /* send it... */
8786   S (mp);
8787
8788   /* Wait for a reply, return good/bad news  */
8789   W (ret);
8790   return ret;
8791 }
8792
8793 static int
8794 api_set_ip_flow_hash (vat_main_t * vam)
8795 {
8796   unformat_input_t *i = vam->input;
8797   vl_api_set_ip_flow_hash_t *mp;
8798   u32 vrf_id = 0;
8799   u8 is_ipv6 = 0;
8800   u8 vrf_id_set = 0;
8801   u8 src = 0;
8802   u8 dst = 0;
8803   u8 sport = 0;
8804   u8 dport = 0;
8805   u8 proto = 0;
8806   u8 reverse = 0;
8807   int ret;
8808
8809   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8810     {
8811       if (unformat (i, "vrf %d", &vrf_id))
8812         vrf_id_set = 1;
8813       else if (unformat (i, "ipv6"))
8814         is_ipv6 = 1;
8815       else if (unformat (i, "src"))
8816         src = 1;
8817       else if (unformat (i, "dst"))
8818         dst = 1;
8819       else if (unformat (i, "sport"))
8820         sport = 1;
8821       else if (unformat (i, "dport"))
8822         dport = 1;
8823       else if (unformat (i, "proto"))
8824         proto = 1;
8825       else if (unformat (i, "reverse"))
8826         reverse = 1;
8827
8828       else
8829         {
8830           clib_warning ("parse error '%U'", format_unformat_error, i);
8831           return -99;
8832         }
8833     }
8834
8835   if (vrf_id_set == 0)
8836     {
8837       errmsg ("missing vrf id");
8838       return -99;
8839     }
8840
8841   M (SET_IP_FLOW_HASH, mp);
8842   mp->src = src;
8843   mp->dst = dst;
8844   mp->sport = sport;
8845   mp->dport = dport;
8846   mp->proto = proto;
8847   mp->reverse = reverse;
8848   mp->vrf_id = ntohl (vrf_id);
8849   mp->is_ipv6 = is_ipv6;
8850
8851   S (mp);
8852   W (ret);
8853   return ret;
8854 }
8855
8856 static int
8857 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
8858 {
8859   unformat_input_t *i = vam->input;
8860   vl_api_sw_interface_ip6_enable_disable_t *mp;
8861   u32 sw_if_index;
8862   u8 sw_if_index_set = 0;
8863   u8 enable = 0;
8864   int ret;
8865
8866   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8867     {
8868       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8869         sw_if_index_set = 1;
8870       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8871         sw_if_index_set = 1;
8872       else if (unformat (i, "enable"))
8873         enable = 1;
8874       else if (unformat (i, "disable"))
8875         enable = 0;
8876       else
8877         {
8878           clib_warning ("parse error '%U'", format_unformat_error, i);
8879           return -99;
8880         }
8881     }
8882
8883   if (sw_if_index_set == 0)
8884     {
8885       errmsg ("missing interface name or sw_if_index");
8886       return -99;
8887     }
8888
8889   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
8890
8891   mp->sw_if_index = ntohl (sw_if_index);
8892   mp->enable = enable;
8893
8894   S (mp);
8895   W (ret);
8896   return ret;
8897 }
8898
8899 static int
8900 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
8901 {
8902   unformat_input_t *i = vam->input;
8903   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
8904   u32 sw_if_index;
8905   u8 sw_if_index_set = 0;
8906   u8 v6_address_set = 0;
8907   ip6_address_t v6address;
8908   int ret;
8909
8910   /* Parse args required to build the message */
8911   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8912     {
8913       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8914         sw_if_index_set = 1;
8915       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8916         sw_if_index_set = 1;
8917       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
8918         v6_address_set = 1;
8919       else
8920         break;
8921     }
8922
8923   if (sw_if_index_set == 0)
8924     {
8925       errmsg ("missing interface name or sw_if_index");
8926       return -99;
8927     }
8928   if (!v6_address_set)
8929     {
8930       errmsg ("no address set");
8931       return -99;
8932     }
8933
8934   /* Construct the API message */
8935   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS, mp);
8936
8937   mp->sw_if_index = ntohl (sw_if_index);
8938   clib_memcpy (mp->address, &v6address, sizeof (v6address));
8939
8940   /* send it... */
8941   S (mp);
8942
8943   /* Wait for a reply, return good/bad news  */
8944   W (ret);
8945   return ret;
8946 }
8947
8948 static int
8949 api_ip6nd_proxy_add_del (vat_main_t * vam)
8950 {
8951   unformat_input_t *i = vam->input;
8952   vl_api_ip6nd_proxy_add_del_t *mp;
8953   u32 sw_if_index = ~0;
8954   u8 v6_address_set = 0;
8955   ip6_address_t v6address;
8956   u8 is_del = 0;
8957   int ret;
8958
8959   /* Parse args required to build the message */
8960   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8961     {
8962       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8963         ;
8964       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8965         ;
8966       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
8967         v6_address_set = 1;
8968       if (unformat (i, "del"))
8969         is_del = 1;
8970       else
8971         {
8972           clib_warning ("parse error '%U'", format_unformat_error, i);
8973           return -99;
8974         }
8975     }
8976
8977   if (sw_if_index == ~0)
8978     {
8979       errmsg ("missing interface name or sw_if_index");
8980       return -99;
8981     }
8982   if (!v6_address_set)
8983     {
8984       errmsg ("no address set");
8985       return -99;
8986     }
8987
8988   /* Construct the API message */
8989   M (IP6ND_PROXY_ADD_DEL, mp);
8990
8991   mp->is_del = is_del;
8992   mp->sw_if_index = ntohl (sw_if_index);
8993   clib_memcpy (mp->address, &v6address, sizeof (v6address));
8994
8995   /* send it... */
8996   S (mp);
8997
8998   /* Wait for a reply, return good/bad news  */
8999   W (ret);
9000   return ret;
9001 }
9002
9003 static int
9004 api_ip6nd_proxy_dump (vat_main_t * vam)
9005 {
9006   vl_api_ip6nd_proxy_dump_t *mp;
9007   vl_api_control_ping_t *mp_ping;
9008   int ret;
9009
9010   M (IP6ND_PROXY_DUMP, mp);
9011
9012   S (mp);
9013
9014   /* Use a control ping for synchronization */
9015   M (CONTROL_PING, mp_ping);
9016   S (mp_ping);
9017
9018   W (ret);
9019   return ret;
9020 }
9021
9022 static void vl_api_ip6nd_proxy_details_t_handler
9023   (vl_api_ip6nd_proxy_details_t * mp)
9024 {
9025   vat_main_t *vam = &vat_main;
9026
9027   print (vam->ofp, "host %U sw_if_index %d",
9028          format_ip6_address, mp->address, ntohl (mp->sw_if_index));
9029 }
9030
9031 static void vl_api_ip6nd_proxy_details_t_handler_json
9032   (vl_api_ip6nd_proxy_details_t * mp)
9033 {
9034   vat_main_t *vam = &vat_main;
9035   struct in6_addr ip6;
9036   vat_json_node_t *node = NULL;
9037
9038   if (VAT_JSON_ARRAY != vam->json_tree.type)
9039     {
9040       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9041       vat_json_init_array (&vam->json_tree);
9042     }
9043   node = vat_json_array_add (&vam->json_tree);
9044
9045   vat_json_init_object (node);
9046   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9047
9048   clib_memcpy (&ip6, mp->address, sizeof (ip6));
9049   vat_json_object_add_ip6 (node, "host", ip6);
9050 }
9051
9052 static int
9053 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
9054 {
9055   unformat_input_t *i = vam->input;
9056   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
9057   u32 sw_if_index;
9058   u8 sw_if_index_set = 0;
9059   u32 address_length = 0;
9060   u8 v6_address_set = 0;
9061   ip6_address_t v6address;
9062   u8 use_default = 0;
9063   u8 no_advertise = 0;
9064   u8 off_link = 0;
9065   u8 no_autoconfig = 0;
9066   u8 no_onlink = 0;
9067   u8 is_no = 0;
9068   u32 val_lifetime = 0;
9069   u32 pref_lifetime = 0;
9070   int ret;
9071
9072   /* Parse args required to build the message */
9073   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9074     {
9075       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9076         sw_if_index_set = 1;
9077       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9078         sw_if_index_set = 1;
9079       else if (unformat (i, "%U/%d",
9080                          unformat_ip6_address, &v6address, &address_length))
9081         v6_address_set = 1;
9082       else if (unformat (i, "val_life %d", &val_lifetime))
9083         ;
9084       else if (unformat (i, "pref_life %d", &pref_lifetime))
9085         ;
9086       else if (unformat (i, "def"))
9087         use_default = 1;
9088       else if (unformat (i, "noadv"))
9089         no_advertise = 1;
9090       else if (unformat (i, "offl"))
9091         off_link = 1;
9092       else if (unformat (i, "noauto"))
9093         no_autoconfig = 1;
9094       else if (unformat (i, "nolink"))
9095         no_onlink = 1;
9096       else if (unformat (i, "isno"))
9097         is_no = 1;
9098       else
9099         {
9100           clib_warning ("parse error '%U'", format_unformat_error, i);
9101           return -99;
9102         }
9103     }
9104
9105   if (sw_if_index_set == 0)
9106     {
9107       errmsg ("missing interface name or sw_if_index");
9108       return -99;
9109     }
9110   if (!v6_address_set)
9111     {
9112       errmsg ("no address set");
9113       return -99;
9114     }
9115
9116   /* Construct the API message */
9117   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
9118
9119   mp->sw_if_index = ntohl (sw_if_index);
9120   clib_memcpy (mp->address, &v6address, sizeof (v6address));
9121   mp->address_length = address_length;
9122   mp->use_default = use_default;
9123   mp->no_advertise = no_advertise;
9124   mp->off_link = off_link;
9125   mp->no_autoconfig = no_autoconfig;
9126   mp->no_onlink = no_onlink;
9127   mp->is_no = is_no;
9128   mp->val_lifetime = ntohl (val_lifetime);
9129   mp->pref_lifetime = ntohl (pref_lifetime);
9130
9131   /* send it... */
9132   S (mp);
9133
9134   /* Wait for a reply, return good/bad news  */
9135   W (ret);
9136   return ret;
9137 }
9138
9139 static int
9140 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
9141 {
9142   unformat_input_t *i = vam->input;
9143   vl_api_sw_interface_ip6nd_ra_config_t *mp;
9144   u32 sw_if_index;
9145   u8 sw_if_index_set = 0;
9146   u8 suppress = 0;
9147   u8 managed = 0;
9148   u8 other = 0;
9149   u8 ll_option = 0;
9150   u8 send_unicast = 0;
9151   u8 cease = 0;
9152   u8 is_no = 0;
9153   u8 default_router = 0;
9154   u32 max_interval = 0;
9155   u32 min_interval = 0;
9156   u32 lifetime = 0;
9157   u32 initial_count = 0;
9158   u32 initial_interval = 0;
9159   int ret;
9160
9161
9162   /* Parse args required to build the message */
9163   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9164     {
9165       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9166         sw_if_index_set = 1;
9167       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9168         sw_if_index_set = 1;
9169       else if (unformat (i, "maxint %d", &max_interval))
9170         ;
9171       else if (unformat (i, "minint %d", &min_interval))
9172         ;
9173       else if (unformat (i, "life %d", &lifetime))
9174         ;
9175       else if (unformat (i, "count %d", &initial_count))
9176         ;
9177       else if (unformat (i, "interval %d", &initial_interval))
9178         ;
9179       else if (unformat (i, "suppress") || unformat (i, "surpress"))
9180         suppress = 1;
9181       else if (unformat (i, "managed"))
9182         managed = 1;
9183       else if (unformat (i, "other"))
9184         other = 1;
9185       else if (unformat (i, "ll"))
9186         ll_option = 1;
9187       else if (unformat (i, "send"))
9188         send_unicast = 1;
9189       else if (unformat (i, "cease"))
9190         cease = 1;
9191       else if (unformat (i, "isno"))
9192         is_no = 1;
9193       else if (unformat (i, "def"))
9194         default_router = 1;
9195       else
9196         {
9197           clib_warning ("parse error '%U'", format_unformat_error, i);
9198           return -99;
9199         }
9200     }
9201
9202   if (sw_if_index_set == 0)
9203     {
9204       errmsg ("missing interface name or sw_if_index");
9205       return -99;
9206     }
9207
9208   /* Construct the API message */
9209   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
9210
9211   mp->sw_if_index = ntohl (sw_if_index);
9212   mp->max_interval = ntohl (max_interval);
9213   mp->min_interval = ntohl (min_interval);
9214   mp->lifetime = ntohl (lifetime);
9215   mp->initial_count = ntohl (initial_count);
9216   mp->initial_interval = ntohl (initial_interval);
9217   mp->suppress = suppress;
9218   mp->managed = managed;
9219   mp->other = other;
9220   mp->ll_option = ll_option;
9221   mp->send_unicast = send_unicast;
9222   mp->cease = cease;
9223   mp->is_no = is_no;
9224   mp->default_router = default_router;
9225
9226   /* send it... */
9227   S (mp);
9228
9229   /* Wait for a reply, return good/bad news  */
9230   W (ret);
9231   return ret;
9232 }
9233
9234 static int
9235 api_set_arp_neighbor_limit (vat_main_t * vam)
9236 {
9237   unformat_input_t *i = vam->input;
9238   vl_api_set_arp_neighbor_limit_t *mp;
9239   u32 arp_nbr_limit;
9240   u8 limit_set = 0;
9241   u8 is_ipv6 = 0;
9242   int ret;
9243
9244   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9245     {
9246       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
9247         limit_set = 1;
9248       else if (unformat (i, "ipv6"))
9249         is_ipv6 = 1;
9250       else
9251         {
9252           clib_warning ("parse error '%U'", format_unformat_error, i);
9253           return -99;
9254         }
9255     }
9256
9257   if (limit_set == 0)
9258     {
9259       errmsg ("missing limit value");
9260       return -99;
9261     }
9262
9263   M (SET_ARP_NEIGHBOR_LIMIT, mp);
9264
9265   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
9266   mp->is_ipv6 = is_ipv6;
9267
9268   S (mp);
9269   W (ret);
9270   return ret;
9271 }
9272
9273 static int
9274 api_l2_patch_add_del (vat_main_t * vam)
9275 {
9276   unformat_input_t *i = vam->input;
9277   vl_api_l2_patch_add_del_t *mp;
9278   u32 rx_sw_if_index;
9279   u8 rx_sw_if_index_set = 0;
9280   u32 tx_sw_if_index;
9281   u8 tx_sw_if_index_set = 0;
9282   u8 is_add = 1;
9283   int ret;
9284
9285   /* Parse args required to build the message */
9286   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9287     {
9288       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
9289         rx_sw_if_index_set = 1;
9290       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
9291         tx_sw_if_index_set = 1;
9292       else if (unformat (i, "rx"))
9293         {
9294           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9295             {
9296               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
9297                             &rx_sw_if_index))
9298                 rx_sw_if_index_set = 1;
9299             }
9300           else
9301             break;
9302         }
9303       else if (unformat (i, "tx"))
9304         {
9305           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9306             {
9307               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
9308                             &tx_sw_if_index))
9309                 tx_sw_if_index_set = 1;
9310             }
9311           else
9312             break;
9313         }
9314       else if (unformat (i, "del"))
9315         is_add = 0;
9316       else
9317         break;
9318     }
9319
9320   if (rx_sw_if_index_set == 0)
9321     {
9322       errmsg ("missing rx interface name or rx_sw_if_index");
9323       return -99;
9324     }
9325
9326   if (tx_sw_if_index_set == 0)
9327     {
9328       errmsg ("missing tx interface name or tx_sw_if_index");
9329       return -99;
9330     }
9331
9332   M (L2_PATCH_ADD_DEL, mp);
9333
9334   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
9335   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
9336   mp->is_add = is_add;
9337
9338   S (mp);
9339   W (ret);
9340   return ret;
9341 }
9342
9343 u8 is_del;
9344 u8 localsid_addr[16];
9345 u8 end_psp;
9346 u8 behavior;
9347 u32 sw_if_index;
9348 u32 vlan_index;
9349 u32 fib_table;
9350 u8 nh_addr[16];
9351
9352 static int
9353 api_sr_localsid_add_del (vat_main_t * vam)
9354 {
9355   unformat_input_t *i = vam->input;
9356   vl_api_sr_localsid_add_del_t *mp;
9357
9358   u8 is_del;
9359   ip6_address_t localsid;
9360   u8 end_psp = 0;
9361   u8 behavior = ~0;
9362   u32 sw_if_index;
9363   u32 fib_table = ~(u32) 0;
9364   ip6_address_t next_hop;
9365
9366   bool nexthop_set = 0;
9367
9368   int ret;
9369
9370   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9371     {
9372       if (unformat (i, "del"))
9373         is_del = 1;
9374       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
9375       else if (unformat (i, "next-hop %U", unformat_ip6_address, &next_hop))
9376         nexthop_set = 1;
9377       else if (unformat (i, "behavior %u", &behavior));
9378       else if (unformat (i, "sw_if_index %u", &sw_if_index));
9379       else if (unformat (i, "fib-table %u", &fib_table));
9380       else if (unformat (i, "end.psp %u", &behavior));
9381       else
9382         break;
9383     }
9384
9385   M (SR_LOCALSID_ADD_DEL, mp);
9386
9387   clib_memcpy (mp->localsid_addr, &localsid, sizeof (mp->localsid_addr));
9388   if (nexthop_set)
9389     clib_memcpy (mp->nh_addr, &next_hop, sizeof (mp->nh_addr));
9390   mp->behavior = behavior;
9391   mp->sw_if_index = ntohl (sw_if_index);
9392   mp->fib_table = ntohl (fib_table);
9393   mp->end_psp = end_psp;
9394   mp->is_del = is_del;
9395
9396   S (mp);
9397   W (ret);
9398   return ret;
9399 }
9400
9401 static int
9402 api_ioam_enable (vat_main_t * vam)
9403 {
9404   unformat_input_t *input = vam->input;
9405   vl_api_ioam_enable_t *mp;
9406   u32 id = 0;
9407   int has_trace_option = 0;
9408   int has_pot_option = 0;
9409   int has_seqno_option = 0;
9410   int has_analyse_option = 0;
9411   int ret;
9412
9413   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9414     {
9415       if (unformat (input, "trace"))
9416         has_trace_option = 1;
9417       else if (unformat (input, "pot"))
9418         has_pot_option = 1;
9419       else if (unformat (input, "seqno"))
9420         has_seqno_option = 1;
9421       else if (unformat (input, "analyse"))
9422         has_analyse_option = 1;
9423       else
9424         break;
9425     }
9426   M (IOAM_ENABLE, mp);
9427   mp->id = htons (id);
9428   mp->seqno = has_seqno_option;
9429   mp->analyse = has_analyse_option;
9430   mp->pot_enable = has_pot_option;
9431   mp->trace_enable = has_trace_option;
9432
9433   S (mp);
9434   W (ret);
9435   return ret;
9436 }
9437
9438
9439 static int
9440 api_ioam_disable (vat_main_t * vam)
9441 {
9442   vl_api_ioam_disable_t *mp;
9443   int ret;
9444
9445   M (IOAM_DISABLE, mp);
9446   S (mp);
9447   W (ret);
9448   return ret;
9449 }
9450
9451 #define foreach_tcp_proto_field                 \
9452 _(src_port)                                     \
9453 _(dst_port)
9454
9455 #define foreach_udp_proto_field                 \
9456 _(src_port)                                     \
9457 _(dst_port)
9458
9459 #define foreach_ip4_proto_field                 \
9460 _(src_address)                                  \
9461 _(dst_address)                                  \
9462 _(tos)                                          \
9463 _(length)                                       \
9464 _(fragment_id)                                  \
9465 _(ttl)                                          \
9466 _(protocol)                                     \
9467 _(checksum)
9468
9469 typedef struct
9470 {
9471   u16 src_port, dst_port;
9472 } tcpudp_header_t;
9473
9474 #if VPP_API_TEST_BUILTIN == 0
9475 uword
9476 unformat_tcp_mask (unformat_input_t * input, va_list * args)
9477 {
9478   u8 **maskp = va_arg (*args, u8 **);
9479   u8 *mask = 0;
9480   u8 found_something = 0;
9481   tcp_header_t *tcp;
9482
9483 #define _(a) u8 a=0;
9484   foreach_tcp_proto_field;
9485 #undef _
9486
9487   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9488     {
9489       if (0);
9490 #define _(a) else if (unformat (input, #a)) a=1;
9491       foreach_tcp_proto_field
9492 #undef _
9493         else
9494         break;
9495     }
9496
9497 #define _(a) found_something += a;
9498   foreach_tcp_proto_field;
9499 #undef _
9500
9501   if (found_something == 0)
9502     return 0;
9503
9504   vec_validate (mask, sizeof (*tcp) - 1);
9505
9506   tcp = (tcp_header_t *) mask;
9507
9508 #define _(a) if (a) memset (&tcp->a, 0xff, sizeof (tcp->a));
9509   foreach_tcp_proto_field;
9510 #undef _
9511
9512   *maskp = mask;
9513   return 1;
9514 }
9515
9516 uword
9517 unformat_udp_mask (unformat_input_t * input, va_list * args)
9518 {
9519   u8 **maskp = va_arg (*args, u8 **);
9520   u8 *mask = 0;
9521   u8 found_something = 0;
9522   udp_header_t *udp;
9523
9524 #define _(a) u8 a=0;
9525   foreach_udp_proto_field;
9526 #undef _
9527
9528   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9529     {
9530       if (0);
9531 #define _(a) else if (unformat (input, #a)) a=1;
9532       foreach_udp_proto_field
9533 #undef _
9534         else
9535         break;
9536     }
9537
9538 #define _(a) found_something += a;
9539   foreach_udp_proto_field;
9540 #undef _
9541
9542   if (found_something == 0)
9543     return 0;
9544
9545   vec_validate (mask, sizeof (*udp) - 1);
9546
9547   udp = (udp_header_t *) mask;
9548
9549 #define _(a) if (a) memset (&udp->a, 0xff, sizeof (udp->a));
9550   foreach_udp_proto_field;
9551 #undef _
9552
9553   *maskp = mask;
9554   return 1;
9555 }
9556
9557 uword
9558 unformat_l4_mask (unformat_input_t * input, va_list * args)
9559 {
9560   u8 **maskp = va_arg (*args, u8 **);
9561   u16 src_port = 0, dst_port = 0;
9562   tcpudp_header_t *tcpudp;
9563
9564   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9565     {
9566       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
9567         return 1;
9568       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
9569         return 1;
9570       else if (unformat (input, "src_port"))
9571         src_port = 0xFFFF;
9572       else if (unformat (input, "dst_port"))
9573         dst_port = 0xFFFF;
9574       else
9575         return 0;
9576     }
9577
9578   if (!src_port && !dst_port)
9579     return 0;
9580
9581   u8 *mask = 0;
9582   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
9583
9584   tcpudp = (tcpudp_header_t *) mask;
9585   tcpudp->src_port = src_port;
9586   tcpudp->dst_port = dst_port;
9587
9588   *maskp = mask;
9589
9590   return 1;
9591 }
9592
9593 uword
9594 unformat_ip4_mask (unformat_input_t * input, va_list * args)
9595 {
9596   u8 **maskp = va_arg (*args, u8 **);
9597   u8 *mask = 0;
9598   u8 found_something = 0;
9599   ip4_header_t *ip;
9600
9601 #define _(a) u8 a=0;
9602   foreach_ip4_proto_field;
9603 #undef _
9604   u8 version = 0;
9605   u8 hdr_length = 0;
9606
9607
9608   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9609     {
9610       if (unformat (input, "version"))
9611         version = 1;
9612       else if (unformat (input, "hdr_length"))
9613         hdr_length = 1;
9614       else if (unformat (input, "src"))
9615         src_address = 1;
9616       else if (unformat (input, "dst"))
9617         dst_address = 1;
9618       else if (unformat (input, "proto"))
9619         protocol = 1;
9620
9621 #define _(a) else if (unformat (input, #a)) a=1;
9622       foreach_ip4_proto_field
9623 #undef _
9624         else
9625         break;
9626     }
9627
9628 #define _(a) found_something += a;
9629   foreach_ip4_proto_field;
9630 #undef _
9631
9632   if (found_something == 0)
9633     return 0;
9634
9635   vec_validate (mask, sizeof (*ip) - 1);
9636
9637   ip = (ip4_header_t *) mask;
9638
9639 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
9640   foreach_ip4_proto_field;
9641 #undef _
9642
9643   ip->ip_version_and_header_length = 0;
9644
9645   if (version)
9646     ip->ip_version_and_header_length |= 0xF0;
9647
9648   if (hdr_length)
9649     ip->ip_version_and_header_length |= 0x0F;
9650
9651   *maskp = mask;
9652   return 1;
9653 }
9654
9655 #define foreach_ip6_proto_field                 \
9656 _(src_address)                                  \
9657 _(dst_address)                                  \
9658 _(payload_length)                               \
9659 _(hop_limit)                                    \
9660 _(protocol)
9661
9662 uword
9663 unformat_ip6_mask (unformat_input_t * input, va_list * args)
9664 {
9665   u8 **maskp = va_arg (*args, u8 **);
9666   u8 *mask = 0;
9667   u8 found_something = 0;
9668   ip6_header_t *ip;
9669   u32 ip_version_traffic_class_and_flow_label;
9670
9671 #define _(a) u8 a=0;
9672   foreach_ip6_proto_field;
9673 #undef _
9674   u8 version = 0;
9675   u8 traffic_class = 0;
9676   u8 flow_label = 0;
9677
9678   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9679     {
9680       if (unformat (input, "version"))
9681         version = 1;
9682       else if (unformat (input, "traffic-class"))
9683         traffic_class = 1;
9684       else if (unformat (input, "flow-label"))
9685         flow_label = 1;
9686       else if (unformat (input, "src"))
9687         src_address = 1;
9688       else if (unformat (input, "dst"))
9689         dst_address = 1;
9690       else if (unformat (input, "proto"))
9691         protocol = 1;
9692
9693 #define _(a) else if (unformat (input, #a)) a=1;
9694       foreach_ip6_proto_field
9695 #undef _
9696         else
9697         break;
9698     }
9699
9700 #define _(a) found_something += a;
9701   foreach_ip6_proto_field;
9702 #undef _
9703
9704   if (found_something == 0)
9705     return 0;
9706
9707   vec_validate (mask, sizeof (*ip) - 1);
9708
9709   ip = (ip6_header_t *) mask;
9710
9711 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
9712   foreach_ip6_proto_field;
9713 #undef _
9714
9715   ip_version_traffic_class_and_flow_label = 0;
9716
9717   if (version)
9718     ip_version_traffic_class_and_flow_label |= 0xF0000000;
9719
9720   if (traffic_class)
9721     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
9722
9723   if (flow_label)
9724     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
9725
9726   ip->ip_version_traffic_class_and_flow_label =
9727     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
9728
9729   *maskp = mask;
9730   return 1;
9731 }
9732
9733 uword
9734 unformat_l3_mask (unformat_input_t * input, va_list * args)
9735 {
9736   u8 **maskp = va_arg (*args, u8 **);
9737
9738   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9739     {
9740       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
9741         return 1;
9742       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
9743         return 1;
9744       else
9745         break;
9746     }
9747   return 0;
9748 }
9749
9750 uword
9751 unformat_l2_mask (unformat_input_t * input, va_list * args)
9752 {
9753   u8 **maskp = va_arg (*args, u8 **);
9754   u8 *mask = 0;
9755   u8 src = 0;
9756   u8 dst = 0;
9757   u8 proto = 0;
9758   u8 tag1 = 0;
9759   u8 tag2 = 0;
9760   u8 ignore_tag1 = 0;
9761   u8 ignore_tag2 = 0;
9762   u8 cos1 = 0;
9763   u8 cos2 = 0;
9764   u8 dot1q = 0;
9765   u8 dot1ad = 0;
9766   int len = 14;
9767
9768   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9769     {
9770       if (unformat (input, "src"))
9771         src = 1;
9772       else if (unformat (input, "dst"))
9773         dst = 1;
9774       else if (unformat (input, "proto"))
9775         proto = 1;
9776       else if (unformat (input, "tag1"))
9777         tag1 = 1;
9778       else if (unformat (input, "tag2"))
9779         tag2 = 1;
9780       else if (unformat (input, "ignore-tag1"))
9781         ignore_tag1 = 1;
9782       else if (unformat (input, "ignore-tag2"))
9783         ignore_tag2 = 1;
9784       else if (unformat (input, "cos1"))
9785         cos1 = 1;
9786       else if (unformat (input, "cos2"))
9787         cos2 = 1;
9788       else if (unformat (input, "dot1q"))
9789         dot1q = 1;
9790       else if (unformat (input, "dot1ad"))
9791         dot1ad = 1;
9792       else
9793         break;
9794     }
9795   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
9796        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
9797     return 0;
9798
9799   if (tag1 || ignore_tag1 || cos1 || dot1q)
9800     len = 18;
9801   if (tag2 || ignore_tag2 || cos2 || dot1ad)
9802     len = 22;
9803
9804   vec_validate (mask, len - 1);
9805
9806   if (dst)
9807     memset (mask, 0xff, 6);
9808
9809   if (src)
9810     memset (mask + 6, 0xff, 6);
9811
9812   if (tag2 || dot1ad)
9813     {
9814       /* inner vlan tag */
9815       if (tag2)
9816         {
9817           mask[19] = 0xff;
9818           mask[18] = 0x0f;
9819         }
9820       if (cos2)
9821         mask[18] |= 0xe0;
9822       if (proto)
9823         mask[21] = mask[20] = 0xff;
9824       if (tag1)
9825         {
9826           mask[15] = 0xff;
9827           mask[14] = 0x0f;
9828         }
9829       if (cos1)
9830         mask[14] |= 0xe0;
9831       *maskp = mask;
9832       return 1;
9833     }
9834   if (tag1 | dot1q)
9835     {
9836       if (tag1)
9837         {
9838           mask[15] = 0xff;
9839           mask[14] = 0x0f;
9840         }
9841       if (cos1)
9842         mask[14] |= 0xe0;
9843       if (proto)
9844         mask[16] = mask[17] = 0xff;
9845
9846       *maskp = mask;
9847       return 1;
9848     }
9849   if (cos2)
9850     mask[18] |= 0xe0;
9851   if (cos1)
9852     mask[14] |= 0xe0;
9853   if (proto)
9854     mask[12] = mask[13] = 0xff;
9855
9856   *maskp = mask;
9857   return 1;
9858 }
9859
9860 uword
9861 unformat_classify_mask (unformat_input_t * input, va_list * args)
9862 {
9863   u8 **maskp = va_arg (*args, u8 **);
9864   u32 *skipp = va_arg (*args, u32 *);
9865   u32 *matchp = va_arg (*args, u32 *);
9866   u32 match;
9867   u8 *mask = 0;
9868   u8 *l2 = 0;
9869   u8 *l3 = 0;
9870   u8 *l4 = 0;
9871   int i;
9872
9873   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9874     {
9875       if (unformat (input, "hex %U", unformat_hex_string, &mask))
9876         ;
9877       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
9878         ;
9879       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
9880         ;
9881       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
9882         ;
9883       else
9884         break;
9885     }
9886
9887   if (l4 && !l3)
9888     {
9889       vec_free (mask);
9890       vec_free (l2);
9891       vec_free (l4);
9892       return 0;
9893     }
9894
9895   if (mask || l2 || l3 || l4)
9896     {
9897       if (l2 || l3 || l4)
9898         {
9899           /* "With a free Ethernet header in every package" */
9900           if (l2 == 0)
9901             vec_validate (l2, 13);
9902           mask = l2;
9903           if (vec_len (l3))
9904             {
9905               vec_append (mask, l3);
9906               vec_free (l3);
9907             }
9908           if (vec_len (l4))
9909             {
9910               vec_append (mask, l4);
9911               vec_free (l4);
9912             }
9913         }
9914
9915       /* Scan forward looking for the first significant mask octet */
9916       for (i = 0; i < vec_len (mask); i++)
9917         if (mask[i])
9918           break;
9919
9920       /* compute (skip, match) params */
9921       *skipp = i / sizeof (u32x4);
9922       vec_delete (mask, *skipp * sizeof (u32x4), 0);
9923
9924       /* Pad mask to an even multiple of the vector size */
9925       while (vec_len (mask) % sizeof (u32x4))
9926         vec_add1 (mask, 0);
9927
9928       match = vec_len (mask) / sizeof (u32x4);
9929
9930       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
9931         {
9932           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
9933           if (*tmp || *(tmp + 1))
9934             break;
9935           match--;
9936         }
9937       if (match == 0)
9938         clib_warning ("BUG: match 0");
9939
9940       _vec_len (mask) = match * sizeof (u32x4);
9941
9942       *matchp = match;
9943       *maskp = mask;
9944
9945       return 1;
9946     }
9947
9948   return 0;
9949 }
9950 #endif /* VPP_API_TEST_BUILTIN */
9951
9952 #define foreach_l2_next                         \
9953 _(drop, DROP)                                   \
9954 _(ethernet, ETHERNET_INPUT)                     \
9955 _(ip4, IP4_INPUT)                               \
9956 _(ip6, IP6_INPUT)
9957
9958 uword
9959 unformat_l2_next_index (unformat_input_t * input, va_list * args)
9960 {
9961   u32 *miss_next_indexp = va_arg (*args, u32 *);
9962   u32 next_index = 0;
9963   u32 tmp;
9964
9965 #define _(n,N) \
9966   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
9967   foreach_l2_next;
9968 #undef _
9969
9970   if (unformat (input, "%d", &tmp))
9971     {
9972       next_index = tmp;
9973       goto out;
9974     }
9975
9976   return 0;
9977
9978 out:
9979   *miss_next_indexp = next_index;
9980   return 1;
9981 }
9982
9983 #define foreach_ip_next                         \
9984 _(drop, DROP)                                   \
9985 _(local, LOCAL)                                 \
9986 _(rewrite, REWRITE)
9987
9988 uword
9989 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
9990 {
9991   u32 *miss_next_indexp = va_arg (*args, u32 *);
9992   u32 next_index = 0;
9993   u32 tmp;
9994
9995 #define _(n,N) \
9996   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
9997   foreach_ip_next;
9998 #undef _
9999
10000   if (unformat (input, "%d", &tmp))
10001     {
10002       next_index = tmp;
10003       goto out;
10004     }
10005
10006   return 0;
10007
10008 out:
10009   *miss_next_indexp = next_index;
10010   return 1;
10011 }
10012
10013 #define foreach_acl_next                        \
10014 _(deny, DENY)
10015
10016 uword
10017 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
10018 {
10019   u32 *miss_next_indexp = va_arg (*args, u32 *);
10020   u32 next_index = 0;
10021   u32 tmp;
10022
10023 #define _(n,N) \
10024   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
10025   foreach_acl_next;
10026 #undef _
10027
10028   if (unformat (input, "permit"))
10029     {
10030       next_index = ~0;
10031       goto out;
10032     }
10033   else if (unformat (input, "%d", &tmp))
10034     {
10035       next_index = tmp;
10036       goto out;
10037     }
10038
10039   return 0;
10040
10041 out:
10042   *miss_next_indexp = next_index;
10043   return 1;
10044 }
10045
10046 uword
10047 unformat_policer_precolor (unformat_input_t * input, va_list * args)
10048 {
10049   u32 *r = va_arg (*args, u32 *);
10050
10051   if (unformat (input, "conform-color"))
10052     *r = POLICE_CONFORM;
10053   else if (unformat (input, "exceed-color"))
10054     *r = POLICE_EXCEED;
10055   else
10056     return 0;
10057
10058   return 1;
10059 }
10060
10061 static int
10062 api_classify_add_del_table (vat_main_t * vam)
10063 {
10064   unformat_input_t *i = vam->input;
10065   vl_api_classify_add_del_table_t *mp;
10066
10067   u32 nbuckets = 2;
10068   u32 skip = ~0;
10069   u32 match = ~0;
10070   int is_add = 1;
10071   int del_chain = 0;
10072   u32 table_index = ~0;
10073   u32 next_table_index = ~0;
10074   u32 miss_next_index = ~0;
10075   u32 memory_size = 32 << 20;
10076   u8 *mask = 0;
10077   u32 current_data_flag = 0;
10078   int current_data_offset = 0;
10079   int ret;
10080
10081   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10082     {
10083       if (unformat (i, "del"))
10084         is_add = 0;
10085       else if (unformat (i, "del-chain"))
10086         {
10087           is_add = 0;
10088           del_chain = 1;
10089         }
10090       else if (unformat (i, "buckets %d", &nbuckets))
10091         ;
10092       else if (unformat (i, "memory_size %d", &memory_size))
10093         ;
10094       else if (unformat (i, "skip %d", &skip))
10095         ;
10096       else if (unformat (i, "match %d", &match))
10097         ;
10098       else if (unformat (i, "table %d", &table_index))
10099         ;
10100       else if (unformat (i, "mask %U", unformat_classify_mask,
10101                          &mask, &skip, &match))
10102         ;
10103       else if (unformat (i, "next-table %d", &next_table_index))
10104         ;
10105       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
10106                          &miss_next_index))
10107         ;
10108       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
10109                          &miss_next_index))
10110         ;
10111       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
10112                          &miss_next_index))
10113         ;
10114       else if (unformat (i, "current-data-flag %d", &current_data_flag))
10115         ;
10116       else if (unformat (i, "current-data-offset %d", &current_data_offset))
10117         ;
10118       else
10119         break;
10120     }
10121
10122   if (is_add && mask == 0)
10123     {
10124       errmsg ("Mask required");
10125       return -99;
10126     }
10127
10128   if (is_add && skip == ~0)
10129     {
10130       errmsg ("skip count required");
10131       return -99;
10132     }
10133
10134   if (is_add && match == ~0)
10135     {
10136       errmsg ("match count required");
10137       return -99;
10138     }
10139
10140   if (!is_add && table_index == ~0)
10141     {
10142       errmsg ("table index required for delete");
10143       return -99;
10144     }
10145
10146   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
10147
10148   mp->is_add = is_add;
10149   mp->del_chain = del_chain;
10150   mp->table_index = ntohl (table_index);
10151   mp->nbuckets = ntohl (nbuckets);
10152   mp->memory_size = ntohl (memory_size);
10153   mp->skip_n_vectors = ntohl (skip);
10154   mp->match_n_vectors = ntohl (match);
10155   mp->next_table_index = ntohl (next_table_index);
10156   mp->miss_next_index = ntohl (miss_next_index);
10157   mp->current_data_flag = ntohl (current_data_flag);
10158   mp->current_data_offset = ntohl (current_data_offset);
10159   clib_memcpy (mp->mask, mask, vec_len (mask));
10160
10161   vec_free (mask);
10162
10163   S (mp);
10164   W (ret);
10165   return ret;
10166 }
10167
10168 #if VPP_API_TEST_BUILTIN == 0
10169 uword
10170 unformat_l4_match (unformat_input_t * input, va_list * args)
10171 {
10172   u8 **matchp = va_arg (*args, u8 **);
10173
10174   u8 *proto_header = 0;
10175   int src_port = 0;
10176   int dst_port = 0;
10177
10178   tcpudp_header_t h;
10179
10180   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10181     {
10182       if (unformat (input, "src_port %d", &src_port))
10183         ;
10184       else if (unformat (input, "dst_port %d", &dst_port))
10185         ;
10186       else
10187         return 0;
10188     }
10189
10190   h.src_port = clib_host_to_net_u16 (src_port);
10191   h.dst_port = clib_host_to_net_u16 (dst_port);
10192   vec_validate (proto_header, sizeof (h) - 1);
10193   memcpy (proto_header, &h, sizeof (h));
10194
10195   *matchp = proto_header;
10196
10197   return 1;
10198 }
10199
10200 uword
10201 unformat_ip4_match (unformat_input_t * input, va_list * args)
10202 {
10203   u8 **matchp = va_arg (*args, u8 **);
10204   u8 *match = 0;
10205   ip4_header_t *ip;
10206   int version = 0;
10207   u32 version_val;
10208   int hdr_length = 0;
10209   u32 hdr_length_val;
10210   int src = 0, dst = 0;
10211   ip4_address_t src_val, dst_val;
10212   int proto = 0;
10213   u32 proto_val;
10214   int tos = 0;
10215   u32 tos_val;
10216   int length = 0;
10217   u32 length_val;
10218   int fragment_id = 0;
10219   u32 fragment_id_val;
10220   int ttl = 0;
10221   int ttl_val;
10222   int checksum = 0;
10223   u32 checksum_val;
10224
10225   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10226     {
10227       if (unformat (input, "version %d", &version_val))
10228         version = 1;
10229       else if (unformat (input, "hdr_length %d", &hdr_length_val))
10230         hdr_length = 1;
10231       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
10232         src = 1;
10233       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
10234         dst = 1;
10235       else if (unformat (input, "proto %d", &proto_val))
10236         proto = 1;
10237       else if (unformat (input, "tos %d", &tos_val))
10238         tos = 1;
10239       else if (unformat (input, "length %d", &length_val))
10240         length = 1;
10241       else if (unformat (input, "fragment_id %d", &fragment_id_val))
10242         fragment_id = 1;
10243       else if (unformat (input, "ttl %d", &ttl_val))
10244         ttl = 1;
10245       else if (unformat (input, "checksum %d", &checksum_val))
10246         checksum = 1;
10247       else
10248         break;
10249     }
10250
10251   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
10252       + ttl + checksum == 0)
10253     return 0;
10254
10255   /*
10256    * Aligned because we use the real comparison functions
10257    */
10258   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
10259
10260   ip = (ip4_header_t *) match;
10261
10262   /* These are realistically matched in practice */
10263   if (src)
10264     ip->src_address.as_u32 = src_val.as_u32;
10265
10266   if (dst)
10267     ip->dst_address.as_u32 = dst_val.as_u32;
10268
10269   if (proto)
10270     ip->protocol = proto_val;
10271
10272
10273   /* These are not, but they're included for completeness */
10274   if (version)
10275     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
10276
10277   if (hdr_length)
10278     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
10279
10280   if (tos)
10281     ip->tos = tos_val;
10282
10283   if (length)
10284     ip->length = clib_host_to_net_u16 (length_val);
10285
10286   if (ttl)
10287     ip->ttl = ttl_val;
10288
10289   if (checksum)
10290     ip->checksum = clib_host_to_net_u16 (checksum_val);
10291
10292   *matchp = match;
10293   return 1;
10294 }
10295
10296 uword
10297 unformat_ip6_match (unformat_input_t * input, va_list * args)
10298 {
10299   u8 **matchp = va_arg (*args, u8 **);
10300   u8 *match = 0;
10301   ip6_header_t *ip;
10302   int version = 0;
10303   u32 version_val;
10304   u8 traffic_class = 0;
10305   u32 traffic_class_val = 0;
10306   u8 flow_label = 0;
10307   u8 flow_label_val;
10308   int src = 0, dst = 0;
10309   ip6_address_t src_val, dst_val;
10310   int proto = 0;
10311   u32 proto_val;
10312   int payload_length = 0;
10313   u32 payload_length_val;
10314   int hop_limit = 0;
10315   int hop_limit_val;
10316   u32 ip_version_traffic_class_and_flow_label;
10317
10318   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10319     {
10320       if (unformat (input, "version %d", &version_val))
10321         version = 1;
10322       else if (unformat (input, "traffic_class %d", &traffic_class_val))
10323         traffic_class = 1;
10324       else if (unformat (input, "flow_label %d", &flow_label_val))
10325         flow_label = 1;
10326       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
10327         src = 1;
10328       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
10329         dst = 1;
10330       else if (unformat (input, "proto %d", &proto_val))
10331         proto = 1;
10332       else if (unformat (input, "payload_length %d", &payload_length_val))
10333         payload_length = 1;
10334       else if (unformat (input, "hop_limit %d", &hop_limit_val))
10335         hop_limit = 1;
10336       else
10337         break;
10338     }
10339
10340   if (version + traffic_class + flow_label + src + dst + proto +
10341       payload_length + hop_limit == 0)
10342     return 0;
10343
10344   /*
10345    * Aligned because we use the real comparison functions
10346    */
10347   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
10348
10349   ip = (ip6_header_t *) match;
10350
10351   if (src)
10352     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
10353
10354   if (dst)
10355     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
10356
10357   if (proto)
10358     ip->protocol = proto_val;
10359
10360   ip_version_traffic_class_and_flow_label = 0;
10361
10362   if (version)
10363     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
10364
10365   if (traffic_class)
10366     ip_version_traffic_class_and_flow_label |=
10367       (traffic_class_val & 0xFF) << 20;
10368
10369   if (flow_label)
10370     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
10371
10372   ip->ip_version_traffic_class_and_flow_label =
10373     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
10374
10375   if (payload_length)
10376     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
10377
10378   if (hop_limit)
10379     ip->hop_limit = hop_limit_val;
10380
10381   *matchp = match;
10382   return 1;
10383 }
10384
10385 uword
10386 unformat_l3_match (unformat_input_t * input, va_list * args)
10387 {
10388   u8 **matchp = va_arg (*args, u8 **);
10389
10390   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10391     {
10392       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
10393         return 1;
10394       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
10395         return 1;
10396       else
10397         break;
10398     }
10399   return 0;
10400 }
10401
10402 uword
10403 unformat_vlan_tag (unformat_input_t * input, va_list * args)
10404 {
10405   u8 *tagp = va_arg (*args, u8 *);
10406   u32 tag;
10407
10408   if (unformat (input, "%d", &tag))
10409     {
10410       tagp[0] = (tag >> 8) & 0x0F;
10411       tagp[1] = tag & 0xFF;
10412       return 1;
10413     }
10414
10415   return 0;
10416 }
10417
10418 uword
10419 unformat_l2_match (unformat_input_t * input, va_list * args)
10420 {
10421   u8 **matchp = va_arg (*args, u8 **);
10422   u8 *match = 0;
10423   u8 src = 0;
10424   u8 src_val[6];
10425   u8 dst = 0;
10426   u8 dst_val[6];
10427   u8 proto = 0;
10428   u16 proto_val;
10429   u8 tag1 = 0;
10430   u8 tag1_val[2];
10431   u8 tag2 = 0;
10432   u8 tag2_val[2];
10433   int len = 14;
10434   u8 ignore_tag1 = 0;
10435   u8 ignore_tag2 = 0;
10436   u8 cos1 = 0;
10437   u8 cos2 = 0;
10438   u32 cos1_val = 0;
10439   u32 cos2_val = 0;
10440
10441   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10442     {
10443       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
10444         src = 1;
10445       else
10446         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
10447         dst = 1;
10448       else if (unformat (input, "proto %U",
10449                          unformat_ethernet_type_host_byte_order, &proto_val))
10450         proto = 1;
10451       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
10452         tag1 = 1;
10453       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
10454         tag2 = 1;
10455       else if (unformat (input, "ignore-tag1"))
10456         ignore_tag1 = 1;
10457       else if (unformat (input, "ignore-tag2"))
10458         ignore_tag2 = 1;
10459       else if (unformat (input, "cos1 %d", &cos1_val))
10460         cos1 = 1;
10461       else if (unformat (input, "cos2 %d", &cos2_val))
10462         cos2 = 1;
10463       else
10464         break;
10465     }
10466   if ((src + dst + proto + tag1 + tag2 +
10467        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
10468     return 0;
10469
10470   if (tag1 || ignore_tag1 || cos1)
10471     len = 18;
10472   if (tag2 || ignore_tag2 || cos2)
10473     len = 22;
10474
10475   vec_validate_aligned (match, len - 1, sizeof (u32x4));
10476
10477   if (dst)
10478     clib_memcpy (match, dst_val, 6);
10479
10480   if (src)
10481     clib_memcpy (match + 6, src_val, 6);
10482
10483   if (tag2)
10484     {
10485       /* inner vlan tag */
10486       match[19] = tag2_val[1];
10487       match[18] = tag2_val[0];
10488       if (cos2)
10489         match[18] |= (cos2_val & 0x7) << 5;
10490       if (proto)
10491         {
10492           match[21] = proto_val & 0xff;
10493           match[20] = proto_val >> 8;
10494         }
10495       if (tag1)
10496         {
10497           match[15] = tag1_val[1];
10498           match[14] = tag1_val[0];
10499         }
10500       if (cos1)
10501         match[14] |= (cos1_val & 0x7) << 5;
10502       *matchp = match;
10503       return 1;
10504     }
10505   if (tag1)
10506     {
10507       match[15] = tag1_val[1];
10508       match[14] = tag1_val[0];
10509       if (proto)
10510         {
10511           match[17] = proto_val & 0xff;
10512           match[16] = proto_val >> 8;
10513         }
10514       if (cos1)
10515         match[14] |= (cos1_val & 0x7) << 5;
10516
10517       *matchp = match;
10518       return 1;
10519     }
10520   if (cos2)
10521     match[18] |= (cos2_val & 0x7) << 5;
10522   if (cos1)
10523     match[14] |= (cos1_val & 0x7) << 5;
10524   if (proto)
10525     {
10526       match[13] = proto_val & 0xff;
10527       match[12] = proto_val >> 8;
10528     }
10529
10530   *matchp = match;
10531   return 1;
10532 }
10533 #endif
10534
10535 uword
10536 api_unformat_classify_match (unformat_input_t * input, va_list * args)
10537 {
10538   u8 **matchp = va_arg (*args, u8 **);
10539   u32 skip_n_vectors = va_arg (*args, u32);
10540   u32 match_n_vectors = va_arg (*args, u32);
10541
10542   u8 *match = 0;
10543   u8 *l2 = 0;
10544   u8 *l3 = 0;
10545   u8 *l4 = 0;
10546
10547   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10548     {
10549       if (unformat (input, "hex %U", unformat_hex_string, &match))
10550         ;
10551       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
10552         ;
10553       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
10554         ;
10555       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
10556         ;
10557       else
10558         break;
10559     }
10560
10561   if (l4 && !l3)
10562     {
10563       vec_free (match);
10564       vec_free (l2);
10565       vec_free (l4);
10566       return 0;
10567     }
10568
10569   if (match || l2 || l3 || l4)
10570     {
10571       if (l2 || l3 || l4)
10572         {
10573           /* "Win a free Ethernet header in every packet" */
10574           if (l2 == 0)
10575             vec_validate_aligned (l2, 13, sizeof (u32x4));
10576           match = l2;
10577           if (vec_len (l3))
10578             {
10579               vec_append_aligned (match, l3, sizeof (u32x4));
10580               vec_free (l3);
10581             }
10582           if (vec_len (l4))
10583             {
10584               vec_append_aligned (match, l4, sizeof (u32x4));
10585               vec_free (l4);
10586             }
10587         }
10588
10589       /* Make sure the vector is big enough even if key is all 0's */
10590       vec_validate_aligned
10591         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
10592          sizeof (u32x4));
10593
10594       /* Set size, include skipped vectors */
10595       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
10596
10597       *matchp = match;
10598
10599       return 1;
10600     }
10601
10602   return 0;
10603 }
10604
10605 static int
10606 api_classify_add_del_session (vat_main_t * vam)
10607 {
10608   unformat_input_t *i = vam->input;
10609   vl_api_classify_add_del_session_t *mp;
10610   int is_add = 1;
10611   u32 table_index = ~0;
10612   u32 hit_next_index = ~0;
10613   u32 opaque_index = ~0;
10614   u8 *match = 0;
10615   i32 advance = 0;
10616   u32 skip_n_vectors = 0;
10617   u32 match_n_vectors = 0;
10618   u32 action = 0;
10619   u32 metadata = 0;
10620   int ret;
10621
10622   /*
10623    * Warning: you have to supply skip_n and match_n
10624    * because the API client cant simply look at the classify
10625    * table object.
10626    */
10627
10628   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10629     {
10630       if (unformat (i, "del"))
10631         is_add = 0;
10632       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
10633                          &hit_next_index))
10634         ;
10635       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
10636                          &hit_next_index))
10637         ;
10638       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
10639                          &hit_next_index))
10640         ;
10641       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
10642         ;
10643       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
10644         ;
10645       else if (unformat (i, "opaque-index %d", &opaque_index))
10646         ;
10647       else if (unformat (i, "skip_n %d", &skip_n_vectors))
10648         ;
10649       else if (unformat (i, "match_n %d", &match_n_vectors))
10650         ;
10651       else if (unformat (i, "match %U", api_unformat_classify_match,
10652                          &match, skip_n_vectors, match_n_vectors))
10653         ;
10654       else if (unformat (i, "advance %d", &advance))
10655         ;
10656       else if (unformat (i, "table-index %d", &table_index))
10657         ;
10658       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
10659         action = 1;
10660       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
10661         action = 2;
10662       else if (unformat (i, "action %d", &action))
10663         ;
10664       else if (unformat (i, "metadata %d", &metadata))
10665         ;
10666       else
10667         break;
10668     }
10669
10670   if (table_index == ~0)
10671     {
10672       errmsg ("Table index required");
10673       return -99;
10674     }
10675
10676   if (is_add && match == 0)
10677     {
10678       errmsg ("Match value required");
10679       return -99;
10680     }
10681
10682   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
10683
10684   mp->is_add = is_add;
10685   mp->table_index = ntohl (table_index);
10686   mp->hit_next_index = ntohl (hit_next_index);
10687   mp->opaque_index = ntohl (opaque_index);
10688   mp->advance = ntohl (advance);
10689   mp->action = action;
10690   mp->metadata = ntohl (metadata);
10691   clib_memcpy (mp->match, match, vec_len (match));
10692   vec_free (match);
10693
10694   S (mp);
10695   W (ret);
10696   return ret;
10697 }
10698
10699 static int
10700 api_classify_set_interface_ip_table (vat_main_t * vam)
10701 {
10702   unformat_input_t *i = vam->input;
10703   vl_api_classify_set_interface_ip_table_t *mp;
10704   u32 sw_if_index;
10705   int sw_if_index_set;
10706   u32 table_index = ~0;
10707   u8 is_ipv6 = 0;
10708   int ret;
10709
10710   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10711     {
10712       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10713         sw_if_index_set = 1;
10714       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10715         sw_if_index_set = 1;
10716       else if (unformat (i, "table %d", &table_index))
10717         ;
10718       else
10719         {
10720           clib_warning ("parse error '%U'", format_unformat_error, i);
10721           return -99;
10722         }
10723     }
10724
10725   if (sw_if_index_set == 0)
10726     {
10727       errmsg ("missing interface name or sw_if_index");
10728       return -99;
10729     }
10730
10731
10732   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
10733
10734   mp->sw_if_index = ntohl (sw_if_index);
10735   mp->table_index = ntohl (table_index);
10736   mp->is_ipv6 = is_ipv6;
10737
10738   S (mp);
10739   W (ret);
10740   return ret;
10741 }
10742
10743 static int
10744 api_classify_set_interface_l2_tables (vat_main_t * vam)
10745 {
10746   unformat_input_t *i = vam->input;
10747   vl_api_classify_set_interface_l2_tables_t *mp;
10748   u32 sw_if_index;
10749   int sw_if_index_set;
10750   u32 ip4_table_index = ~0;
10751   u32 ip6_table_index = ~0;
10752   u32 other_table_index = ~0;
10753   u32 is_input = 1;
10754   int ret;
10755
10756   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10757     {
10758       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10759         sw_if_index_set = 1;
10760       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10761         sw_if_index_set = 1;
10762       else if (unformat (i, "ip4-table %d", &ip4_table_index))
10763         ;
10764       else if (unformat (i, "ip6-table %d", &ip6_table_index))
10765         ;
10766       else if (unformat (i, "other-table %d", &other_table_index))
10767         ;
10768       else if (unformat (i, "is-input %d", &is_input))
10769         ;
10770       else
10771         {
10772           clib_warning ("parse error '%U'", format_unformat_error, i);
10773           return -99;
10774         }
10775     }
10776
10777   if (sw_if_index_set == 0)
10778     {
10779       errmsg ("missing interface name or sw_if_index");
10780       return -99;
10781     }
10782
10783
10784   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
10785
10786   mp->sw_if_index = ntohl (sw_if_index);
10787   mp->ip4_table_index = ntohl (ip4_table_index);
10788   mp->ip6_table_index = ntohl (ip6_table_index);
10789   mp->other_table_index = ntohl (other_table_index);
10790   mp->is_input = (u8) is_input;
10791
10792   S (mp);
10793   W (ret);
10794   return ret;
10795 }
10796
10797 static int
10798 api_set_ipfix_exporter (vat_main_t * vam)
10799 {
10800   unformat_input_t *i = vam->input;
10801   vl_api_set_ipfix_exporter_t *mp;
10802   ip4_address_t collector_address;
10803   u8 collector_address_set = 0;
10804   u32 collector_port = ~0;
10805   ip4_address_t src_address;
10806   u8 src_address_set = 0;
10807   u32 vrf_id = ~0;
10808   u32 path_mtu = ~0;
10809   u32 template_interval = ~0;
10810   u8 udp_checksum = 0;
10811   int ret;
10812
10813   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10814     {
10815       if (unformat (i, "collector_address %U", unformat_ip4_address,
10816                     &collector_address))
10817         collector_address_set = 1;
10818       else if (unformat (i, "collector_port %d", &collector_port))
10819         ;
10820       else if (unformat (i, "src_address %U", unformat_ip4_address,
10821                          &src_address))
10822         src_address_set = 1;
10823       else if (unformat (i, "vrf_id %d", &vrf_id))
10824         ;
10825       else if (unformat (i, "path_mtu %d", &path_mtu))
10826         ;
10827       else if (unformat (i, "template_interval %d", &template_interval))
10828         ;
10829       else if (unformat (i, "udp_checksum"))
10830         udp_checksum = 1;
10831       else
10832         break;
10833     }
10834
10835   if (collector_address_set == 0)
10836     {
10837       errmsg ("collector_address required");
10838       return -99;
10839     }
10840
10841   if (src_address_set == 0)
10842     {
10843       errmsg ("src_address required");
10844       return -99;
10845     }
10846
10847   M (SET_IPFIX_EXPORTER, mp);
10848
10849   memcpy (mp->collector_address, collector_address.data,
10850           sizeof (collector_address.data));
10851   mp->collector_port = htons ((u16) collector_port);
10852   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
10853   mp->vrf_id = htonl (vrf_id);
10854   mp->path_mtu = htonl (path_mtu);
10855   mp->template_interval = htonl (template_interval);
10856   mp->udp_checksum = udp_checksum;
10857
10858   S (mp);
10859   W (ret);
10860   return ret;
10861 }
10862
10863 static int
10864 api_set_ipfix_classify_stream (vat_main_t * vam)
10865 {
10866   unformat_input_t *i = vam->input;
10867   vl_api_set_ipfix_classify_stream_t *mp;
10868   u32 domain_id = 0;
10869   u32 src_port = UDP_DST_PORT_ipfix;
10870   int ret;
10871
10872   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10873     {
10874       if (unformat (i, "domain %d", &domain_id))
10875         ;
10876       else if (unformat (i, "src_port %d", &src_port))
10877         ;
10878       else
10879         {
10880           errmsg ("unknown input `%U'", format_unformat_error, i);
10881           return -99;
10882         }
10883     }
10884
10885   M (SET_IPFIX_CLASSIFY_STREAM, mp);
10886
10887   mp->domain_id = htonl (domain_id);
10888   mp->src_port = htons ((u16) src_port);
10889
10890   S (mp);
10891   W (ret);
10892   return ret;
10893 }
10894
10895 static int
10896 api_ipfix_classify_table_add_del (vat_main_t * vam)
10897 {
10898   unformat_input_t *i = vam->input;
10899   vl_api_ipfix_classify_table_add_del_t *mp;
10900   int is_add = -1;
10901   u32 classify_table_index = ~0;
10902   u8 ip_version = 0;
10903   u8 transport_protocol = 255;
10904   int ret;
10905
10906   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10907     {
10908       if (unformat (i, "add"))
10909         is_add = 1;
10910       else if (unformat (i, "del"))
10911         is_add = 0;
10912       else if (unformat (i, "table %d", &classify_table_index))
10913         ;
10914       else if (unformat (i, "ip4"))
10915         ip_version = 4;
10916       else if (unformat (i, "ip6"))
10917         ip_version = 6;
10918       else if (unformat (i, "tcp"))
10919         transport_protocol = 6;
10920       else if (unformat (i, "udp"))
10921         transport_protocol = 17;
10922       else
10923         {
10924           errmsg ("unknown input `%U'", format_unformat_error, i);
10925           return -99;
10926         }
10927     }
10928
10929   if (is_add == -1)
10930     {
10931       errmsg ("expecting: add|del");
10932       return -99;
10933     }
10934   if (classify_table_index == ~0)
10935     {
10936       errmsg ("classifier table not specified");
10937       return -99;
10938     }
10939   if (ip_version == 0)
10940     {
10941       errmsg ("IP version not specified");
10942       return -99;
10943     }
10944
10945   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
10946
10947   mp->is_add = is_add;
10948   mp->table_id = htonl (classify_table_index);
10949   mp->ip_version = ip_version;
10950   mp->transport_protocol = transport_protocol;
10951
10952   S (mp);
10953   W (ret);
10954   return ret;
10955 }
10956
10957 static int
10958 api_get_node_index (vat_main_t * vam)
10959 {
10960   unformat_input_t *i = vam->input;
10961   vl_api_get_node_index_t *mp;
10962   u8 *name = 0;
10963   int ret;
10964
10965   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10966     {
10967       if (unformat (i, "node %s", &name))
10968         ;
10969       else
10970         break;
10971     }
10972   if (name == 0)
10973     {
10974       errmsg ("node name required");
10975       return -99;
10976     }
10977   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
10978     {
10979       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10980       return -99;
10981     }
10982
10983   M (GET_NODE_INDEX, mp);
10984   clib_memcpy (mp->node_name, name, vec_len (name));
10985   vec_free (name);
10986
10987   S (mp);
10988   W (ret);
10989   return ret;
10990 }
10991
10992 static int
10993 api_get_next_index (vat_main_t * vam)
10994 {
10995   unformat_input_t *i = vam->input;
10996   vl_api_get_next_index_t *mp;
10997   u8 *node_name = 0, *next_node_name = 0;
10998   int ret;
10999
11000   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11001     {
11002       if (unformat (i, "node-name %s", &node_name))
11003         ;
11004       else if (unformat (i, "next-node-name %s", &next_node_name))
11005         break;
11006     }
11007
11008   if (node_name == 0)
11009     {
11010       errmsg ("node name required");
11011       return -99;
11012     }
11013   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
11014     {
11015       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11016       return -99;
11017     }
11018
11019   if (next_node_name == 0)
11020     {
11021       errmsg ("next node name required");
11022       return -99;
11023     }
11024   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
11025     {
11026       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
11027       return -99;
11028     }
11029
11030   M (GET_NEXT_INDEX, mp);
11031   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
11032   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
11033   vec_free (node_name);
11034   vec_free (next_node_name);
11035
11036   S (mp);
11037   W (ret);
11038   return ret;
11039 }
11040
11041 static int
11042 api_add_node_next (vat_main_t * vam)
11043 {
11044   unformat_input_t *i = vam->input;
11045   vl_api_add_node_next_t *mp;
11046   u8 *name = 0;
11047   u8 *next = 0;
11048   int ret;
11049
11050   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11051     {
11052       if (unformat (i, "node %s", &name))
11053         ;
11054       else if (unformat (i, "next %s", &next))
11055         ;
11056       else
11057         break;
11058     }
11059   if (name == 0)
11060     {
11061       errmsg ("node name required");
11062       return -99;
11063     }
11064   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
11065     {
11066       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11067       return -99;
11068     }
11069   if (next == 0)
11070     {
11071       errmsg ("next node required");
11072       return -99;
11073     }
11074   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
11075     {
11076       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
11077       return -99;
11078     }
11079
11080   M (ADD_NODE_NEXT, mp);
11081   clib_memcpy (mp->node_name, name, vec_len (name));
11082   clib_memcpy (mp->next_name, next, vec_len (next));
11083   vec_free (name);
11084   vec_free (next);
11085
11086   S (mp);
11087   W (ret);
11088   return ret;
11089 }
11090
11091 static int
11092 api_l2tpv3_create_tunnel (vat_main_t * vam)
11093 {
11094   unformat_input_t *i = vam->input;
11095   ip6_address_t client_address, our_address;
11096   int client_address_set = 0;
11097   int our_address_set = 0;
11098   u32 local_session_id = 0;
11099   u32 remote_session_id = 0;
11100   u64 local_cookie = 0;
11101   u64 remote_cookie = 0;
11102   u8 l2_sublayer_present = 0;
11103   vl_api_l2tpv3_create_tunnel_t *mp;
11104   int ret;
11105
11106   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11107     {
11108       if (unformat (i, "client_address %U", unformat_ip6_address,
11109                     &client_address))
11110         client_address_set = 1;
11111       else if (unformat (i, "our_address %U", unformat_ip6_address,
11112                          &our_address))
11113         our_address_set = 1;
11114       else if (unformat (i, "local_session_id %d", &local_session_id))
11115         ;
11116       else if (unformat (i, "remote_session_id %d", &remote_session_id))
11117         ;
11118       else if (unformat (i, "local_cookie %lld", &local_cookie))
11119         ;
11120       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
11121         ;
11122       else if (unformat (i, "l2-sublayer-present"))
11123         l2_sublayer_present = 1;
11124       else
11125         break;
11126     }
11127
11128   if (client_address_set == 0)
11129     {
11130       errmsg ("client_address required");
11131       return -99;
11132     }
11133
11134   if (our_address_set == 0)
11135     {
11136       errmsg ("our_address required");
11137       return -99;
11138     }
11139
11140   M (L2TPV3_CREATE_TUNNEL, mp);
11141
11142   clib_memcpy (mp->client_address, client_address.as_u8,
11143                sizeof (mp->client_address));
11144
11145   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
11146
11147   mp->local_session_id = ntohl (local_session_id);
11148   mp->remote_session_id = ntohl (remote_session_id);
11149   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
11150   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
11151   mp->l2_sublayer_present = l2_sublayer_present;
11152   mp->is_ipv6 = 1;
11153
11154   S (mp);
11155   W (ret);
11156   return ret;
11157 }
11158
11159 static int
11160 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
11161 {
11162   unformat_input_t *i = vam->input;
11163   u32 sw_if_index;
11164   u8 sw_if_index_set = 0;
11165   u64 new_local_cookie = 0;
11166   u64 new_remote_cookie = 0;
11167   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
11168   int ret;
11169
11170   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11171     {
11172       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11173         sw_if_index_set = 1;
11174       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11175         sw_if_index_set = 1;
11176       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
11177         ;
11178       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
11179         ;
11180       else
11181         break;
11182     }
11183
11184   if (sw_if_index_set == 0)
11185     {
11186       errmsg ("missing interface name or sw_if_index");
11187       return -99;
11188     }
11189
11190   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
11191
11192   mp->sw_if_index = ntohl (sw_if_index);
11193   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
11194   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
11195
11196   S (mp);
11197   W (ret);
11198   return ret;
11199 }
11200
11201 static int
11202 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
11203 {
11204   unformat_input_t *i = vam->input;
11205   vl_api_l2tpv3_interface_enable_disable_t *mp;
11206   u32 sw_if_index;
11207   u8 sw_if_index_set = 0;
11208   u8 enable_disable = 1;
11209   int ret;
11210
11211   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11212     {
11213       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11214         sw_if_index_set = 1;
11215       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11216         sw_if_index_set = 1;
11217       else if (unformat (i, "enable"))
11218         enable_disable = 1;
11219       else if (unformat (i, "disable"))
11220         enable_disable = 0;
11221       else
11222         break;
11223     }
11224
11225   if (sw_if_index_set == 0)
11226     {
11227       errmsg ("missing interface name or sw_if_index");
11228       return -99;
11229     }
11230
11231   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
11232
11233   mp->sw_if_index = ntohl (sw_if_index);
11234   mp->enable_disable = enable_disable;
11235
11236   S (mp);
11237   W (ret);
11238   return ret;
11239 }
11240
11241 static int
11242 api_l2tpv3_set_lookup_key (vat_main_t * vam)
11243 {
11244   unformat_input_t *i = vam->input;
11245   vl_api_l2tpv3_set_lookup_key_t *mp;
11246   u8 key = ~0;
11247   int ret;
11248
11249   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11250     {
11251       if (unformat (i, "lookup_v6_src"))
11252         key = L2T_LOOKUP_SRC_ADDRESS;
11253       else if (unformat (i, "lookup_v6_dst"))
11254         key = L2T_LOOKUP_DST_ADDRESS;
11255       else if (unformat (i, "lookup_session_id"))
11256         key = L2T_LOOKUP_SESSION_ID;
11257       else
11258         break;
11259     }
11260
11261   if (key == (u8) ~ 0)
11262     {
11263       errmsg ("l2tp session lookup key unset");
11264       return -99;
11265     }
11266
11267   M (L2TPV3_SET_LOOKUP_KEY, mp);
11268
11269   mp->key = key;
11270
11271   S (mp);
11272   W (ret);
11273   return ret;
11274 }
11275
11276 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
11277   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
11278 {
11279   vat_main_t *vam = &vat_main;
11280
11281   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
11282          format_ip6_address, mp->our_address,
11283          format_ip6_address, mp->client_address,
11284          clib_net_to_host_u32 (mp->sw_if_index));
11285
11286   print (vam->ofp,
11287          "   local cookies %016llx %016llx remote cookie %016llx",
11288          clib_net_to_host_u64 (mp->local_cookie[0]),
11289          clib_net_to_host_u64 (mp->local_cookie[1]),
11290          clib_net_to_host_u64 (mp->remote_cookie));
11291
11292   print (vam->ofp, "   local session-id %d remote session-id %d",
11293          clib_net_to_host_u32 (mp->local_session_id),
11294          clib_net_to_host_u32 (mp->remote_session_id));
11295
11296   print (vam->ofp, "   l2 specific sublayer %s\n",
11297          mp->l2_sublayer_present ? "preset" : "absent");
11298
11299 }
11300
11301 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
11302   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
11303 {
11304   vat_main_t *vam = &vat_main;
11305   vat_json_node_t *node = NULL;
11306   struct in6_addr addr;
11307
11308   if (VAT_JSON_ARRAY != vam->json_tree.type)
11309     {
11310       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11311       vat_json_init_array (&vam->json_tree);
11312     }
11313   node = vat_json_array_add (&vam->json_tree);
11314
11315   vat_json_init_object (node);
11316
11317   clib_memcpy (&addr, mp->our_address, sizeof (addr));
11318   vat_json_object_add_ip6 (node, "our_address", addr);
11319   clib_memcpy (&addr, mp->client_address, sizeof (addr));
11320   vat_json_object_add_ip6 (node, "client_address", addr);
11321
11322   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
11323   vat_json_init_array (lc);
11324   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
11325   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
11326   vat_json_object_add_uint (node, "remote_cookie",
11327                             clib_net_to_host_u64 (mp->remote_cookie));
11328
11329   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
11330   vat_json_object_add_uint (node, "local_session_id",
11331                             clib_net_to_host_u32 (mp->local_session_id));
11332   vat_json_object_add_uint (node, "remote_session_id",
11333                             clib_net_to_host_u32 (mp->remote_session_id));
11334   vat_json_object_add_string_copy (node, "l2_sublayer",
11335                                    mp->l2_sublayer_present ? (u8 *) "present"
11336                                    : (u8 *) "absent");
11337 }
11338
11339 static int
11340 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
11341 {
11342   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
11343   vl_api_control_ping_t *mp_ping;
11344   int ret;
11345
11346   /* Get list of l2tpv3-tunnel interfaces */
11347   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
11348   S (mp);
11349
11350   /* Use a control ping for synchronization */
11351   M (CONTROL_PING, mp_ping);
11352   S (mp_ping);
11353
11354   W (ret);
11355   return ret;
11356 }
11357
11358
11359 static void vl_api_sw_interface_tap_details_t_handler
11360   (vl_api_sw_interface_tap_details_t * mp)
11361 {
11362   vat_main_t *vam = &vat_main;
11363
11364   print (vam->ofp, "%-16s %d",
11365          mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
11366 }
11367
11368 static void vl_api_sw_interface_tap_details_t_handler_json
11369   (vl_api_sw_interface_tap_details_t * mp)
11370 {
11371   vat_main_t *vam = &vat_main;
11372   vat_json_node_t *node = NULL;
11373
11374   if (VAT_JSON_ARRAY != vam->json_tree.type)
11375     {
11376       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11377       vat_json_init_array (&vam->json_tree);
11378     }
11379   node = vat_json_array_add (&vam->json_tree);
11380
11381   vat_json_init_object (node);
11382   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11383   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
11384 }
11385
11386 static int
11387 api_sw_interface_tap_dump (vat_main_t * vam)
11388 {
11389   vl_api_sw_interface_tap_dump_t *mp;
11390   vl_api_control_ping_t *mp_ping;
11391   int ret;
11392
11393   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
11394   /* Get list of tap interfaces */
11395   M (SW_INTERFACE_TAP_DUMP, mp);
11396   S (mp);
11397
11398   /* Use a control ping for synchronization */
11399   M (CONTROL_PING, mp_ping);
11400   S (mp_ping);
11401
11402   W (ret);
11403   return ret;
11404 }
11405
11406 static uword unformat_vxlan_decap_next
11407   (unformat_input_t * input, va_list * args)
11408 {
11409   u32 *result = va_arg (*args, u32 *);
11410   u32 tmp;
11411
11412   if (unformat (input, "l2"))
11413     *result = VXLAN_INPUT_NEXT_L2_INPUT;
11414   else if (unformat (input, "%d", &tmp))
11415     *result = tmp;
11416   else
11417     return 0;
11418   return 1;
11419 }
11420
11421 static int
11422 api_vxlan_add_del_tunnel (vat_main_t * vam)
11423 {
11424   unformat_input_t *line_input = vam->input;
11425   vl_api_vxlan_add_del_tunnel_t *mp;
11426   ip46_address_t src, dst;
11427   u8 is_add = 1;
11428   u8 ipv4_set = 0, ipv6_set = 0;
11429   u8 src_set = 0;
11430   u8 dst_set = 0;
11431   u8 grp_set = 0;
11432   u32 mcast_sw_if_index = ~0;
11433   u32 encap_vrf_id = 0;
11434   u32 decap_next_index = ~0;
11435   u32 vni = 0;
11436   int ret;
11437
11438   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
11439   memset (&src, 0, sizeof src);
11440   memset (&dst, 0, sizeof dst);
11441
11442   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11443     {
11444       if (unformat (line_input, "del"))
11445         is_add = 0;
11446       else
11447         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
11448         {
11449           ipv4_set = 1;
11450           src_set = 1;
11451         }
11452       else
11453         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
11454         {
11455           ipv4_set = 1;
11456           dst_set = 1;
11457         }
11458       else
11459         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
11460         {
11461           ipv6_set = 1;
11462           src_set = 1;
11463         }
11464       else
11465         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
11466         {
11467           ipv6_set = 1;
11468           dst_set = 1;
11469         }
11470       else if (unformat (line_input, "group %U %U",
11471                          unformat_ip4_address, &dst.ip4,
11472                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11473         {
11474           grp_set = dst_set = 1;
11475           ipv4_set = 1;
11476         }
11477       else if (unformat (line_input, "group %U",
11478                          unformat_ip4_address, &dst.ip4))
11479         {
11480           grp_set = dst_set = 1;
11481           ipv4_set = 1;
11482         }
11483       else if (unformat (line_input, "group %U %U",
11484                          unformat_ip6_address, &dst.ip6,
11485                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11486         {
11487           grp_set = dst_set = 1;
11488           ipv6_set = 1;
11489         }
11490       else if (unformat (line_input, "group %U",
11491                          unformat_ip6_address, &dst.ip6))
11492         {
11493           grp_set = dst_set = 1;
11494           ipv6_set = 1;
11495         }
11496       else
11497         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
11498         ;
11499       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
11500         ;
11501       else if (unformat (line_input, "decap-next %U",
11502                          unformat_vxlan_decap_next, &decap_next_index))
11503         ;
11504       else if (unformat (line_input, "vni %d", &vni))
11505         ;
11506       else
11507         {
11508           errmsg ("parse error '%U'", format_unformat_error, line_input);
11509           return -99;
11510         }
11511     }
11512
11513   if (src_set == 0)
11514     {
11515       errmsg ("tunnel src address not specified");
11516       return -99;
11517     }
11518   if (dst_set == 0)
11519     {
11520       errmsg ("tunnel dst address not specified");
11521       return -99;
11522     }
11523
11524   if (grp_set && !ip46_address_is_multicast (&dst))
11525     {
11526       errmsg ("tunnel group address not multicast");
11527       return -99;
11528     }
11529   if (grp_set && mcast_sw_if_index == ~0)
11530     {
11531       errmsg ("tunnel nonexistent multicast device");
11532       return -99;
11533     }
11534   if (grp_set == 0 && ip46_address_is_multicast (&dst))
11535     {
11536       errmsg ("tunnel dst address must be unicast");
11537       return -99;
11538     }
11539
11540
11541   if (ipv4_set && ipv6_set)
11542     {
11543       errmsg ("both IPv4 and IPv6 addresses specified");
11544       return -99;
11545     }
11546
11547   if ((vni == 0) || (vni >> 24))
11548     {
11549       errmsg ("vni not specified or out of range");
11550       return -99;
11551     }
11552
11553   M (VXLAN_ADD_DEL_TUNNEL, mp);
11554
11555   if (ipv6_set)
11556     {
11557       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
11558       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
11559     }
11560   else
11561     {
11562       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
11563       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
11564     }
11565   mp->encap_vrf_id = ntohl (encap_vrf_id);
11566   mp->decap_next_index = ntohl (decap_next_index);
11567   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
11568   mp->vni = ntohl (vni);
11569   mp->is_add = is_add;
11570   mp->is_ipv6 = ipv6_set;
11571
11572   S (mp);
11573   W (ret);
11574   return ret;
11575 }
11576
11577 static void vl_api_vxlan_tunnel_details_t_handler
11578   (vl_api_vxlan_tunnel_details_t * mp)
11579 {
11580   vat_main_t *vam = &vat_main;
11581   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
11582   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
11583
11584   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
11585          ntohl (mp->sw_if_index),
11586          format_ip46_address, &src, IP46_TYPE_ANY,
11587          format_ip46_address, &dst, IP46_TYPE_ANY,
11588          ntohl (mp->encap_vrf_id),
11589          ntohl (mp->decap_next_index), ntohl (mp->vni),
11590          ntohl (mp->mcast_sw_if_index));
11591 }
11592
11593 static void vl_api_vxlan_tunnel_details_t_handler_json
11594   (vl_api_vxlan_tunnel_details_t * mp)
11595 {
11596   vat_main_t *vam = &vat_main;
11597   vat_json_node_t *node = NULL;
11598
11599   if (VAT_JSON_ARRAY != vam->json_tree.type)
11600     {
11601       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11602       vat_json_init_array (&vam->json_tree);
11603     }
11604   node = vat_json_array_add (&vam->json_tree);
11605
11606   vat_json_init_object (node);
11607   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11608   if (mp->is_ipv6)
11609     {
11610       struct in6_addr ip6;
11611
11612       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
11613       vat_json_object_add_ip6 (node, "src_address", ip6);
11614       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
11615       vat_json_object_add_ip6 (node, "dst_address", ip6);
11616     }
11617   else
11618     {
11619       struct in_addr ip4;
11620
11621       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
11622       vat_json_object_add_ip4 (node, "src_address", ip4);
11623       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
11624       vat_json_object_add_ip4 (node, "dst_address", ip4);
11625     }
11626   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
11627   vat_json_object_add_uint (node, "decap_next_index",
11628                             ntohl (mp->decap_next_index));
11629   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
11630   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
11631   vat_json_object_add_uint (node, "mcast_sw_if_index",
11632                             ntohl (mp->mcast_sw_if_index));
11633 }
11634
11635 static int
11636 api_vxlan_tunnel_dump (vat_main_t * vam)
11637 {
11638   unformat_input_t *i = vam->input;
11639   vl_api_vxlan_tunnel_dump_t *mp;
11640   vl_api_control_ping_t *mp_ping;
11641   u32 sw_if_index;
11642   u8 sw_if_index_set = 0;
11643   int ret;
11644
11645   /* Parse args required to build the message */
11646   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11647     {
11648       if (unformat (i, "sw_if_index %d", &sw_if_index))
11649         sw_if_index_set = 1;
11650       else
11651         break;
11652     }
11653
11654   if (sw_if_index_set == 0)
11655     {
11656       sw_if_index = ~0;
11657     }
11658
11659   if (!vam->json_output)
11660     {
11661       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
11662              "sw_if_index", "src_address", "dst_address",
11663              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
11664     }
11665
11666   /* Get list of vxlan-tunnel interfaces */
11667   M (VXLAN_TUNNEL_DUMP, mp);
11668
11669   mp->sw_if_index = htonl (sw_if_index);
11670
11671   S (mp);
11672
11673   /* Use a control ping for synchronization */
11674   M (CONTROL_PING, mp_ping);
11675   S (mp_ping);
11676
11677   W (ret);
11678   return ret;
11679 }
11680
11681 static int
11682 api_gre_add_del_tunnel (vat_main_t * vam)
11683 {
11684   unformat_input_t *line_input = vam->input;
11685   vl_api_gre_add_del_tunnel_t *mp;
11686   ip4_address_t src4, dst4;
11687   ip6_address_t src6, dst6;
11688   u8 is_add = 1;
11689   u8 ipv4_set = 0;
11690   u8 ipv6_set = 0;
11691   u8 teb = 0;
11692   u8 src_set = 0;
11693   u8 dst_set = 0;
11694   u32 outer_fib_id = 0;
11695   int ret;
11696
11697   memset (&src4, 0, sizeof src4);
11698   memset (&dst4, 0, sizeof dst4);
11699   memset (&src6, 0, sizeof src6);
11700   memset (&dst6, 0, sizeof dst6);
11701
11702   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11703     {
11704       if (unformat (line_input, "del"))
11705         is_add = 0;
11706       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
11707         {
11708           src_set = 1;
11709           ipv4_set = 1;
11710         }
11711       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
11712         {
11713           dst_set = 1;
11714           ipv4_set = 1;
11715         }
11716       else if (unformat (line_input, "src %U", unformat_ip6_address, &src6))
11717         {
11718           src_set = 1;
11719           ipv6_set = 1;
11720         }
11721       else if (unformat (line_input, "dst %U", unformat_ip6_address, &dst6))
11722         {
11723           dst_set = 1;
11724           ipv6_set = 1;
11725         }
11726       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
11727         ;
11728       else if (unformat (line_input, "teb"))
11729         teb = 1;
11730       else
11731         {
11732           errmsg ("parse error '%U'", format_unformat_error, line_input);
11733           return -99;
11734         }
11735     }
11736
11737   if (src_set == 0)
11738     {
11739       errmsg ("tunnel src address not specified");
11740       return -99;
11741     }
11742   if (dst_set == 0)
11743     {
11744       errmsg ("tunnel dst address not specified");
11745       return -99;
11746     }
11747   if (ipv4_set && ipv6_set)
11748     {
11749       errmsg ("both IPv4 and IPv6 addresses specified");
11750       return -99;
11751     }
11752
11753
11754   M (GRE_ADD_DEL_TUNNEL, mp);
11755
11756   if (ipv4_set)
11757     {
11758       clib_memcpy (&mp->src_address, &src4, 4);
11759       clib_memcpy (&mp->dst_address, &dst4, 4);
11760     }
11761   else
11762     {
11763       clib_memcpy (&mp->src_address, &src6, 16);
11764       clib_memcpy (&mp->dst_address, &dst6, 16);
11765     }
11766   mp->outer_fib_id = ntohl (outer_fib_id);
11767   mp->is_add = is_add;
11768   mp->teb = teb;
11769   mp->is_ipv6 = ipv6_set;
11770
11771   S (mp);
11772   W (ret);
11773   return ret;
11774 }
11775
11776 static void vl_api_gre_tunnel_details_t_handler
11777   (vl_api_gre_tunnel_details_t * mp)
11778 {
11779   vat_main_t *vam = &vat_main;
11780   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->src_address);
11781   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->dst_address);
11782
11783   print (vam->ofp, "%11d%24U%24U%6d%14d",
11784          ntohl (mp->sw_if_index),
11785          format_ip46_address, &src, IP46_TYPE_ANY,
11786          format_ip46_address, &dst, IP46_TYPE_ANY,
11787          mp->teb, ntohl (mp->outer_fib_id));
11788 }
11789
11790 static void vl_api_gre_tunnel_details_t_handler_json
11791   (vl_api_gre_tunnel_details_t * mp)
11792 {
11793   vat_main_t *vam = &vat_main;
11794   vat_json_node_t *node = NULL;
11795   struct in_addr ip4;
11796   struct in6_addr ip6;
11797
11798   if (VAT_JSON_ARRAY != vam->json_tree.type)
11799     {
11800       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11801       vat_json_init_array (&vam->json_tree);
11802     }
11803   node = vat_json_array_add (&vam->json_tree);
11804
11805   vat_json_init_object (node);
11806   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11807   if (!mp->is_ipv6)
11808     {
11809       clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
11810       vat_json_object_add_ip4 (node, "src_address", ip4);
11811       clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
11812       vat_json_object_add_ip4 (node, "dst_address", ip4);
11813     }
11814   else
11815     {
11816       clib_memcpy (&ip6, &mp->src_address, sizeof (ip6));
11817       vat_json_object_add_ip6 (node, "src_address", ip6);
11818       clib_memcpy (&ip6, &mp->dst_address, sizeof (ip6));
11819       vat_json_object_add_ip6 (node, "dst_address", ip6);
11820     }
11821   vat_json_object_add_uint (node, "teb", mp->teb);
11822   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
11823   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6);
11824 }
11825
11826 static int
11827 api_gre_tunnel_dump (vat_main_t * vam)
11828 {
11829   unformat_input_t *i = vam->input;
11830   vl_api_gre_tunnel_dump_t *mp;
11831   vl_api_control_ping_t *mp_ping;
11832   u32 sw_if_index;
11833   u8 sw_if_index_set = 0;
11834   int ret;
11835
11836   /* Parse args required to build the message */
11837   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11838     {
11839       if (unformat (i, "sw_if_index %d", &sw_if_index))
11840         sw_if_index_set = 1;
11841       else
11842         break;
11843     }
11844
11845   if (sw_if_index_set == 0)
11846     {
11847       sw_if_index = ~0;
11848     }
11849
11850   if (!vam->json_output)
11851     {
11852       print (vam->ofp, "%11s%24s%24s%6s%14s",
11853              "sw_if_index", "src_address", "dst_address", "teb",
11854              "outer_fib_id");
11855     }
11856
11857   /* Get list of gre-tunnel interfaces */
11858   M (GRE_TUNNEL_DUMP, mp);
11859
11860   mp->sw_if_index = htonl (sw_if_index);
11861
11862   S (mp);
11863
11864   /* Use a control ping for synchronization */
11865   M (CONTROL_PING, mp_ping);
11866   S (mp_ping);
11867
11868   W (ret);
11869   return ret;
11870 }
11871
11872 static int
11873 api_l2_fib_clear_table (vat_main_t * vam)
11874 {
11875 //  unformat_input_t * i = vam->input;
11876   vl_api_l2_fib_clear_table_t *mp;
11877   int ret;
11878
11879   M (L2_FIB_CLEAR_TABLE, mp);
11880
11881   S (mp);
11882   W (ret);
11883   return ret;
11884 }
11885
11886 static int
11887 api_l2_interface_efp_filter (vat_main_t * vam)
11888 {
11889   unformat_input_t *i = vam->input;
11890   vl_api_l2_interface_efp_filter_t *mp;
11891   u32 sw_if_index;
11892   u8 enable = 1;
11893   u8 sw_if_index_set = 0;
11894   int ret;
11895
11896   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11897     {
11898       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11899         sw_if_index_set = 1;
11900       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11901         sw_if_index_set = 1;
11902       else if (unformat (i, "enable"))
11903         enable = 1;
11904       else if (unformat (i, "disable"))
11905         enable = 0;
11906       else
11907         {
11908           clib_warning ("parse error '%U'", format_unformat_error, i);
11909           return -99;
11910         }
11911     }
11912
11913   if (sw_if_index_set == 0)
11914     {
11915       errmsg ("missing sw_if_index");
11916       return -99;
11917     }
11918
11919   M (L2_INTERFACE_EFP_FILTER, mp);
11920
11921   mp->sw_if_index = ntohl (sw_if_index);
11922   mp->enable_disable = enable;
11923
11924   S (mp);
11925   W (ret);
11926   return ret;
11927 }
11928
11929 #define foreach_vtr_op                          \
11930 _("disable",  L2_VTR_DISABLED)                  \
11931 _("push-1",  L2_VTR_PUSH_1)                     \
11932 _("push-2",  L2_VTR_PUSH_2)                     \
11933 _("pop-1",  L2_VTR_POP_1)                       \
11934 _("pop-2",  L2_VTR_POP_2)                       \
11935 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
11936 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
11937 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
11938 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
11939
11940 static int
11941 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
11942 {
11943   unformat_input_t *i = vam->input;
11944   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
11945   u32 sw_if_index;
11946   u8 sw_if_index_set = 0;
11947   u8 vtr_op_set = 0;
11948   u32 vtr_op = 0;
11949   u32 push_dot1q = 1;
11950   u32 tag1 = ~0;
11951   u32 tag2 = ~0;
11952   int ret;
11953
11954   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11955     {
11956       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11957         sw_if_index_set = 1;
11958       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11959         sw_if_index_set = 1;
11960       else if (unformat (i, "vtr_op %d", &vtr_op))
11961         vtr_op_set = 1;
11962 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
11963       foreach_vtr_op
11964 #undef _
11965         else if (unformat (i, "push_dot1q %d", &push_dot1q))
11966         ;
11967       else if (unformat (i, "tag1 %d", &tag1))
11968         ;
11969       else if (unformat (i, "tag2 %d", &tag2))
11970         ;
11971       else
11972         {
11973           clib_warning ("parse error '%U'", format_unformat_error, i);
11974           return -99;
11975         }
11976     }
11977
11978   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
11979     {
11980       errmsg ("missing vtr operation or sw_if_index");
11981       return -99;
11982     }
11983
11984   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
11985   mp->sw_if_index = ntohl (sw_if_index);
11986   mp->vtr_op = ntohl (vtr_op);
11987   mp->push_dot1q = ntohl (push_dot1q);
11988   mp->tag1 = ntohl (tag1);
11989   mp->tag2 = ntohl (tag2);
11990
11991   S (mp);
11992   W (ret);
11993   return ret;
11994 }
11995
11996 static int
11997 api_create_vhost_user_if (vat_main_t * vam)
11998 {
11999   unformat_input_t *i = vam->input;
12000   vl_api_create_vhost_user_if_t *mp;
12001   u8 *file_name;
12002   u8 is_server = 0;
12003   u8 file_name_set = 0;
12004   u32 custom_dev_instance = ~0;
12005   u8 hwaddr[6];
12006   u8 use_custom_mac = 0;
12007   u8 *tag = 0;
12008   int ret;
12009
12010   /* Shut up coverity */
12011   memset (hwaddr, 0, sizeof (hwaddr));
12012
12013   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12014     {
12015       if (unformat (i, "socket %s", &file_name))
12016         {
12017           file_name_set = 1;
12018         }
12019       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
12020         ;
12021       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
12022         use_custom_mac = 1;
12023       else if (unformat (i, "server"))
12024         is_server = 1;
12025       else if (unformat (i, "tag %s", &tag))
12026         ;
12027       else
12028         break;
12029     }
12030
12031   if (file_name_set == 0)
12032     {
12033       errmsg ("missing socket file name");
12034       return -99;
12035     }
12036
12037   if (vec_len (file_name) > 255)
12038     {
12039       errmsg ("socket file name too long");
12040       return -99;
12041     }
12042   vec_add1 (file_name, 0);
12043
12044   M (CREATE_VHOST_USER_IF, mp);
12045
12046   mp->is_server = is_server;
12047   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
12048   vec_free (file_name);
12049   if (custom_dev_instance != ~0)
12050     {
12051       mp->renumber = 1;
12052       mp->custom_dev_instance = ntohl (custom_dev_instance);
12053     }
12054   mp->use_custom_mac = use_custom_mac;
12055   clib_memcpy (mp->mac_address, hwaddr, 6);
12056   if (tag)
12057     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
12058   vec_free (tag);
12059
12060   S (mp);
12061   W (ret);
12062   return ret;
12063 }
12064
12065 static int
12066 api_modify_vhost_user_if (vat_main_t * vam)
12067 {
12068   unformat_input_t *i = vam->input;
12069   vl_api_modify_vhost_user_if_t *mp;
12070   u8 *file_name;
12071   u8 is_server = 0;
12072   u8 file_name_set = 0;
12073   u32 custom_dev_instance = ~0;
12074   u8 sw_if_index_set = 0;
12075   u32 sw_if_index = (u32) ~ 0;
12076   int ret;
12077
12078   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12079     {
12080       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12081         sw_if_index_set = 1;
12082       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12083         sw_if_index_set = 1;
12084       else if (unformat (i, "socket %s", &file_name))
12085         {
12086           file_name_set = 1;
12087         }
12088       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
12089         ;
12090       else if (unformat (i, "server"))
12091         is_server = 1;
12092       else
12093         break;
12094     }
12095
12096   if (sw_if_index_set == 0)
12097     {
12098       errmsg ("missing sw_if_index or interface name");
12099       return -99;
12100     }
12101
12102   if (file_name_set == 0)
12103     {
12104       errmsg ("missing socket file name");
12105       return -99;
12106     }
12107
12108   if (vec_len (file_name) > 255)
12109     {
12110       errmsg ("socket file name too long");
12111       return -99;
12112     }
12113   vec_add1 (file_name, 0);
12114
12115   M (MODIFY_VHOST_USER_IF, mp);
12116
12117   mp->sw_if_index = ntohl (sw_if_index);
12118   mp->is_server = is_server;
12119   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
12120   vec_free (file_name);
12121   if (custom_dev_instance != ~0)
12122     {
12123       mp->renumber = 1;
12124       mp->custom_dev_instance = ntohl (custom_dev_instance);
12125     }
12126
12127   S (mp);
12128   W (ret);
12129   return ret;
12130 }
12131
12132 static int
12133 api_delete_vhost_user_if (vat_main_t * vam)
12134 {
12135   unformat_input_t *i = vam->input;
12136   vl_api_delete_vhost_user_if_t *mp;
12137   u32 sw_if_index = ~0;
12138   u8 sw_if_index_set = 0;
12139   int ret;
12140
12141   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12142     {
12143       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12144         sw_if_index_set = 1;
12145       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12146         sw_if_index_set = 1;
12147       else
12148         break;
12149     }
12150
12151   if (sw_if_index_set == 0)
12152     {
12153       errmsg ("missing sw_if_index or interface name");
12154       return -99;
12155     }
12156
12157
12158   M (DELETE_VHOST_USER_IF, mp);
12159
12160   mp->sw_if_index = ntohl (sw_if_index);
12161
12162   S (mp);
12163   W (ret);
12164   return ret;
12165 }
12166
12167 static void vl_api_sw_interface_vhost_user_details_t_handler
12168   (vl_api_sw_interface_vhost_user_details_t * mp)
12169 {
12170   vat_main_t *vam = &vat_main;
12171
12172   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
12173          (char *) mp->interface_name,
12174          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
12175          clib_net_to_host_u64 (mp->features), mp->is_server,
12176          ntohl (mp->num_regions), (char *) mp->sock_filename);
12177   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
12178 }
12179
12180 static void vl_api_sw_interface_vhost_user_details_t_handler_json
12181   (vl_api_sw_interface_vhost_user_details_t * mp)
12182 {
12183   vat_main_t *vam = &vat_main;
12184   vat_json_node_t *node = NULL;
12185
12186   if (VAT_JSON_ARRAY != vam->json_tree.type)
12187     {
12188       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12189       vat_json_init_array (&vam->json_tree);
12190     }
12191   node = vat_json_array_add (&vam->json_tree);
12192
12193   vat_json_init_object (node);
12194   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12195   vat_json_object_add_string_copy (node, "interface_name",
12196                                    mp->interface_name);
12197   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
12198                             ntohl (mp->virtio_net_hdr_sz));
12199   vat_json_object_add_uint (node, "features",
12200                             clib_net_to_host_u64 (mp->features));
12201   vat_json_object_add_uint (node, "is_server", mp->is_server);
12202   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
12203   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
12204   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
12205 }
12206
12207 static int
12208 api_sw_interface_vhost_user_dump (vat_main_t * vam)
12209 {
12210   vl_api_sw_interface_vhost_user_dump_t *mp;
12211   vl_api_control_ping_t *mp_ping;
12212   int ret;
12213   print (vam->ofp,
12214          "Interface name            idx hdr_sz features server regions filename");
12215
12216   /* Get list of vhost-user interfaces */
12217   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
12218   S (mp);
12219
12220   /* Use a control ping for synchronization */
12221   M (CONTROL_PING, mp_ping);
12222   S (mp_ping);
12223
12224   W (ret);
12225   return ret;
12226 }
12227
12228 static int
12229 api_show_version (vat_main_t * vam)
12230 {
12231   vl_api_show_version_t *mp;
12232   int ret;
12233
12234   M (SHOW_VERSION, mp);
12235
12236   S (mp);
12237   W (ret);
12238   return ret;
12239 }
12240
12241
12242 static int
12243 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
12244 {
12245   unformat_input_t *line_input = vam->input;
12246   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
12247   ip4_address_t local4, remote4;
12248   ip6_address_t local6, remote6;
12249   u8 is_add = 1;
12250   u8 ipv4_set = 0, ipv6_set = 0;
12251   u8 local_set = 0;
12252   u8 remote_set = 0;
12253   u8 grp_set = 0;
12254   u32 mcast_sw_if_index = ~0;
12255   u32 encap_vrf_id = 0;
12256   u32 decap_vrf_id = 0;
12257   u8 protocol = ~0;
12258   u32 vni;
12259   u8 vni_set = 0;
12260   int ret;
12261
12262   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12263   memset (&local4, 0, sizeof local4);
12264   memset (&remote4, 0, sizeof remote4);
12265   memset (&local6, 0, sizeof local6);
12266   memset (&remote6, 0, sizeof remote6);
12267
12268   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12269     {
12270       if (unformat (line_input, "del"))
12271         is_add = 0;
12272       else if (unformat (line_input, "local %U",
12273                          unformat_ip4_address, &local4))
12274         {
12275           local_set = 1;
12276           ipv4_set = 1;
12277         }
12278       else if (unformat (line_input, "remote %U",
12279                          unformat_ip4_address, &remote4))
12280         {
12281           remote_set = 1;
12282           ipv4_set = 1;
12283         }
12284       else if (unformat (line_input, "local %U",
12285                          unformat_ip6_address, &local6))
12286         {
12287           local_set = 1;
12288           ipv6_set = 1;
12289         }
12290       else if (unformat (line_input, "remote %U",
12291                          unformat_ip6_address, &remote6))
12292         {
12293           remote_set = 1;
12294           ipv6_set = 1;
12295         }
12296       else if (unformat (line_input, "group %U %U",
12297                          unformat_ip4_address, &remote4,
12298                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12299         {
12300           grp_set = remote_set = 1;
12301           ipv4_set = 1;
12302         }
12303       else if (unformat (line_input, "group %U",
12304                          unformat_ip4_address, &remote4))
12305         {
12306           grp_set = remote_set = 1;
12307           ipv4_set = 1;
12308         }
12309       else if (unformat (line_input, "group %U %U",
12310                          unformat_ip6_address, &remote6,
12311                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12312         {
12313           grp_set = remote_set = 1;
12314           ipv6_set = 1;
12315         }
12316       else if (unformat (line_input, "group %U",
12317                          unformat_ip6_address, &remote6))
12318         {
12319           grp_set = remote_set = 1;
12320           ipv6_set = 1;
12321         }
12322       else
12323         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12324         ;
12325       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12326         ;
12327       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
12328         ;
12329       else if (unformat (line_input, "vni %d", &vni))
12330         vni_set = 1;
12331       else if (unformat (line_input, "next-ip4"))
12332         protocol = 1;
12333       else if (unformat (line_input, "next-ip6"))
12334         protocol = 2;
12335       else if (unformat (line_input, "next-ethernet"))
12336         protocol = 3;
12337       else if (unformat (line_input, "next-nsh"))
12338         protocol = 4;
12339       else
12340         {
12341           errmsg ("parse error '%U'", format_unformat_error, line_input);
12342           return -99;
12343         }
12344     }
12345
12346   if (local_set == 0)
12347     {
12348       errmsg ("tunnel local address not specified");
12349       return -99;
12350     }
12351   if (remote_set == 0)
12352     {
12353       errmsg ("tunnel remote address not specified");
12354       return -99;
12355     }
12356   if (grp_set && mcast_sw_if_index == ~0)
12357     {
12358       errmsg ("tunnel nonexistent multicast device");
12359       return -99;
12360     }
12361   if (ipv4_set && ipv6_set)
12362     {
12363       errmsg ("both IPv4 and IPv6 addresses specified");
12364       return -99;
12365     }
12366
12367   if (vni_set == 0)
12368     {
12369       errmsg ("vni not specified");
12370       return -99;
12371     }
12372
12373   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
12374
12375
12376   if (ipv6_set)
12377     {
12378       clib_memcpy (&mp->local, &local6, sizeof (local6));
12379       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
12380     }
12381   else
12382     {
12383       clib_memcpy (&mp->local, &local4, sizeof (local4));
12384       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
12385     }
12386
12387   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12388   mp->encap_vrf_id = ntohl (encap_vrf_id);
12389   mp->decap_vrf_id = ntohl (decap_vrf_id);
12390   mp->protocol = protocol;
12391   mp->vni = ntohl (vni);
12392   mp->is_add = is_add;
12393   mp->is_ipv6 = ipv6_set;
12394
12395   S (mp);
12396   W (ret);
12397   return ret;
12398 }
12399
12400 static void vl_api_vxlan_gpe_tunnel_details_t_handler
12401   (vl_api_vxlan_gpe_tunnel_details_t * mp)
12402 {
12403   vat_main_t *vam = &vat_main;
12404   ip46_address_t local = to_ip46 (mp->is_ipv6, mp->local);
12405   ip46_address_t remote = to_ip46 (mp->is_ipv6, mp->remote);
12406
12407   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
12408          ntohl (mp->sw_if_index),
12409          format_ip46_address, &local, IP46_TYPE_ANY,
12410          format_ip46_address, &remote, IP46_TYPE_ANY,
12411          ntohl (mp->vni), mp->protocol,
12412          ntohl (mp->mcast_sw_if_index),
12413          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
12414 }
12415
12416
12417 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
12418   (vl_api_vxlan_gpe_tunnel_details_t * mp)
12419 {
12420   vat_main_t *vam = &vat_main;
12421   vat_json_node_t *node = NULL;
12422   struct in_addr ip4;
12423   struct in6_addr ip6;
12424
12425   if (VAT_JSON_ARRAY != vam->json_tree.type)
12426     {
12427       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12428       vat_json_init_array (&vam->json_tree);
12429     }
12430   node = vat_json_array_add (&vam->json_tree);
12431
12432   vat_json_init_object (node);
12433   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12434   if (mp->is_ipv6)
12435     {
12436       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
12437       vat_json_object_add_ip6 (node, "local", ip6);
12438       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
12439       vat_json_object_add_ip6 (node, "remote", ip6);
12440     }
12441   else
12442     {
12443       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
12444       vat_json_object_add_ip4 (node, "local", ip4);
12445       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
12446       vat_json_object_add_ip4 (node, "remote", ip4);
12447     }
12448   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12449   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
12450   vat_json_object_add_uint (node, "mcast_sw_if_index",
12451                             ntohl (mp->mcast_sw_if_index));
12452   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12453   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
12454   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12455 }
12456
12457 static int
12458 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
12459 {
12460   unformat_input_t *i = vam->input;
12461   vl_api_vxlan_gpe_tunnel_dump_t *mp;
12462   vl_api_control_ping_t *mp_ping;
12463   u32 sw_if_index;
12464   u8 sw_if_index_set = 0;
12465   int ret;
12466
12467   /* Parse args required to build the message */
12468   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12469     {
12470       if (unformat (i, "sw_if_index %d", &sw_if_index))
12471         sw_if_index_set = 1;
12472       else
12473         break;
12474     }
12475
12476   if (sw_if_index_set == 0)
12477     {
12478       sw_if_index = ~0;
12479     }
12480
12481   if (!vam->json_output)
12482     {
12483       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
12484              "sw_if_index", "local", "remote", "vni",
12485              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
12486     }
12487
12488   /* Get list of vxlan-tunnel interfaces */
12489   M (VXLAN_GPE_TUNNEL_DUMP, mp);
12490
12491   mp->sw_if_index = htonl (sw_if_index);
12492
12493   S (mp);
12494
12495   /* Use a control ping for synchronization */
12496   M (CONTROL_PING, mp_ping);
12497   S (mp_ping);
12498
12499   W (ret);
12500   return ret;
12501 }
12502
12503
12504 u8 *
12505 format_l2_fib_mac_address (u8 * s, va_list * args)
12506 {
12507   u8 *a = va_arg (*args, u8 *);
12508
12509   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
12510                  a[2], a[3], a[4], a[5], a[6], a[7]);
12511 }
12512
12513 static void vl_api_l2_fib_table_details_t_handler
12514   (vl_api_l2_fib_table_details_t * mp)
12515 {
12516   vat_main_t *vam = &vat_main;
12517
12518   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
12519          "       %d       %d     %d",
12520          ntohl (mp->bd_id), format_l2_fib_mac_address, &mp->mac,
12521          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
12522          mp->bvi_mac);
12523 }
12524
12525 static void vl_api_l2_fib_table_details_t_handler_json
12526   (vl_api_l2_fib_table_details_t * mp)
12527 {
12528   vat_main_t *vam = &vat_main;
12529   vat_json_node_t *node = NULL;
12530
12531   if (VAT_JSON_ARRAY != vam->json_tree.type)
12532     {
12533       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12534       vat_json_init_array (&vam->json_tree);
12535     }
12536   node = vat_json_array_add (&vam->json_tree);
12537
12538   vat_json_init_object (node);
12539   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
12540   vat_json_object_add_uint (node, "mac", clib_net_to_host_u64 (mp->mac));
12541   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12542   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
12543   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
12544   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
12545 }
12546
12547 static int
12548 api_l2_fib_table_dump (vat_main_t * vam)
12549 {
12550   unformat_input_t *i = vam->input;
12551   vl_api_l2_fib_table_dump_t *mp;
12552   vl_api_control_ping_t *mp_ping;
12553   u32 bd_id;
12554   u8 bd_id_set = 0;
12555   int ret;
12556
12557   /* Parse args required to build the message */
12558   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12559     {
12560       if (unformat (i, "bd_id %d", &bd_id))
12561         bd_id_set = 1;
12562       else
12563         break;
12564     }
12565
12566   if (bd_id_set == 0)
12567     {
12568       errmsg ("missing bridge domain");
12569       return -99;
12570     }
12571
12572   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
12573
12574   /* Get list of l2 fib entries */
12575   M (L2_FIB_TABLE_DUMP, mp);
12576
12577   mp->bd_id = ntohl (bd_id);
12578   S (mp);
12579
12580   /* Use a control ping for synchronization */
12581   M (CONTROL_PING, mp_ping);
12582   S (mp_ping);
12583
12584   W (ret);
12585   return ret;
12586 }
12587
12588
12589 static int
12590 api_interface_name_renumber (vat_main_t * vam)
12591 {
12592   unformat_input_t *line_input = vam->input;
12593   vl_api_interface_name_renumber_t *mp;
12594   u32 sw_if_index = ~0;
12595   u32 new_show_dev_instance = ~0;
12596   int ret;
12597
12598   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12599     {
12600       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
12601                     &sw_if_index))
12602         ;
12603       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
12604         ;
12605       else if (unformat (line_input, "new_show_dev_instance %d",
12606                          &new_show_dev_instance))
12607         ;
12608       else
12609         break;
12610     }
12611
12612   if (sw_if_index == ~0)
12613     {
12614       errmsg ("missing interface name or sw_if_index");
12615       return -99;
12616     }
12617
12618   if (new_show_dev_instance == ~0)
12619     {
12620       errmsg ("missing new_show_dev_instance");
12621       return -99;
12622     }
12623
12624   M (INTERFACE_NAME_RENUMBER, mp);
12625
12626   mp->sw_if_index = ntohl (sw_if_index);
12627   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
12628
12629   S (mp);
12630   W (ret);
12631   return ret;
12632 }
12633
12634 static int
12635 api_want_ip4_arp_events (vat_main_t * vam)
12636 {
12637   unformat_input_t *line_input = vam->input;
12638   vl_api_want_ip4_arp_events_t *mp;
12639   ip4_address_t address;
12640   int address_set = 0;
12641   u32 enable_disable = 1;
12642   int ret;
12643
12644   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12645     {
12646       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
12647         address_set = 1;
12648       else if (unformat (line_input, "del"))
12649         enable_disable = 0;
12650       else
12651         break;
12652     }
12653
12654   if (address_set == 0)
12655     {
12656       errmsg ("missing addresses");
12657       return -99;
12658     }
12659
12660   M (WANT_IP4_ARP_EVENTS, mp);
12661   mp->enable_disable = enable_disable;
12662   mp->pid = htonl (getpid ());
12663   mp->address = address.as_u32;
12664
12665   S (mp);
12666   W (ret);
12667   return ret;
12668 }
12669
12670 static int
12671 api_want_ip6_nd_events (vat_main_t * vam)
12672 {
12673   unformat_input_t *line_input = vam->input;
12674   vl_api_want_ip6_nd_events_t *mp;
12675   ip6_address_t address;
12676   int address_set = 0;
12677   u32 enable_disable = 1;
12678   int ret;
12679
12680   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12681     {
12682       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
12683         address_set = 1;
12684       else if (unformat (line_input, "del"))
12685         enable_disable = 0;
12686       else
12687         break;
12688     }
12689
12690   if (address_set == 0)
12691     {
12692       errmsg ("missing addresses");
12693       return -99;
12694     }
12695
12696   M (WANT_IP6_ND_EVENTS, mp);
12697   mp->enable_disable = enable_disable;
12698   mp->pid = htonl (getpid ());
12699   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
12700
12701   S (mp);
12702   W (ret);
12703   return ret;
12704 }
12705
12706 static int
12707 api_want_l2_macs_events (vat_main_t * vam)
12708 {
12709   unformat_input_t *line_input = vam->input;
12710   vl_api_want_l2_macs_events_t *mp;
12711   u8 enable_disable = 1;
12712   u32 scan_delay = 0;
12713   u32 max_macs_in_event = 0;
12714   u32 learn_limit = 0;
12715   int ret;
12716
12717   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12718     {
12719       if (unformat (line_input, "learn-limit %d", &learn_limit))
12720         ;
12721       else if (unformat (line_input, "scan-delay %d", &scan_delay))
12722         ;
12723       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
12724         ;
12725       else if (unformat (line_input, "disable"))
12726         enable_disable = 0;
12727       else
12728         break;
12729     }
12730
12731   M (WANT_L2_MACS_EVENTS, mp);
12732   mp->enable_disable = enable_disable;
12733   mp->pid = htonl (getpid ());
12734   mp->learn_limit = htonl (learn_limit);
12735   mp->scan_delay = (u8) scan_delay;
12736   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
12737   S (mp);
12738   W (ret);
12739   return ret;
12740 }
12741
12742 static int
12743 api_input_acl_set_interface (vat_main_t * vam)
12744 {
12745   unformat_input_t *i = vam->input;
12746   vl_api_input_acl_set_interface_t *mp;
12747   u32 sw_if_index;
12748   int sw_if_index_set;
12749   u32 ip4_table_index = ~0;
12750   u32 ip6_table_index = ~0;
12751   u32 l2_table_index = ~0;
12752   u8 is_add = 1;
12753   int ret;
12754
12755   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12756     {
12757       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12758         sw_if_index_set = 1;
12759       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12760         sw_if_index_set = 1;
12761       else if (unformat (i, "del"))
12762         is_add = 0;
12763       else if (unformat (i, "ip4-table %d", &ip4_table_index))
12764         ;
12765       else if (unformat (i, "ip6-table %d", &ip6_table_index))
12766         ;
12767       else if (unformat (i, "l2-table %d", &l2_table_index))
12768         ;
12769       else
12770         {
12771           clib_warning ("parse error '%U'", format_unformat_error, i);
12772           return -99;
12773         }
12774     }
12775
12776   if (sw_if_index_set == 0)
12777     {
12778       errmsg ("missing interface name or sw_if_index");
12779       return -99;
12780     }
12781
12782   M (INPUT_ACL_SET_INTERFACE, mp);
12783
12784   mp->sw_if_index = ntohl (sw_if_index);
12785   mp->ip4_table_index = ntohl (ip4_table_index);
12786   mp->ip6_table_index = ntohl (ip6_table_index);
12787   mp->l2_table_index = ntohl (l2_table_index);
12788   mp->is_add = is_add;
12789
12790   S (mp);
12791   W (ret);
12792   return ret;
12793 }
12794
12795 static int
12796 api_ip_address_dump (vat_main_t * vam)
12797 {
12798   unformat_input_t *i = vam->input;
12799   vl_api_ip_address_dump_t *mp;
12800   vl_api_control_ping_t *mp_ping;
12801   u32 sw_if_index = ~0;
12802   u8 sw_if_index_set = 0;
12803   u8 ipv4_set = 0;
12804   u8 ipv6_set = 0;
12805   int ret;
12806
12807   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12808     {
12809       if (unformat (i, "sw_if_index %d", &sw_if_index))
12810         sw_if_index_set = 1;
12811       else
12812         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12813         sw_if_index_set = 1;
12814       else if (unformat (i, "ipv4"))
12815         ipv4_set = 1;
12816       else if (unformat (i, "ipv6"))
12817         ipv6_set = 1;
12818       else
12819         break;
12820     }
12821
12822   if (ipv4_set && ipv6_set)
12823     {
12824       errmsg ("ipv4 and ipv6 flags cannot be both set");
12825       return -99;
12826     }
12827
12828   if ((!ipv4_set) && (!ipv6_set))
12829     {
12830       errmsg ("no ipv4 nor ipv6 flag set");
12831       return -99;
12832     }
12833
12834   if (sw_if_index_set == 0)
12835     {
12836       errmsg ("missing interface name or sw_if_index");
12837       return -99;
12838     }
12839
12840   vam->current_sw_if_index = sw_if_index;
12841   vam->is_ipv6 = ipv6_set;
12842
12843   M (IP_ADDRESS_DUMP, mp);
12844   mp->sw_if_index = ntohl (sw_if_index);
12845   mp->is_ipv6 = ipv6_set;
12846   S (mp);
12847
12848   /* Use a control ping for synchronization */
12849   M (CONTROL_PING, mp_ping);
12850   S (mp_ping);
12851
12852   W (ret);
12853   return ret;
12854 }
12855
12856 static int
12857 api_ip_dump (vat_main_t * vam)
12858 {
12859   vl_api_ip_dump_t *mp;
12860   vl_api_control_ping_t *mp_ping;
12861   unformat_input_t *in = vam->input;
12862   int ipv4_set = 0;
12863   int ipv6_set = 0;
12864   int is_ipv6;
12865   int i;
12866   int ret;
12867
12868   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
12869     {
12870       if (unformat (in, "ipv4"))
12871         ipv4_set = 1;
12872       else if (unformat (in, "ipv6"))
12873         ipv6_set = 1;
12874       else
12875         break;
12876     }
12877
12878   if (ipv4_set && ipv6_set)
12879     {
12880       errmsg ("ipv4 and ipv6 flags cannot be both set");
12881       return -99;
12882     }
12883
12884   if ((!ipv4_set) && (!ipv6_set))
12885     {
12886       errmsg ("no ipv4 nor ipv6 flag set");
12887       return -99;
12888     }
12889
12890   is_ipv6 = ipv6_set;
12891   vam->is_ipv6 = is_ipv6;
12892
12893   /* free old data */
12894   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
12895     {
12896       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
12897     }
12898   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
12899
12900   M (IP_DUMP, mp);
12901   mp->is_ipv6 = ipv6_set;
12902   S (mp);
12903
12904   /* Use a control ping for synchronization */
12905   M (CONTROL_PING, mp_ping);
12906   S (mp_ping);
12907
12908   W (ret);
12909   return ret;
12910 }
12911
12912 static int
12913 api_ipsec_spd_add_del (vat_main_t * vam)
12914 {
12915   unformat_input_t *i = vam->input;
12916   vl_api_ipsec_spd_add_del_t *mp;
12917   u32 spd_id = ~0;
12918   u8 is_add = 1;
12919   int ret;
12920
12921   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12922     {
12923       if (unformat (i, "spd_id %d", &spd_id))
12924         ;
12925       else if (unformat (i, "del"))
12926         is_add = 0;
12927       else
12928         {
12929           clib_warning ("parse error '%U'", format_unformat_error, i);
12930           return -99;
12931         }
12932     }
12933   if (spd_id == ~0)
12934     {
12935       errmsg ("spd_id must be set");
12936       return -99;
12937     }
12938
12939   M (IPSEC_SPD_ADD_DEL, mp);
12940
12941   mp->spd_id = ntohl (spd_id);
12942   mp->is_add = is_add;
12943
12944   S (mp);
12945   W (ret);
12946   return ret;
12947 }
12948
12949 static int
12950 api_ipsec_interface_add_del_spd (vat_main_t * vam)
12951 {
12952   unformat_input_t *i = vam->input;
12953   vl_api_ipsec_interface_add_del_spd_t *mp;
12954   u32 sw_if_index;
12955   u8 sw_if_index_set = 0;
12956   u32 spd_id = (u32) ~ 0;
12957   u8 is_add = 1;
12958   int ret;
12959
12960   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12961     {
12962       if (unformat (i, "del"))
12963         is_add = 0;
12964       else if (unformat (i, "spd_id %d", &spd_id))
12965         ;
12966       else
12967         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12968         sw_if_index_set = 1;
12969       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12970         sw_if_index_set = 1;
12971       else
12972         {
12973           clib_warning ("parse error '%U'", format_unformat_error, i);
12974           return -99;
12975         }
12976
12977     }
12978
12979   if (spd_id == (u32) ~ 0)
12980     {
12981       errmsg ("spd_id must be set");
12982       return -99;
12983     }
12984
12985   if (sw_if_index_set == 0)
12986     {
12987       errmsg ("missing interface name or sw_if_index");
12988       return -99;
12989     }
12990
12991   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
12992
12993   mp->spd_id = ntohl (spd_id);
12994   mp->sw_if_index = ntohl (sw_if_index);
12995   mp->is_add = is_add;
12996
12997   S (mp);
12998   W (ret);
12999   return ret;
13000 }
13001
13002 static int
13003 api_ipsec_spd_add_del_entry (vat_main_t * vam)
13004 {
13005   unformat_input_t *i = vam->input;
13006   vl_api_ipsec_spd_add_del_entry_t *mp;
13007   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
13008   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
13009   i32 priority = 0;
13010   u32 rport_start = 0, rport_stop = (u32) ~ 0;
13011   u32 lport_start = 0, lport_stop = (u32) ~ 0;
13012   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
13013   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
13014   int ret;
13015
13016   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
13017   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
13018   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
13019   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
13020   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
13021   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
13022
13023   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13024     {
13025       if (unformat (i, "del"))
13026         is_add = 0;
13027       if (unformat (i, "outbound"))
13028         is_outbound = 1;
13029       if (unformat (i, "inbound"))
13030         is_outbound = 0;
13031       else if (unformat (i, "spd_id %d", &spd_id))
13032         ;
13033       else if (unformat (i, "sa_id %d", &sa_id))
13034         ;
13035       else if (unformat (i, "priority %d", &priority))
13036         ;
13037       else if (unformat (i, "protocol %d", &protocol))
13038         ;
13039       else if (unformat (i, "lport_start %d", &lport_start))
13040         ;
13041       else if (unformat (i, "lport_stop %d", &lport_stop))
13042         ;
13043       else if (unformat (i, "rport_start %d", &rport_start))
13044         ;
13045       else if (unformat (i, "rport_stop %d", &rport_stop))
13046         ;
13047       else
13048         if (unformat
13049             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
13050         {
13051           is_ipv6 = 0;
13052           is_ip_any = 0;
13053         }
13054       else
13055         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
13056         {
13057           is_ipv6 = 0;
13058           is_ip_any = 0;
13059         }
13060       else
13061         if (unformat
13062             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
13063         {
13064           is_ipv6 = 0;
13065           is_ip_any = 0;
13066         }
13067       else
13068         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
13069         {
13070           is_ipv6 = 0;
13071           is_ip_any = 0;
13072         }
13073       else
13074         if (unformat
13075             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
13076         {
13077           is_ipv6 = 1;
13078           is_ip_any = 0;
13079         }
13080       else
13081         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
13082         {
13083           is_ipv6 = 1;
13084           is_ip_any = 0;
13085         }
13086       else
13087         if (unformat
13088             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
13089         {
13090           is_ipv6 = 1;
13091           is_ip_any = 0;
13092         }
13093       else
13094         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
13095         {
13096           is_ipv6 = 1;
13097           is_ip_any = 0;
13098         }
13099       else
13100         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
13101         {
13102           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
13103             {
13104               clib_warning ("unsupported action: 'resolve'");
13105               return -99;
13106             }
13107         }
13108       else
13109         {
13110           clib_warning ("parse error '%U'", format_unformat_error, i);
13111           return -99;
13112         }
13113
13114     }
13115
13116   M (IPSEC_SPD_ADD_DEL_ENTRY, mp);
13117
13118   mp->spd_id = ntohl (spd_id);
13119   mp->priority = ntohl (priority);
13120   mp->is_outbound = is_outbound;
13121
13122   mp->is_ipv6 = is_ipv6;
13123   if (is_ipv6 || is_ip_any)
13124     {
13125       clib_memcpy (mp->remote_address_start, &raddr6_start,
13126                    sizeof (ip6_address_t));
13127       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
13128                    sizeof (ip6_address_t));
13129       clib_memcpy (mp->local_address_start, &laddr6_start,
13130                    sizeof (ip6_address_t));
13131       clib_memcpy (mp->local_address_stop, &laddr6_stop,
13132                    sizeof (ip6_address_t));
13133     }
13134   else
13135     {
13136       clib_memcpy (mp->remote_address_start, &raddr4_start,
13137                    sizeof (ip4_address_t));
13138       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
13139                    sizeof (ip4_address_t));
13140       clib_memcpy (mp->local_address_start, &laddr4_start,
13141                    sizeof (ip4_address_t));
13142       clib_memcpy (mp->local_address_stop, &laddr4_stop,
13143                    sizeof (ip4_address_t));
13144     }
13145   mp->protocol = (u8) protocol;
13146   mp->local_port_start = ntohs ((u16) lport_start);
13147   mp->local_port_stop = ntohs ((u16) lport_stop);
13148   mp->remote_port_start = ntohs ((u16) rport_start);
13149   mp->remote_port_stop = ntohs ((u16) rport_stop);
13150   mp->policy = (u8) policy;
13151   mp->sa_id = ntohl (sa_id);
13152   mp->is_add = is_add;
13153   mp->is_ip_any = is_ip_any;
13154   S (mp);
13155   W (ret);
13156   return ret;
13157 }
13158
13159 static int
13160 api_ipsec_sad_add_del_entry (vat_main_t * vam)
13161 {
13162   unformat_input_t *i = vam->input;
13163   vl_api_ipsec_sad_add_del_entry_t *mp;
13164   u32 sad_id = 0, spi = 0;
13165   u8 *ck = 0, *ik = 0;
13166   u8 is_add = 1;
13167
13168   u8 protocol = IPSEC_PROTOCOL_AH;
13169   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
13170   u32 crypto_alg = 0, integ_alg = 0;
13171   ip4_address_t tun_src4;
13172   ip4_address_t tun_dst4;
13173   ip6_address_t tun_src6;
13174   ip6_address_t tun_dst6;
13175   int ret;
13176
13177   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13178     {
13179       if (unformat (i, "del"))
13180         is_add = 0;
13181       else if (unformat (i, "sad_id %d", &sad_id))
13182         ;
13183       else if (unformat (i, "spi %d", &spi))
13184         ;
13185       else if (unformat (i, "esp"))
13186         protocol = IPSEC_PROTOCOL_ESP;
13187       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
13188         {
13189           is_tunnel = 1;
13190           is_tunnel_ipv6 = 0;
13191         }
13192       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
13193         {
13194           is_tunnel = 1;
13195           is_tunnel_ipv6 = 0;
13196         }
13197       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
13198         {
13199           is_tunnel = 1;
13200           is_tunnel_ipv6 = 1;
13201         }
13202       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
13203         {
13204           is_tunnel = 1;
13205           is_tunnel_ipv6 = 1;
13206         }
13207       else
13208         if (unformat
13209             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
13210         {
13211           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
13212               crypto_alg >= IPSEC_CRYPTO_N_ALG)
13213             {
13214               clib_warning ("unsupported crypto-alg: '%U'",
13215                             format_ipsec_crypto_alg, crypto_alg);
13216               return -99;
13217             }
13218         }
13219       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
13220         ;
13221       else
13222         if (unformat
13223             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
13224         {
13225           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
13226               integ_alg >= IPSEC_INTEG_N_ALG)
13227             {
13228               clib_warning ("unsupported integ-alg: '%U'",
13229                             format_ipsec_integ_alg, integ_alg);
13230               return -99;
13231             }
13232         }
13233       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
13234         ;
13235       else
13236         {
13237           clib_warning ("parse error '%U'", format_unformat_error, i);
13238           return -99;
13239         }
13240
13241     }
13242
13243   M (IPSEC_SAD_ADD_DEL_ENTRY, mp);
13244
13245   mp->sad_id = ntohl (sad_id);
13246   mp->is_add = is_add;
13247   mp->protocol = protocol;
13248   mp->spi = ntohl (spi);
13249   mp->is_tunnel = is_tunnel;
13250   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
13251   mp->crypto_algorithm = crypto_alg;
13252   mp->integrity_algorithm = integ_alg;
13253   mp->crypto_key_length = vec_len (ck);
13254   mp->integrity_key_length = vec_len (ik);
13255
13256   if (mp->crypto_key_length > sizeof (mp->crypto_key))
13257     mp->crypto_key_length = sizeof (mp->crypto_key);
13258
13259   if (mp->integrity_key_length > sizeof (mp->integrity_key))
13260     mp->integrity_key_length = sizeof (mp->integrity_key);
13261
13262   if (ck)
13263     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
13264   if (ik)
13265     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
13266
13267   if (is_tunnel)
13268     {
13269       if (is_tunnel_ipv6)
13270         {
13271           clib_memcpy (mp->tunnel_src_address, &tun_src6,
13272                        sizeof (ip6_address_t));
13273           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
13274                        sizeof (ip6_address_t));
13275         }
13276       else
13277         {
13278           clib_memcpy (mp->tunnel_src_address, &tun_src4,
13279                        sizeof (ip4_address_t));
13280           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
13281                        sizeof (ip4_address_t));
13282         }
13283     }
13284
13285   S (mp);
13286   W (ret);
13287   return ret;
13288 }
13289
13290 static int
13291 api_ipsec_sa_set_key (vat_main_t * vam)
13292 {
13293   unformat_input_t *i = vam->input;
13294   vl_api_ipsec_sa_set_key_t *mp;
13295   u32 sa_id;
13296   u8 *ck = 0, *ik = 0;
13297   int ret;
13298
13299   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13300     {
13301       if (unformat (i, "sa_id %d", &sa_id))
13302         ;
13303       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
13304         ;
13305       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
13306         ;
13307       else
13308         {
13309           clib_warning ("parse error '%U'", format_unformat_error, i);
13310           return -99;
13311         }
13312     }
13313
13314   M (IPSEC_SA_SET_KEY, mp);
13315
13316   mp->sa_id = ntohl (sa_id);
13317   mp->crypto_key_length = vec_len (ck);
13318   mp->integrity_key_length = vec_len (ik);
13319
13320   if (mp->crypto_key_length > sizeof (mp->crypto_key))
13321     mp->crypto_key_length = sizeof (mp->crypto_key);
13322
13323   if (mp->integrity_key_length > sizeof (mp->integrity_key))
13324     mp->integrity_key_length = sizeof (mp->integrity_key);
13325
13326   if (ck)
13327     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
13328   if (ik)
13329     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
13330
13331   S (mp);
13332   W (ret);
13333   return ret;
13334 }
13335
13336 static int
13337 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
13338 {
13339   unformat_input_t *i = vam->input;
13340   vl_api_ipsec_tunnel_if_add_del_t *mp;
13341   u32 local_spi = 0, remote_spi = 0;
13342   u32 crypto_alg = 0, integ_alg = 0;
13343   u8 *lck = NULL, *rck = NULL;
13344   u8 *lik = NULL, *rik = NULL;
13345   ip4_address_t local_ip = { {0} };
13346   ip4_address_t remote_ip = { {0} };
13347   u8 is_add = 1;
13348   u8 esn = 0;
13349   u8 anti_replay = 0;
13350   int ret;
13351
13352   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13353     {
13354       if (unformat (i, "del"))
13355         is_add = 0;
13356       else if (unformat (i, "esn"))
13357         esn = 1;
13358       else if (unformat (i, "anti_replay"))
13359         anti_replay = 1;
13360       else if (unformat (i, "local_spi %d", &local_spi))
13361         ;
13362       else if (unformat (i, "remote_spi %d", &remote_spi))
13363         ;
13364       else if (unformat (i, "local_ip %U", unformat_ip4_address, &local_ip))
13365         ;
13366       else if (unformat (i, "remote_ip %U", unformat_ip4_address, &remote_ip))
13367         ;
13368       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
13369         ;
13370       else
13371         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
13372         ;
13373       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
13374         ;
13375       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
13376         ;
13377       else
13378         if (unformat
13379             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
13380         {
13381           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
13382               crypto_alg >= IPSEC_CRYPTO_N_ALG)
13383             {
13384               errmsg ("unsupported crypto-alg: '%U'\n",
13385                       format_ipsec_crypto_alg, crypto_alg);
13386               return -99;
13387             }
13388         }
13389       else
13390         if (unformat
13391             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
13392         {
13393           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
13394               integ_alg >= IPSEC_INTEG_N_ALG)
13395             {
13396               errmsg ("unsupported integ-alg: '%U'\n",
13397                       format_ipsec_integ_alg, integ_alg);
13398               return -99;
13399             }
13400         }
13401       else
13402         {
13403           errmsg ("parse error '%U'\n", format_unformat_error, i);
13404           return -99;
13405         }
13406     }
13407
13408   M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
13409
13410   mp->is_add = is_add;
13411   mp->esn = esn;
13412   mp->anti_replay = anti_replay;
13413
13414   clib_memcpy (mp->local_ip, &local_ip, sizeof (ip4_address_t));
13415   clib_memcpy (mp->remote_ip, &remote_ip, sizeof (ip4_address_t));
13416
13417   mp->local_spi = htonl (local_spi);
13418   mp->remote_spi = htonl (remote_spi);
13419   mp->crypto_alg = (u8) crypto_alg;
13420
13421   mp->local_crypto_key_len = 0;
13422   if (lck)
13423     {
13424       mp->local_crypto_key_len = vec_len (lck);
13425       if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
13426         mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
13427       clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
13428     }
13429
13430   mp->remote_crypto_key_len = 0;
13431   if (rck)
13432     {
13433       mp->remote_crypto_key_len = vec_len (rck);
13434       if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
13435         mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
13436       clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
13437     }
13438
13439   mp->integ_alg = (u8) integ_alg;
13440
13441   mp->local_integ_key_len = 0;
13442   if (lik)
13443     {
13444       mp->local_integ_key_len = vec_len (lik);
13445       if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
13446         mp->local_integ_key_len = sizeof (mp->local_integ_key);
13447       clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
13448     }
13449
13450   mp->remote_integ_key_len = 0;
13451   if (rik)
13452     {
13453       mp->remote_integ_key_len = vec_len (rik);
13454       if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
13455         mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
13456       clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
13457     }
13458
13459   S (mp);
13460   W (ret);
13461   return ret;
13462 }
13463
13464 static int
13465 api_ikev2_profile_add_del (vat_main_t * vam)
13466 {
13467   unformat_input_t *i = vam->input;
13468   vl_api_ikev2_profile_add_del_t *mp;
13469   u8 is_add = 1;
13470   u8 *name = 0;
13471   int ret;
13472
13473   const char *valid_chars = "a-zA-Z0-9_";
13474
13475   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13476     {
13477       if (unformat (i, "del"))
13478         is_add = 0;
13479       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
13480         vec_add1 (name, 0);
13481       else
13482         {
13483           errmsg ("parse error '%U'", format_unformat_error, i);
13484           return -99;
13485         }
13486     }
13487
13488   if (!vec_len (name))
13489     {
13490       errmsg ("profile name must be specified");
13491       return -99;
13492     }
13493
13494   if (vec_len (name) > 64)
13495     {
13496       errmsg ("profile name too long");
13497       return -99;
13498     }
13499
13500   M (IKEV2_PROFILE_ADD_DEL, mp);
13501
13502   clib_memcpy (mp->name, name, vec_len (name));
13503   mp->is_add = is_add;
13504   vec_free (name);
13505
13506   S (mp);
13507   W (ret);
13508   return ret;
13509 }
13510
13511 static int
13512 api_ikev2_profile_set_auth (vat_main_t * vam)
13513 {
13514   unformat_input_t *i = vam->input;
13515   vl_api_ikev2_profile_set_auth_t *mp;
13516   u8 *name = 0;
13517   u8 *data = 0;
13518   u32 auth_method = 0;
13519   u8 is_hex = 0;
13520   int ret;
13521
13522   const char *valid_chars = "a-zA-Z0-9_";
13523
13524   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13525     {
13526       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
13527         vec_add1 (name, 0);
13528       else if (unformat (i, "auth_method %U",
13529                          unformat_ikev2_auth_method, &auth_method))
13530         ;
13531       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
13532         is_hex = 1;
13533       else if (unformat (i, "auth_data %v", &data))
13534         ;
13535       else
13536         {
13537           errmsg ("parse error '%U'", format_unformat_error, i);
13538           return -99;
13539         }
13540     }
13541
13542   if (!vec_len (name))
13543     {
13544       errmsg ("profile name must be specified");
13545       return -99;
13546     }
13547
13548   if (vec_len (name) > 64)
13549     {
13550       errmsg ("profile name too long");
13551       return -99;
13552     }
13553
13554   if (!vec_len (data))
13555     {
13556       errmsg ("auth_data must be specified");
13557       return -99;
13558     }
13559
13560   if (!auth_method)
13561     {
13562       errmsg ("auth_method must be specified");
13563       return -99;
13564     }
13565
13566   M (IKEV2_PROFILE_SET_AUTH, mp);
13567
13568   mp->is_hex = is_hex;
13569   mp->auth_method = (u8) auth_method;
13570   mp->data_len = vec_len (data);
13571   clib_memcpy (mp->name, name, vec_len (name));
13572   clib_memcpy (mp->data, data, vec_len (data));
13573   vec_free (name);
13574   vec_free (data);
13575
13576   S (mp);
13577   W (ret);
13578   return ret;
13579 }
13580
13581 static int
13582 api_ikev2_profile_set_id (vat_main_t * vam)
13583 {
13584   unformat_input_t *i = vam->input;
13585   vl_api_ikev2_profile_set_id_t *mp;
13586   u8 *name = 0;
13587   u8 *data = 0;
13588   u8 is_local = 0;
13589   u32 id_type = 0;
13590   ip4_address_t ip4;
13591   int ret;
13592
13593   const char *valid_chars = "a-zA-Z0-9_";
13594
13595   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13596     {
13597       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
13598         vec_add1 (name, 0);
13599       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
13600         ;
13601       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
13602         {
13603           data = vec_new (u8, 4);
13604           clib_memcpy (data, ip4.as_u8, 4);
13605         }
13606       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
13607         ;
13608       else if (unformat (i, "id_data %v", &data))
13609         ;
13610       else if (unformat (i, "local"))
13611         is_local = 1;
13612       else if (unformat (i, "remote"))
13613         is_local = 0;
13614       else
13615         {
13616           errmsg ("parse error '%U'", format_unformat_error, i);
13617           return -99;
13618         }
13619     }
13620
13621   if (!vec_len (name))
13622     {
13623       errmsg ("profile name must be specified");
13624       return -99;
13625     }
13626
13627   if (vec_len (name) > 64)
13628     {
13629       errmsg ("profile name too long");
13630       return -99;
13631     }
13632
13633   if (!vec_len (data))
13634     {
13635       errmsg ("id_data must be specified");
13636       return -99;
13637     }
13638
13639   if (!id_type)
13640     {
13641       errmsg ("id_type must be specified");
13642       return -99;
13643     }
13644
13645   M (IKEV2_PROFILE_SET_ID, mp);
13646
13647   mp->is_local = is_local;
13648   mp->id_type = (u8) id_type;
13649   mp->data_len = vec_len (data);
13650   clib_memcpy (mp->name, name, vec_len (name));
13651   clib_memcpy (mp->data, data, vec_len (data));
13652   vec_free (name);
13653   vec_free (data);
13654
13655   S (mp);
13656   W (ret);
13657   return ret;
13658 }
13659
13660 static int
13661 api_ikev2_profile_set_ts (vat_main_t * vam)
13662 {
13663   unformat_input_t *i = vam->input;
13664   vl_api_ikev2_profile_set_ts_t *mp;
13665   u8 *name = 0;
13666   u8 is_local = 0;
13667   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
13668   ip4_address_t start_addr, end_addr;
13669
13670   const char *valid_chars = "a-zA-Z0-9_";
13671   int ret;
13672
13673   start_addr.as_u32 = 0;
13674   end_addr.as_u32 = (u32) ~ 0;
13675
13676   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13677     {
13678       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
13679         vec_add1 (name, 0);
13680       else if (unformat (i, "protocol %d", &proto))
13681         ;
13682       else if (unformat (i, "start_port %d", &start_port))
13683         ;
13684       else if (unformat (i, "end_port %d", &end_port))
13685         ;
13686       else
13687         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
13688         ;
13689       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
13690         ;
13691       else if (unformat (i, "local"))
13692         is_local = 1;
13693       else if (unformat (i, "remote"))
13694         is_local = 0;
13695       else
13696         {
13697           errmsg ("parse error '%U'", format_unformat_error, i);
13698           return -99;
13699         }
13700     }
13701
13702   if (!vec_len (name))
13703     {
13704       errmsg ("profile name must be specified");
13705       return -99;
13706     }
13707
13708   if (vec_len (name) > 64)
13709     {
13710       errmsg ("profile name too long");
13711       return -99;
13712     }
13713
13714   M (IKEV2_PROFILE_SET_TS, mp);
13715
13716   mp->is_local = is_local;
13717   mp->proto = (u8) proto;
13718   mp->start_port = (u16) start_port;
13719   mp->end_port = (u16) end_port;
13720   mp->start_addr = start_addr.as_u32;
13721   mp->end_addr = end_addr.as_u32;
13722   clib_memcpy (mp->name, name, vec_len (name));
13723   vec_free (name);
13724
13725   S (mp);
13726   W (ret);
13727   return ret;
13728 }
13729
13730 static int
13731 api_ikev2_set_local_key (vat_main_t * vam)
13732 {
13733   unformat_input_t *i = vam->input;
13734   vl_api_ikev2_set_local_key_t *mp;
13735   u8 *file = 0;
13736   int ret;
13737
13738   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13739     {
13740       if (unformat (i, "file %v", &file))
13741         vec_add1 (file, 0);
13742       else
13743         {
13744           errmsg ("parse error '%U'", format_unformat_error, i);
13745           return -99;
13746         }
13747     }
13748
13749   if (!vec_len (file))
13750     {
13751       errmsg ("RSA key file must be specified");
13752       return -99;
13753     }
13754
13755   if (vec_len (file) > 256)
13756     {
13757       errmsg ("file name too long");
13758       return -99;
13759     }
13760
13761   M (IKEV2_SET_LOCAL_KEY, mp);
13762
13763   clib_memcpy (mp->key_file, file, vec_len (file));
13764   vec_free (file);
13765
13766   S (mp);
13767   W (ret);
13768   return ret;
13769 }
13770
13771 static int
13772 api_ikev2_set_responder (vat_main_t * vam)
13773 {
13774   unformat_input_t *i = vam->input;
13775   vl_api_ikev2_set_responder_t *mp;
13776   int ret;
13777   u8 *name = 0;
13778   u32 sw_if_index = ~0;
13779   ip4_address_t address;
13780
13781   const char *valid_chars = "a-zA-Z0-9_";
13782
13783   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13784     {
13785       if (unformat
13786           (i, "%U interface %d address %U", unformat_token, valid_chars,
13787            &name, &sw_if_index, unformat_ip4_address, &address))
13788         vec_add1 (name, 0);
13789       else
13790         {
13791           errmsg ("parse error '%U'", format_unformat_error, i);
13792           return -99;
13793         }
13794     }
13795
13796   if (!vec_len (name))
13797     {
13798       errmsg ("profile name must be specified");
13799       return -99;
13800     }
13801
13802   if (vec_len (name) > 64)
13803     {
13804       errmsg ("profile name too long");
13805       return -99;
13806     }
13807
13808   M (IKEV2_SET_RESPONDER, mp);
13809
13810   clib_memcpy (mp->name, name, vec_len (name));
13811   vec_free (name);
13812
13813   mp->sw_if_index = sw_if_index;
13814   clib_memcpy (mp->address, &address, sizeof (address));
13815
13816   S (mp);
13817   W (ret);
13818   return ret;
13819 }
13820
13821 static int
13822 api_ikev2_set_ike_transforms (vat_main_t * vam)
13823 {
13824   unformat_input_t *i = vam->input;
13825   vl_api_ikev2_set_ike_transforms_t *mp;
13826   int ret;
13827   u8 *name = 0;
13828   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
13829
13830   const char *valid_chars = "a-zA-Z0-9_";
13831
13832   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13833     {
13834       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
13835                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
13836         vec_add1 (name, 0);
13837       else
13838         {
13839           errmsg ("parse error '%U'", format_unformat_error, i);
13840           return -99;
13841         }
13842     }
13843
13844   if (!vec_len (name))
13845     {
13846       errmsg ("profile name must be specified");
13847       return -99;
13848     }
13849
13850   if (vec_len (name) > 64)
13851     {
13852       errmsg ("profile name too long");
13853       return -99;
13854     }
13855
13856   M (IKEV2_SET_IKE_TRANSFORMS, mp);
13857
13858   clib_memcpy (mp->name, name, vec_len (name));
13859   vec_free (name);
13860   mp->crypto_alg = crypto_alg;
13861   mp->crypto_key_size = crypto_key_size;
13862   mp->integ_alg = integ_alg;
13863   mp->dh_group = dh_group;
13864
13865   S (mp);
13866   W (ret);
13867   return ret;
13868 }
13869
13870
13871 static int
13872 api_ikev2_set_esp_transforms (vat_main_t * vam)
13873 {
13874   unformat_input_t *i = vam->input;
13875   vl_api_ikev2_set_esp_transforms_t *mp;
13876   int ret;
13877   u8 *name = 0;
13878   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
13879
13880   const char *valid_chars = "a-zA-Z0-9_";
13881
13882   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13883     {
13884       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
13885                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
13886         vec_add1 (name, 0);
13887       else
13888         {
13889           errmsg ("parse error '%U'", format_unformat_error, i);
13890           return -99;
13891         }
13892     }
13893
13894   if (!vec_len (name))
13895     {
13896       errmsg ("profile name must be specified");
13897       return -99;
13898     }
13899
13900   if (vec_len (name) > 64)
13901     {
13902       errmsg ("profile name too long");
13903       return -99;
13904     }
13905
13906   M (IKEV2_SET_ESP_TRANSFORMS, mp);
13907
13908   clib_memcpy (mp->name, name, vec_len (name));
13909   vec_free (name);
13910   mp->crypto_alg = crypto_alg;
13911   mp->crypto_key_size = crypto_key_size;
13912   mp->integ_alg = integ_alg;
13913   mp->dh_group = dh_group;
13914
13915   S (mp);
13916   W (ret);
13917   return ret;
13918 }
13919
13920 static int
13921 api_ikev2_set_sa_lifetime (vat_main_t * vam)
13922 {
13923   unformat_input_t *i = vam->input;
13924   vl_api_ikev2_set_sa_lifetime_t *mp;
13925   int ret;
13926   u8 *name = 0;
13927   u64 lifetime, lifetime_maxdata;
13928   u32 lifetime_jitter, handover;
13929
13930   const char *valid_chars = "a-zA-Z0-9_";
13931
13932   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13933     {
13934       if (unformat (i, "%U %lu %u %u %lu", unformat_token, valid_chars, &name,
13935                     &lifetime, &lifetime_jitter, &handover,
13936                     &lifetime_maxdata))
13937         vec_add1 (name, 0);
13938       else
13939         {
13940           errmsg ("parse error '%U'", format_unformat_error, i);
13941           return -99;
13942         }
13943     }
13944
13945   if (!vec_len (name))
13946     {
13947       errmsg ("profile name must be specified");
13948       return -99;
13949     }
13950
13951   if (vec_len (name) > 64)
13952     {
13953       errmsg ("profile name too long");
13954       return -99;
13955     }
13956
13957   M (IKEV2_SET_SA_LIFETIME, mp);
13958
13959   clib_memcpy (mp->name, name, vec_len (name));
13960   vec_free (name);
13961   mp->lifetime = lifetime;
13962   mp->lifetime_jitter = lifetime_jitter;
13963   mp->handover = handover;
13964   mp->lifetime_maxdata = lifetime_maxdata;
13965
13966   S (mp);
13967   W (ret);
13968   return ret;
13969 }
13970
13971 static int
13972 api_ikev2_initiate_sa_init (vat_main_t * vam)
13973 {
13974   unformat_input_t *i = vam->input;
13975   vl_api_ikev2_initiate_sa_init_t *mp;
13976   int ret;
13977   u8 *name = 0;
13978
13979   const char *valid_chars = "a-zA-Z0-9_";
13980
13981   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13982     {
13983       if (unformat (i, "%U", unformat_token, valid_chars, &name))
13984         vec_add1 (name, 0);
13985       else
13986         {
13987           errmsg ("parse error '%U'", format_unformat_error, i);
13988           return -99;
13989         }
13990     }
13991
13992   if (!vec_len (name))
13993     {
13994       errmsg ("profile name must be specified");
13995       return -99;
13996     }
13997
13998   if (vec_len (name) > 64)
13999     {
14000       errmsg ("profile name too long");
14001       return -99;
14002     }
14003
14004   M (IKEV2_INITIATE_SA_INIT, mp);
14005
14006   clib_memcpy (mp->name, name, vec_len (name));
14007   vec_free (name);
14008
14009   S (mp);
14010   W (ret);
14011   return ret;
14012 }
14013
14014 static int
14015 api_ikev2_initiate_del_ike_sa (vat_main_t * vam)
14016 {
14017   unformat_input_t *i = vam->input;
14018   vl_api_ikev2_initiate_del_ike_sa_t *mp;
14019   int ret;
14020   u64 ispi;
14021
14022
14023   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14024     {
14025       if (unformat (i, "%lx", &ispi))
14026         ;
14027       else
14028         {
14029           errmsg ("parse error '%U'", format_unformat_error, i);
14030           return -99;
14031         }
14032     }
14033
14034   M (IKEV2_INITIATE_DEL_IKE_SA, mp);
14035
14036   mp->ispi = ispi;
14037
14038   S (mp);
14039   W (ret);
14040   return ret;
14041 }
14042
14043 static int
14044 api_ikev2_initiate_del_child_sa (vat_main_t * vam)
14045 {
14046   unformat_input_t *i = vam->input;
14047   vl_api_ikev2_initiate_del_child_sa_t *mp;
14048   int ret;
14049   u32 ispi;
14050
14051
14052   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14053     {
14054       if (unformat (i, "%x", &ispi))
14055         ;
14056       else
14057         {
14058           errmsg ("parse error '%U'", format_unformat_error, i);
14059           return -99;
14060         }
14061     }
14062
14063   M (IKEV2_INITIATE_DEL_CHILD_SA, mp);
14064
14065   mp->ispi = ispi;
14066
14067   S (mp);
14068   W (ret);
14069   return ret;
14070 }
14071
14072 static int
14073 api_ikev2_initiate_rekey_child_sa (vat_main_t * vam)
14074 {
14075   unformat_input_t *i = vam->input;
14076   vl_api_ikev2_initiate_rekey_child_sa_t *mp;
14077   int ret;
14078   u32 ispi;
14079
14080
14081   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14082     {
14083       if (unformat (i, "%x", &ispi))
14084         ;
14085       else
14086         {
14087           errmsg ("parse error '%U'", format_unformat_error, i);
14088           return -99;
14089         }
14090     }
14091
14092   M (IKEV2_INITIATE_REKEY_CHILD_SA, mp);
14093
14094   mp->ispi = ispi;
14095
14096   S (mp);
14097   W (ret);
14098   return ret;
14099 }
14100
14101 /*
14102  * MAP
14103  */
14104 static int
14105 api_map_add_domain (vat_main_t * vam)
14106 {
14107   unformat_input_t *i = vam->input;
14108   vl_api_map_add_domain_t *mp;
14109
14110   ip4_address_t ip4_prefix;
14111   ip6_address_t ip6_prefix;
14112   ip6_address_t ip6_src;
14113   u32 num_m_args = 0;
14114   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
14115     0, psid_length = 0;
14116   u8 is_translation = 0;
14117   u32 mtu = 0;
14118   u32 ip6_src_len = 128;
14119   int ret;
14120
14121   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14122     {
14123       if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
14124                     &ip4_prefix, &ip4_prefix_len))
14125         num_m_args++;
14126       else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
14127                          &ip6_prefix, &ip6_prefix_len))
14128         num_m_args++;
14129       else
14130         if (unformat
14131             (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
14132              &ip6_src_len))
14133         num_m_args++;
14134       else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
14135         num_m_args++;
14136       else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
14137         num_m_args++;
14138       else if (unformat (i, "psid-offset %d", &psid_offset))
14139         num_m_args++;
14140       else if (unformat (i, "psid-len %d", &psid_length))
14141         num_m_args++;
14142       else if (unformat (i, "mtu %d", &mtu))
14143         num_m_args++;
14144       else if (unformat (i, "map-t"))
14145         is_translation = 1;
14146       else
14147         {
14148           clib_warning ("parse error '%U'", format_unformat_error, i);
14149           return -99;
14150         }
14151     }
14152
14153   if (num_m_args < 3)
14154     {
14155       errmsg ("mandatory argument(s) missing");
14156       return -99;
14157     }
14158
14159   /* Construct the API message */
14160   M (MAP_ADD_DOMAIN, mp);
14161
14162   clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
14163   mp->ip4_prefix_len = ip4_prefix_len;
14164
14165   clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
14166   mp->ip6_prefix_len = ip6_prefix_len;
14167
14168   clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
14169   mp->ip6_src_prefix_len = ip6_src_len;
14170
14171   mp->ea_bits_len = ea_bits_len;
14172   mp->psid_offset = psid_offset;
14173   mp->psid_length = psid_length;
14174   mp->is_translation = is_translation;
14175   mp->mtu = htons (mtu);
14176
14177   /* send it... */
14178   S (mp);
14179
14180   /* Wait for a reply, return good/bad news  */
14181   W (ret);
14182   return ret;
14183 }
14184
14185 static int
14186 api_map_del_domain (vat_main_t * vam)
14187 {
14188   unformat_input_t *i = vam->input;
14189   vl_api_map_del_domain_t *mp;
14190
14191   u32 num_m_args = 0;
14192   u32 index;
14193   int ret;
14194
14195   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14196     {
14197       if (unformat (i, "index %d", &index))
14198         num_m_args++;
14199       else
14200         {
14201           clib_warning ("parse error '%U'", format_unformat_error, i);
14202           return -99;
14203         }
14204     }
14205
14206   if (num_m_args != 1)
14207     {
14208       errmsg ("mandatory argument(s) missing");
14209       return -99;
14210     }
14211
14212   /* Construct the API message */
14213   M (MAP_DEL_DOMAIN, mp);
14214
14215   mp->index = ntohl (index);
14216
14217   /* send it... */
14218   S (mp);
14219
14220   /* Wait for a reply, return good/bad news  */
14221   W (ret);
14222   return ret;
14223 }
14224
14225 static int
14226 api_map_add_del_rule (vat_main_t * vam)
14227 {
14228   unformat_input_t *i = vam->input;
14229   vl_api_map_add_del_rule_t *mp;
14230   u8 is_add = 1;
14231   ip6_address_t ip6_dst;
14232   u32 num_m_args = 0, index, psid = 0;
14233   int ret;
14234
14235   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14236     {
14237       if (unformat (i, "index %d", &index))
14238         num_m_args++;
14239       else if (unformat (i, "psid %d", &psid))
14240         num_m_args++;
14241       else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
14242         num_m_args++;
14243       else if (unformat (i, "del"))
14244         {
14245           is_add = 0;
14246         }
14247       else
14248         {
14249           clib_warning ("parse error '%U'", format_unformat_error, i);
14250           return -99;
14251         }
14252     }
14253
14254   /* Construct the API message */
14255   M (MAP_ADD_DEL_RULE, mp);
14256
14257   mp->index = ntohl (index);
14258   mp->is_add = is_add;
14259   clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
14260   mp->psid = ntohs (psid);
14261
14262   /* send it... */
14263   S (mp);
14264
14265   /* Wait for a reply, return good/bad news  */
14266   W (ret);
14267   return ret;
14268 }
14269
14270 static int
14271 api_map_domain_dump (vat_main_t * vam)
14272 {
14273   vl_api_map_domain_dump_t *mp;
14274   vl_api_control_ping_t *mp_ping;
14275   int ret;
14276
14277   /* Construct the API message */
14278   M (MAP_DOMAIN_DUMP, mp);
14279
14280   /* send it... */
14281   S (mp);
14282
14283   /* Use a control ping for synchronization */
14284   M (CONTROL_PING, mp_ping);
14285   S (mp_ping);
14286
14287   W (ret);
14288   return ret;
14289 }
14290
14291 static int
14292 api_map_rule_dump (vat_main_t * vam)
14293 {
14294   unformat_input_t *i = vam->input;
14295   vl_api_map_rule_dump_t *mp;
14296   vl_api_control_ping_t *mp_ping;
14297   u32 domain_index = ~0;
14298   int ret;
14299
14300   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14301     {
14302       if (unformat (i, "index %u", &domain_index))
14303         ;
14304       else
14305         break;
14306     }
14307
14308   if (domain_index == ~0)
14309     {
14310       clib_warning ("parse error: domain index expected");
14311       return -99;
14312     }
14313
14314   /* Construct the API message */
14315   M (MAP_RULE_DUMP, mp);
14316
14317   mp->domain_index = htonl (domain_index);
14318
14319   /* send it... */
14320   S (mp);
14321
14322   /* Use a control ping for synchronization */
14323   M (CONTROL_PING, mp_ping);
14324   S (mp_ping);
14325
14326   W (ret);
14327   return ret;
14328 }
14329
14330 static void vl_api_map_add_domain_reply_t_handler
14331   (vl_api_map_add_domain_reply_t * mp)
14332 {
14333   vat_main_t *vam = &vat_main;
14334   i32 retval = ntohl (mp->retval);
14335
14336   if (vam->async_mode)
14337     {
14338       vam->async_errors += (retval < 0);
14339     }
14340   else
14341     {
14342       vam->retval = retval;
14343       vam->result_ready = 1;
14344     }
14345 }
14346
14347 static void vl_api_map_add_domain_reply_t_handler_json
14348   (vl_api_map_add_domain_reply_t * mp)
14349 {
14350   vat_main_t *vam = &vat_main;
14351   vat_json_node_t node;
14352
14353   vat_json_init_object (&node);
14354   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
14355   vat_json_object_add_uint (&node, "index", ntohl (mp->index));
14356
14357   vat_json_print (vam->ofp, &node);
14358   vat_json_free (&node);
14359
14360   vam->retval = ntohl (mp->retval);
14361   vam->result_ready = 1;
14362 }
14363
14364 static int
14365 api_get_first_msg_id (vat_main_t * vam)
14366 {
14367   vl_api_get_first_msg_id_t *mp;
14368   unformat_input_t *i = vam->input;
14369   u8 *name;
14370   u8 name_set = 0;
14371   int ret;
14372
14373   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14374     {
14375       if (unformat (i, "client %s", &name))
14376         name_set = 1;
14377       else
14378         break;
14379     }
14380
14381   if (name_set == 0)
14382     {
14383       errmsg ("missing client name");
14384       return -99;
14385     }
14386   vec_add1 (name, 0);
14387
14388   if (vec_len (name) > 63)
14389     {
14390       errmsg ("client name too long");
14391       return -99;
14392     }
14393
14394   M (GET_FIRST_MSG_ID, mp);
14395   clib_memcpy (mp->name, name, vec_len (name));
14396   S (mp);
14397   W (ret);
14398   return ret;
14399 }
14400
14401 static int
14402 api_cop_interface_enable_disable (vat_main_t * vam)
14403 {
14404   unformat_input_t *line_input = vam->input;
14405   vl_api_cop_interface_enable_disable_t *mp;
14406   u32 sw_if_index = ~0;
14407   u8 enable_disable = 1;
14408   int ret;
14409
14410   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14411     {
14412       if (unformat (line_input, "disable"))
14413         enable_disable = 0;
14414       if (unformat (line_input, "enable"))
14415         enable_disable = 1;
14416       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
14417                          vam, &sw_if_index))
14418         ;
14419       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14420         ;
14421       else
14422         break;
14423     }
14424
14425   if (sw_if_index == ~0)
14426     {
14427       errmsg ("missing interface name or sw_if_index");
14428       return -99;
14429     }
14430
14431   /* Construct the API message */
14432   M (COP_INTERFACE_ENABLE_DISABLE, mp);
14433   mp->sw_if_index = ntohl (sw_if_index);
14434   mp->enable_disable = enable_disable;
14435
14436   /* send it... */
14437   S (mp);
14438   /* Wait for the reply */
14439   W (ret);
14440   return ret;
14441 }
14442
14443 static int
14444 api_cop_whitelist_enable_disable (vat_main_t * vam)
14445 {
14446   unformat_input_t *line_input = vam->input;
14447   vl_api_cop_whitelist_enable_disable_t *mp;
14448   u32 sw_if_index = ~0;
14449   u8 ip4 = 0, ip6 = 0, default_cop = 0;
14450   u32 fib_id = 0;
14451   int ret;
14452
14453   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14454     {
14455       if (unformat (line_input, "ip4"))
14456         ip4 = 1;
14457       else if (unformat (line_input, "ip6"))
14458         ip6 = 1;
14459       else if (unformat (line_input, "default"))
14460         default_cop = 1;
14461       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
14462                          vam, &sw_if_index))
14463         ;
14464       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14465         ;
14466       else if (unformat (line_input, "fib-id %d", &fib_id))
14467         ;
14468       else
14469         break;
14470     }
14471
14472   if (sw_if_index == ~0)
14473     {
14474       errmsg ("missing interface name or sw_if_index");
14475       return -99;
14476     }
14477
14478   /* Construct the API message */
14479   M (COP_WHITELIST_ENABLE_DISABLE, mp);
14480   mp->sw_if_index = ntohl (sw_if_index);
14481   mp->fib_id = ntohl (fib_id);
14482   mp->ip4 = ip4;
14483   mp->ip6 = ip6;
14484   mp->default_cop = default_cop;
14485
14486   /* send it... */
14487   S (mp);
14488   /* Wait for the reply */
14489   W (ret);
14490   return ret;
14491 }
14492
14493 static int
14494 api_get_node_graph (vat_main_t * vam)
14495 {
14496   vl_api_get_node_graph_t *mp;
14497   int ret;
14498
14499   M (GET_NODE_GRAPH, mp);
14500
14501   /* send it... */
14502   S (mp);
14503   /* Wait for the reply */
14504   W (ret);
14505   return ret;
14506 }
14507
14508 /* *INDENT-OFF* */
14509 /** Used for parsing LISP eids */
14510 typedef CLIB_PACKED(struct{
14511   u8 addr[16];   /**< eid address */
14512   u32 len;       /**< prefix length if IP */
14513   u8 type;      /**< type of eid */
14514 }) lisp_eid_vat_t;
14515 /* *INDENT-ON* */
14516
14517 static uword
14518 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
14519 {
14520   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
14521
14522   memset (a, 0, sizeof (a[0]));
14523
14524   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
14525     {
14526       a->type = 0;              /* ipv4 type */
14527     }
14528   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
14529     {
14530       a->type = 1;              /* ipv6 type */
14531     }
14532   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
14533     {
14534       a->type = 2;              /* mac type */
14535     }
14536   else if (unformat (input, "%U", unformat_nsh_address, a->addr))
14537     {
14538       a->type = 3;              /* NSH type */
14539       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) a->addr;
14540       nsh->spi = clib_host_to_net_u32 (nsh->spi);
14541     }
14542   else
14543     {
14544       return 0;
14545     }
14546
14547   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
14548     {
14549       return 0;
14550     }
14551
14552   return 1;
14553 }
14554
14555 static int
14556 lisp_eid_size_vat (u8 type)
14557 {
14558   switch (type)
14559     {
14560     case 0:
14561       return 4;
14562     case 1:
14563       return 16;
14564     case 2:
14565       return 6;
14566     case 3:
14567       return 5;
14568     }
14569   return 0;
14570 }
14571
14572 static void
14573 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
14574 {
14575   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
14576 }
14577
14578 static int
14579 api_one_add_del_locator_set (vat_main_t * vam)
14580 {
14581   unformat_input_t *input = vam->input;
14582   vl_api_one_add_del_locator_set_t *mp;
14583   u8 is_add = 1;
14584   u8 *locator_set_name = NULL;
14585   u8 locator_set_name_set = 0;
14586   vl_api_local_locator_t locator, *locators = 0;
14587   u32 sw_if_index, priority, weight;
14588   u32 data_len = 0;
14589
14590   int ret;
14591   /* Parse args required to build the message */
14592   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14593     {
14594       if (unformat (input, "del"))
14595         {
14596           is_add = 0;
14597         }
14598       else if (unformat (input, "locator-set %s", &locator_set_name))
14599         {
14600           locator_set_name_set = 1;
14601         }
14602       else if (unformat (input, "sw_if_index %u p %u w %u",
14603                          &sw_if_index, &priority, &weight))
14604         {
14605           locator.sw_if_index = htonl (sw_if_index);
14606           locator.priority = priority;
14607           locator.weight = weight;
14608           vec_add1 (locators, locator);
14609         }
14610       else
14611         if (unformat
14612             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
14613              &sw_if_index, &priority, &weight))
14614         {
14615           locator.sw_if_index = htonl (sw_if_index);
14616           locator.priority = priority;
14617           locator.weight = weight;
14618           vec_add1 (locators, locator);
14619         }
14620       else
14621         break;
14622     }
14623
14624   if (locator_set_name_set == 0)
14625     {
14626       errmsg ("missing locator-set name");
14627       vec_free (locators);
14628       return -99;
14629     }
14630
14631   if (vec_len (locator_set_name) > 64)
14632     {
14633       errmsg ("locator-set name too long");
14634       vec_free (locator_set_name);
14635       vec_free (locators);
14636       return -99;
14637     }
14638   vec_add1 (locator_set_name, 0);
14639
14640   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
14641
14642   /* Construct the API message */
14643   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
14644
14645   mp->is_add = is_add;
14646   clib_memcpy (mp->locator_set_name, locator_set_name,
14647                vec_len (locator_set_name));
14648   vec_free (locator_set_name);
14649
14650   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
14651   if (locators)
14652     clib_memcpy (mp->locators, locators, data_len);
14653   vec_free (locators);
14654
14655   /* send it... */
14656   S (mp);
14657
14658   /* Wait for a reply... */
14659   W (ret);
14660   return ret;
14661 }
14662
14663 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
14664
14665 static int
14666 api_one_add_del_locator (vat_main_t * vam)
14667 {
14668   unformat_input_t *input = vam->input;
14669   vl_api_one_add_del_locator_t *mp;
14670   u32 tmp_if_index = ~0;
14671   u32 sw_if_index = ~0;
14672   u8 sw_if_index_set = 0;
14673   u8 sw_if_index_if_name_set = 0;
14674   u32 priority = ~0;
14675   u8 priority_set = 0;
14676   u32 weight = ~0;
14677   u8 weight_set = 0;
14678   u8 is_add = 1;
14679   u8 *locator_set_name = NULL;
14680   u8 locator_set_name_set = 0;
14681   int ret;
14682
14683   /* Parse args required to build the message */
14684   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14685     {
14686       if (unformat (input, "del"))
14687         {
14688           is_add = 0;
14689         }
14690       else if (unformat (input, "locator-set %s", &locator_set_name))
14691         {
14692           locator_set_name_set = 1;
14693         }
14694       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
14695                          &tmp_if_index))
14696         {
14697           sw_if_index_if_name_set = 1;
14698           sw_if_index = tmp_if_index;
14699         }
14700       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
14701         {
14702           sw_if_index_set = 1;
14703           sw_if_index = tmp_if_index;
14704         }
14705       else if (unformat (input, "p %d", &priority))
14706         {
14707           priority_set = 1;
14708         }
14709       else if (unformat (input, "w %d", &weight))
14710         {
14711           weight_set = 1;
14712         }
14713       else
14714         break;
14715     }
14716
14717   if (locator_set_name_set == 0)
14718     {
14719       errmsg ("missing locator-set name");
14720       return -99;
14721     }
14722
14723   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
14724     {
14725       errmsg ("missing sw_if_index");
14726       vec_free (locator_set_name);
14727       return -99;
14728     }
14729
14730   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
14731     {
14732       errmsg ("cannot use both params interface name and sw_if_index");
14733       vec_free (locator_set_name);
14734       return -99;
14735     }
14736
14737   if (priority_set == 0)
14738     {
14739       errmsg ("missing locator-set priority");
14740       vec_free (locator_set_name);
14741       return -99;
14742     }
14743
14744   if (weight_set == 0)
14745     {
14746       errmsg ("missing locator-set weight");
14747       vec_free (locator_set_name);
14748       return -99;
14749     }
14750
14751   if (vec_len (locator_set_name) > 64)
14752     {
14753       errmsg ("locator-set name too long");
14754       vec_free (locator_set_name);
14755       return -99;
14756     }
14757   vec_add1 (locator_set_name, 0);
14758
14759   /* Construct the API message */
14760   M (ONE_ADD_DEL_LOCATOR, mp);
14761
14762   mp->is_add = is_add;
14763   mp->sw_if_index = ntohl (sw_if_index);
14764   mp->priority = priority;
14765   mp->weight = weight;
14766   clib_memcpy (mp->locator_set_name, locator_set_name,
14767                vec_len (locator_set_name));
14768   vec_free (locator_set_name);
14769
14770   /* send it... */
14771   S (mp);
14772
14773   /* Wait for a reply... */
14774   W (ret);
14775   return ret;
14776 }
14777
14778 #define api_lisp_add_del_locator api_one_add_del_locator
14779
14780 uword
14781 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
14782 {
14783   u32 *key_id = va_arg (*args, u32 *);
14784   u8 *s = 0;
14785
14786   if (unformat (input, "%s", &s))
14787     {
14788       if (!strcmp ((char *) s, "sha1"))
14789         key_id[0] = HMAC_SHA_1_96;
14790       else if (!strcmp ((char *) s, "sha256"))
14791         key_id[0] = HMAC_SHA_256_128;
14792       else
14793         {
14794           clib_warning ("invalid key_id: '%s'", s);
14795           key_id[0] = HMAC_NO_KEY;
14796         }
14797     }
14798   else
14799     return 0;
14800
14801   vec_free (s);
14802   return 1;
14803 }
14804
14805 static int
14806 api_one_add_del_local_eid (vat_main_t * vam)
14807 {
14808   unformat_input_t *input = vam->input;
14809   vl_api_one_add_del_local_eid_t *mp;
14810   u8 is_add = 1;
14811   u8 eid_set = 0;
14812   lisp_eid_vat_t _eid, *eid = &_eid;
14813   u8 *locator_set_name = 0;
14814   u8 locator_set_name_set = 0;
14815   u32 vni = 0;
14816   u16 key_id = 0;
14817   u8 *key = 0;
14818   int ret;
14819
14820   /* Parse args required to build the message */
14821   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14822     {
14823       if (unformat (input, "del"))
14824         {
14825           is_add = 0;
14826         }
14827       else if (unformat (input, "vni %d", &vni))
14828         {
14829           ;
14830         }
14831       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
14832         {
14833           eid_set = 1;
14834         }
14835       else if (unformat (input, "locator-set %s", &locator_set_name))
14836         {
14837           locator_set_name_set = 1;
14838         }
14839       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
14840         ;
14841       else if (unformat (input, "secret-key %_%v%_", &key))
14842         ;
14843       else
14844         break;
14845     }
14846
14847   if (locator_set_name_set == 0)
14848     {
14849       errmsg ("missing locator-set name");
14850       return -99;
14851     }
14852
14853   if (0 == eid_set)
14854     {
14855       errmsg ("EID address not set!");
14856       vec_free (locator_set_name);
14857       return -99;
14858     }
14859
14860   if (key && (0 == key_id))
14861     {
14862       errmsg ("invalid key_id!");
14863       return -99;
14864     }
14865
14866   if (vec_len (key) > 64)
14867     {
14868       errmsg ("key too long");
14869       vec_free (key);
14870       return -99;
14871     }
14872
14873   if (vec_len (locator_set_name) > 64)
14874     {
14875       errmsg ("locator-set name too long");
14876       vec_free (locator_set_name);
14877       return -99;
14878     }
14879   vec_add1 (locator_set_name, 0);
14880
14881   /* Construct the API message */
14882   M (ONE_ADD_DEL_LOCAL_EID, mp);
14883
14884   mp->is_add = is_add;
14885   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
14886   mp->eid_type = eid->type;
14887   mp->prefix_len = eid->len;
14888   mp->vni = clib_host_to_net_u32 (vni);
14889   mp->key_id = clib_host_to_net_u16 (key_id);
14890   clib_memcpy (mp->locator_set_name, locator_set_name,
14891                vec_len (locator_set_name));
14892   clib_memcpy (mp->key, key, vec_len (key));
14893
14894   vec_free (locator_set_name);
14895   vec_free (key);
14896
14897   /* send it... */
14898   S (mp);
14899
14900   /* Wait for a reply... */
14901   W (ret);
14902   return ret;
14903 }
14904
14905 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
14906
14907 static int
14908 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
14909 {
14910   u32 dp_table = 0, vni = 0;;
14911   unformat_input_t *input = vam->input;
14912   vl_api_gpe_add_del_fwd_entry_t *mp;
14913   u8 is_add = 1;
14914   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
14915   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
14916   u8 rmt_eid_set = 0, lcl_eid_set = 0;
14917   u32 action = ~0, w;
14918   ip4_address_t rmt_rloc4, lcl_rloc4;
14919   ip6_address_t rmt_rloc6, lcl_rloc6;
14920   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
14921   int ret;
14922
14923   memset (&rloc, 0, sizeof (rloc));
14924
14925   /* Parse args required to build the message */
14926   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14927     {
14928       if (unformat (input, "del"))
14929         is_add = 0;
14930       else if (unformat (input, "add"))
14931         is_add = 1;
14932       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
14933         {
14934           rmt_eid_set = 1;
14935         }
14936       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
14937         {
14938           lcl_eid_set = 1;
14939         }
14940       else if (unformat (input, "vrf %d", &dp_table))
14941         ;
14942       else if (unformat (input, "bd %d", &dp_table))
14943         ;
14944       else if (unformat (input, "vni %d", &vni))
14945         ;
14946       else if (unformat (input, "w %d", &w))
14947         {
14948           if (!curr_rloc)
14949             {
14950               errmsg ("No RLOC configured for setting priority/weight!");
14951               return -99;
14952             }
14953           curr_rloc->weight = w;
14954         }
14955       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
14956                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
14957         {
14958           rloc.is_ip4 = 1;
14959
14960           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
14961           rloc.weight = 0;
14962           vec_add1 (lcl_locs, rloc);
14963
14964           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
14965           vec_add1 (rmt_locs, rloc);
14966           /* weight saved in rmt loc */
14967           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
14968         }
14969       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
14970                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
14971         {
14972           rloc.is_ip4 = 0;
14973           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
14974           rloc.weight = 0;
14975           vec_add1 (lcl_locs, rloc);
14976
14977           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
14978           vec_add1 (rmt_locs, rloc);
14979           /* weight saved in rmt loc */
14980           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
14981         }
14982       else if (unformat (input, "action %d", &action))
14983         {
14984           ;
14985         }
14986       else
14987         {
14988           clib_warning ("parse error '%U'", format_unformat_error, input);
14989           return -99;
14990         }
14991     }
14992
14993   if (!rmt_eid_set)
14994     {
14995       errmsg ("remote eid addresses not set");
14996       return -99;
14997     }
14998
14999   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
15000     {
15001       errmsg ("eid types don't match");
15002       return -99;
15003     }
15004
15005   if (0 == rmt_locs && (u32) ~ 0 == action)
15006     {
15007       errmsg ("action not set for negative mapping");
15008       return -99;
15009     }
15010
15011   /* Construct the API message */
15012   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
15013       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
15014
15015   mp->is_add = is_add;
15016   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
15017   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
15018   mp->eid_type = rmt_eid->type;
15019   mp->dp_table = clib_host_to_net_u32 (dp_table);
15020   mp->vni = clib_host_to_net_u32 (vni);
15021   mp->rmt_len = rmt_eid->len;
15022   mp->lcl_len = lcl_eid->len;
15023   mp->action = action;
15024
15025   if (0 != rmt_locs && 0 != lcl_locs)
15026     {
15027       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
15028       clib_memcpy (mp->locs, lcl_locs,
15029                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
15030
15031       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
15032       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
15033                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
15034     }
15035   vec_free (lcl_locs);
15036   vec_free (rmt_locs);
15037
15038   /* send it... */
15039   S (mp);
15040
15041   /* Wait for a reply... */
15042   W (ret);
15043   return ret;
15044 }
15045
15046 static int
15047 api_one_add_del_map_server (vat_main_t * vam)
15048 {
15049   unformat_input_t *input = vam->input;
15050   vl_api_one_add_del_map_server_t *mp;
15051   u8 is_add = 1;
15052   u8 ipv4_set = 0;
15053   u8 ipv6_set = 0;
15054   ip4_address_t ipv4;
15055   ip6_address_t ipv6;
15056   int ret;
15057
15058   /* Parse args required to build the message */
15059   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15060     {
15061       if (unformat (input, "del"))
15062         {
15063           is_add = 0;
15064         }
15065       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
15066         {
15067           ipv4_set = 1;
15068         }
15069       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
15070         {
15071           ipv6_set = 1;
15072         }
15073       else
15074         break;
15075     }
15076
15077   if (ipv4_set && ipv6_set)
15078     {
15079       errmsg ("both eid v4 and v6 addresses set");
15080       return -99;
15081     }
15082
15083   if (!ipv4_set && !ipv6_set)
15084     {
15085       errmsg ("eid addresses not set");
15086       return -99;
15087     }
15088
15089   /* Construct the API message */
15090   M (ONE_ADD_DEL_MAP_SERVER, mp);
15091
15092   mp->is_add = is_add;
15093   if (ipv6_set)
15094     {
15095       mp->is_ipv6 = 1;
15096       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
15097     }
15098   else
15099     {
15100       mp->is_ipv6 = 0;
15101       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
15102     }
15103
15104   /* send it... */
15105   S (mp);
15106
15107   /* Wait for a reply... */
15108   W (ret);
15109   return ret;
15110 }
15111
15112 #define api_lisp_add_del_map_server api_one_add_del_map_server
15113
15114 static int
15115 api_one_add_del_map_resolver (vat_main_t * vam)
15116 {
15117   unformat_input_t *input = vam->input;
15118   vl_api_one_add_del_map_resolver_t *mp;
15119   u8 is_add = 1;
15120   u8 ipv4_set = 0;
15121   u8 ipv6_set = 0;
15122   ip4_address_t ipv4;
15123   ip6_address_t ipv6;
15124   int ret;
15125
15126   /* Parse args required to build the message */
15127   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15128     {
15129       if (unformat (input, "del"))
15130         {
15131           is_add = 0;
15132         }
15133       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
15134         {
15135           ipv4_set = 1;
15136         }
15137       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
15138         {
15139           ipv6_set = 1;
15140         }
15141       else
15142         break;
15143     }
15144
15145   if (ipv4_set && ipv6_set)
15146     {
15147       errmsg ("both eid v4 and v6 addresses set");
15148       return -99;
15149     }
15150
15151   if (!ipv4_set && !ipv6_set)
15152     {
15153       errmsg ("eid addresses not set");
15154       return -99;
15155     }
15156
15157   /* Construct the API message */
15158   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
15159
15160   mp->is_add = is_add;
15161   if (ipv6_set)
15162     {
15163       mp->is_ipv6 = 1;
15164       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
15165     }
15166   else
15167     {
15168       mp->is_ipv6 = 0;
15169       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
15170     }
15171
15172   /* send it... */
15173   S (mp);
15174
15175   /* Wait for a reply... */
15176   W (ret);
15177   return ret;
15178 }
15179
15180 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
15181
15182 static int
15183 api_lisp_gpe_enable_disable (vat_main_t * vam)
15184 {
15185   unformat_input_t *input = vam->input;
15186   vl_api_gpe_enable_disable_t *mp;
15187   u8 is_set = 0;
15188   u8 is_en = 1;
15189   int ret;
15190
15191   /* Parse args required to build the message */
15192   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15193     {
15194       if (unformat (input, "enable"))
15195         {
15196           is_set = 1;
15197           is_en = 1;
15198         }
15199       else if (unformat (input, "disable"))
15200         {
15201           is_set = 1;
15202           is_en = 0;
15203         }
15204       else
15205         break;
15206     }
15207
15208   if (is_set == 0)
15209     {
15210       errmsg ("Value not set");
15211       return -99;
15212     }
15213
15214   /* Construct the API message */
15215   M (GPE_ENABLE_DISABLE, mp);
15216
15217   mp->is_en = is_en;
15218
15219   /* send it... */
15220   S (mp);
15221
15222   /* Wait for a reply... */
15223   W (ret);
15224   return ret;
15225 }
15226
15227 static int
15228 api_one_rloc_probe_enable_disable (vat_main_t * vam)
15229 {
15230   unformat_input_t *input = vam->input;
15231   vl_api_one_rloc_probe_enable_disable_t *mp;
15232   u8 is_set = 0;
15233   u8 is_en = 0;
15234   int ret;
15235
15236   /* Parse args required to build the message */
15237   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15238     {
15239       if (unformat (input, "enable"))
15240         {
15241           is_set = 1;
15242           is_en = 1;
15243         }
15244       else if (unformat (input, "disable"))
15245         is_set = 1;
15246       else
15247         break;
15248     }
15249
15250   if (!is_set)
15251     {
15252       errmsg ("Value not set");
15253       return -99;
15254     }
15255
15256   /* Construct the API message */
15257   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
15258
15259   mp->is_enabled = is_en;
15260
15261   /* send it... */
15262   S (mp);
15263
15264   /* Wait for a reply... */
15265   W (ret);
15266   return ret;
15267 }
15268
15269 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
15270
15271 static int
15272 api_one_map_register_enable_disable (vat_main_t * vam)
15273 {
15274   unformat_input_t *input = vam->input;
15275   vl_api_one_map_register_enable_disable_t *mp;
15276   u8 is_set = 0;
15277   u8 is_en = 0;
15278   int ret;
15279
15280   /* Parse args required to build the message */
15281   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15282     {
15283       if (unformat (input, "enable"))
15284         {
15285           is_set = 1;
15286           is_en = 1;
15287         }
15288       else if (unformat (input, "disable"))
15289         is_set = 1;
15290       else
15291         break;
15292     }
15293
15294   if (!is_set)
15295     {
15296       errmsg ("Value not set");
15297       return -99;
15298     }
15299
15300   /* Construct the API message */
15301   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
15302
15303   mp->is_enabled = is_en;
15304
15305   /* send it... */
15306   S (mp);
15307
15308   /* Wait for a reply... */
15309   W (ret);
15310   return ret;
15311 }
15312
15313 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
15314
15315 static int
15316 api_one_enable_disable (vat_main_t * vam)
15317 {
15318   unformat_input_t *input = vam->input;
15319   vl_api_one_enable_disable_t *mp;
15320   u8 is_set = 0;
15321   u8 is_en = 0;
15322   int ret;
15323
15324   /* Parse args required to build the message */
15325   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15326     {
15327       if (unformat (input, "enable"))
15328         {
15329           is_set = 1;
15330           is_en = 1;
15331         }
15332       else if (unformat (input, "disable"))
15333         {
15334           is_set = 1;
15335         }
15336       else
15337         break;
15338     }
15339
15340   if (!is_set)
15341     {
15342       errmsg ("Value not set");
15343       return -99;
15344     }
15345
15346   /* Construct the API message */
15347   M (ONE_ENABLE_DISABLE, mp);
15348
15349   mp->is_en = is_en;
15350
15351   /* send it... */
15352   S (mp);
15353
15354   /* Wait for a reply... */
15355   W (ret);
15356   return ret;
15357 }
15358
15359 #define api_lisp_enable_disable api_one_enable_disable
15360
15361 static int
15362 api_show_one_map_register_state (vat_main_t * vam)
15363 {
15364   vl_api_show_one_map_register_state_t *mp;
15365   int ret;
15366
15367   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
15368
15369   /* send */
15370   S (mp);
15371
15372   /* wait for reply */
15373   W (ret);
15374   return ret;
15375 }
15376
15377 #define api_show_lisp_map_register_state api_show_one_map_register_state
15378
15379 static int
15380 api_show_one_rloc_probe_state (vat_main_t * vam)
15381 {
15382   vl_api_show_one_rloc_probe_state_t *mp;
15383   int ret;
15384
15385   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
15386
15387   /* send */
15388   S (mp);
15389
15390   /* wait for reply */
15391   W (ret);
15392   return ret;
15393 }
15394
15395 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
15396
15397 static int
15398 api_one_add_del_l2_arp_entry (vat_main_t * vam)
15399 {
15400   vl_api_one_add_del_l2_arp_entry_t *mp;
15401   unformat_input_t *input = vam->input;
15402   u8 is_add = 1;
15403   u8 mac_set = 0;
15404   u8 bd_set = 0;
15405   u8 ip_set = 0;
15406   u8 mac[6] = { 0, };
15407   u32 ip4 = 0, bd = ~0;
15408   int ret;
15409
15410   /* Parse args required to build the message */
15411   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15412     {
15413       if (unformat (input, "del"))
15414         is_add = 0;
15415       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
15416         mac_set = 1;
15417       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
15418         ip_set = 1;
15419       else if (unformat (input, "bd %d", &bd))
15420         bd_set = 1;
15421       else
15422         {
15423           errmsg ("parse error '%U'", format_unformat_error, input);
15424           return -99;
15425         }
15426     }
15427
15428   if (!bd_set || !ip_set || (!mac_set && is_add))
15429     {
15430       errmsg ("Missing BD, IP or MAC!");
15431       return -99;
15432     }
15433
15434   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
15435   mp->is_add = is_add;
15436   clib_memcpy (mp->mac, mac, 6);
15437   mp->bd = clib_host_to_net_u32 (bd);
15438   mp->ip4 = ip4;
15439
15440   /* send */
15441   S (mp);
15442
15443   /* wait for reply */
15444   W (ret);
15445   return ret;
15446 }
15447
15448 static int
15449 api_one_l2_arp_bd_get (vat_main_t * vam)
15450 {
15451   vl_api_one_l2_arp_bd_get_t *mp;
15452   int ret;
15453
15454   M (ONE_L2_ARP_BD_GET, mp);
15455
15456   /* send */
15457   S (mp);
15458
15459   /* wait for reply */
15460   W (ret);
15461   return ret;
15462 }
15463
15464 static int
15465 api_one_l2_arp_entries_get (vat_main_t * vam)
15466 {
15467   vl_api_one_l2_arp_entries_get_t *mp;
15468   unformat_input_t *input = vam->input;
15469   u8 bd_set = 0;
15470   u32 bd = ~0;
15471   int ret;
15472
15473   /* Parse args required to build the message */
15474   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15475     {
15476       if (unformat (input, "bd %d", &bd))
15477         bd_set = 1;
15478       else
15479         {
15480           errmsg ("parse error '%U'", format_unformat_error, input);
15481           return -99;
15482         }
15483     }
15484
15485   if (!bd_set)
15486     {
15487       errmsg ("Expected bridge domain!");
15488       return -99;
15489     }
15490
15491   M (ONE_L2_ARP_ENTRIES_GET, mp);
15492   mp->bd = clib_host_to_net_u32 (bd);
15493
15494   /* send */
15495   S (mp);
15496
15497   /* wait for reply */
15498   W (ret);
15499   return ret;
15500 }
15501
15502 static int
15503 api_one_stats_enable_disable (vat_main_t * vam)
15504 {
15505   vl_api_one_stats_enable_disable_t *mp;
15506   unformat_input_t *input = vam->input;
15507   u8 is_set = 0;
15508   u8 is_en = 0;
15509   int ret;
15510
15511   /* Parse args required to build the message */
15512   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15513     {
15514       if (unformat (input, "enable"))
15515         {
15516           is_set = 1;
15517           is_en = 1;
15518         }
15519       else if (unformat (input, "disable"))
15520         {
15521           is_set = 1;
15522         }
15523       else
15524         break;
15525     }
15526
15527   if (!is_set)
15528     {
15529       errmsg ("Value not set");
15530       return -99;
15531     }
15532
15533   M (ONE_STATS_ENABLE_DISABLE, mp);
15534   mp->is_en = is_en;
15535
15536   /* send */
15537   S (mp);
15538
15539   /* wait for reply */
15540   W (ret);
15541   return ret;
15542 }
15543
15544 static int
15545 api_show_one_stats_enable_disable (vat_main_t * vam)
15546 {
15547   vl_api_show_one_stats_enable_disable_t *mp;
15548   int ret;
15549
15550   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
15551
15552   /* send */
15553   S (mp);
15554
15555   /* wait for reply */
15556   W (ret);
15557   return ret;
15558 }
15559
15560 static int
15561 api_show_one_map_request_mode (vat_main_t * vam)
15562 {
15563   vl_api_show_one_map_request_mode_t *mp;
15564   int ret;
15565
15566   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
15567
15568   /* send */
15569   S (mp);
15570
15571   /* wait for reply */
15572   W (ret);
15573   return ret;
15574 }
15575
15576 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
15577
15578 static int
15579 api_one_map_request_mode (vat_main_t * vam)
15580 {
15581   unformat_input_t *input = vam->input;
15582   vl_api_one_map_request_mode_t *mp;
15583   u8 mode = 0;
15584   int ret;
15585
15586   /* Parse args required to build the message */
15587   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15588     {
15589       if (unformat (input, "dst-only"))
15590         mode = 0;
15591       else if (unformat (input, "src-dst"))
15592         mode = 1;
15593       else
15594         {
15595           errmsg ("parse error '%U'", format_unformat_error, input);
15596           return -99;
15597         }
15598     }
15599
15600   M (ONE_MAP_REQUEST_MODE, mp);
15601
15602   mp->mode = mode;
15603
15604   /* send */
15605   S (mp);
15606
15607   /* wait for reply */
15608   W (ret);
15609   return ret;
15610 }
15611
15612 #define api_lisp_map_request_mode api_one_map_request_mode
15613
15614 /**
15615  * Enable/disable ONE proxy ITR.
15616  *
15617  * @param vam vpp API test context
15618  * @return return code
15619  */
15620 static int
15621 api_one_pitr_set_locator_set (vat_main_t * vam)
15622 {
15623   u8 ls_name_set = 0;
15624   unformat_input_t *input = vam->input;
15625   vl_api_one_pitr_set_locator_set_t *mp;
15626   u8 is_add = 1;
15627   u8 *ls_name = 0;
15628   int ret;
15629
15630   /* Parse args required to build the message */
15631   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15632     {
15633       if (unformat (input, "del"))
15634         is_add = 0;
15635       else if (unformat (input, "locator-set %s", &ls_name))
15636         ls_name_set = 1;
15637       else
15638         {
15639           errmsg ("parse error '%U'", format_unformat_error, input);
15640           return -99;
15641         }
15642     }
15643
15644   if (!ls_name_set)
15645     {
15646       errmsg ("locator-set name not set!");
15647       return -99;
15648     }
15649
15650   M (ONE_PITR_SET_LOCATOR_SET, mp);
15651
15652   mp->is_add = is_add;
15653   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
15654   vec_free (ls_name);
15655
15656   /* send */
15657   S (mp);
15658
15659   /* wait for reply */
15660   W (ret);
15661   return ret;
15662 }
15663
15664 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
15665
15666 static int
15667 api_one_nsh_set_locator_set (vat_main_t * vam)
15668 {
15669   u8 ls_name_set = 0;
15670   unformat_input_t *input = vam->input;
15671   vl_api_one_nsh_set_locator_set_t *mp;
15672   u8 is_add = 1;
15673   u8 *ls_name = 0;
15674   int ret;
15675
15676   /* Parse args required to build the message */
15677   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15678     {
15679       if (unformat (input, "del"))
15680         is_add = 0;
15681       else if (unformat (input, "ls %s", &ls_name))
15682         ls_name_set = 1;
15683       else
15684         {
15685           errmsg ("parse error '%U'", format_unformat_error, input);
15686           return -99;
15687         }
15688     }
15689
15690   if (!ls_name_set && is_add)
15691     {
15692       errmsg ("locator-set name not set!");
15693       return -99;
15694     }
15695
15696   M (ONE_NSH_SET_LOCATOR_SET, mp);
15697
15698   mp->is_add = is_add;
15699   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
15700   vec_free (ls_name);
15701
15702   /* send */
15703   S (mp);
15704
15705   /* wait for reply */
15706   W (ret);
15707   return ret;
15708 }
15709
15710 static int
15711 api_show_one_pitr (vat_main_t * vam)
15712 {
15713   vl_api_show_one_pitr_t *mp;
15714   int ret;
15715
15716   if (!vam->json_output)
15717     {
15718       print (vam->ofp, "%=20s", "lisp status:");
15719     }
15720
15721   M (SHOW_ONE_PITR, mp);
15722   /* send it... */
15723   S (mp);
15724
15725   /* Wait for a reply... */
15726   W (ret);
15727   return ret;
15728 }
15729
15730 #define api_show_lisp_pitr api_show_one_pitr
15731
15732 static int
15733 api_one_use_petr (vat_main_t * vam)
15734 {
15735   unformat_input_t *input = vam->input;
15736   vl_api_one_use_petr_t *mp;
15737   u8 is_add = 0;
15738   ip_address_t ip;
15739   int ret;
15740
15741   memset (&ip, 0, sizeof (ip));
15742
15743   /* Parse args required to build the message */
15744   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15745     {
15746       if (unformat (input, "disable"))
15747         is_add = 0;
15748       else
15749         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
15750         {
15751           is_add = 1;
15752           ip_addr_version (&ip) = IP4;
15753         }
15754       else
15755         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
15756         {
15757           is_add = 1;
15758           ip_addr_version (&ip) = IP6;
15759         }
15760       else
15761         {
15762           errmsg ("parse error '%U'", format_unformat_error, input);
15763           return -99;
15764         }
15765     }
15766
15767   M (ONE_USE_PETR, mp);
15768
15769   mp->is_add = is_add;
15770   if (is_add)
15771     {
15772       mp->is_ip4 = ip_addr_version (&ip) == IP4 ? 1 : 0;
15773       if (mp->is_ip4)
15774         clib_memcpy (mp->address, &ip, 4);
15775       else
15776         clib_memcpy (mp->address, &ip, 16);
15777     }
15778
15779   /* send */
15780   S (mp);
15781
15782   /* wait for reply */
15783   W (ret);
15784   return ret;
15785 }
15786
15787 #define api_lisp_use_petr api_one_use_petr
15788
15789 static int
15790 api_show_one_nsh_mapping (vat_main_t * vam)
15791 {
15792   vl_api_show_one_use_petr_t *mp;
15793   int ret;
15794
15795   if (!vam->json_output)
15796     {
15797       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
15798     }
15799
15800   M (SHOW_ONE_NSH_MAPPING, mp);
15801   /* send it... */
15802   S (mp);
15803
15804   /* Wait for a reply... */
15805   W (ret);
15806   return ret;
15807 }
15808
15809 static int
15810 api_show_one_use_petr (vat_main_t * vam)
15811 {
15812   vl_api_show_one_use_petr_t *mp;
15813   int ret;
15814
15815   if (!vam->json_output)
15816     {
15817       print (vam->ofp, "%=20s", "Proxy-ETR status:");
15818     }
15819
15820   M (SHOW_ONE_USE_PETR, mp);
15821   /* send it... */
15822   S (mp);
15823
15824   /* Wait for a reply... */
15825   W (ret);
15826   return ret;
15827 }
15828
15829 #define api_show_lisp_use_petr api_show_one_use_petr
15830
15831 /**
15832  * Add/delete mapping between vni and vrf
15833  */
15834 static int
15835 api_one_eid_table_add_del_map (vat_main_t * vam)
15836 {
15837   unformat_input_t *input = vam->input;
15838   vl_api_one_eid_table_add_del_map_t *mp;
15839   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
15840   u32 vni, vrf, bd_index;
15841   int ret;
15842
15843   /* Parse args required to build the message */
15844   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15845     {
15846       if (unformat (input, "del"))
15847         is_add = 0;
15848       else if (unformat (input, "vrf %d", &vrf))
15849         vrf_set = 1;
15850       else if (unformat (input, "bd_index %d", &bd_index))
15851         bd_index_set = 1;
15852       else if (unformat (input, "vni %d", &vni))
15853         vni_set = 1;
15854       else
15855         break;
15856     }
15857
15858   if (!vni_set || (!vrf_set && !bd_index_set))
15859     {
15860       errmsg ("missing arguments!");
15861       return -99;
15862     }
15863
15864   if (vrf_set && bd_index_set)
15865     {
15866       errmsg ("error: both vrf and bd entered!");
15867       return -99;
15868     }
15869
15870   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
15871
15872   mp->is_add = is_add;
15873   mp->vni = htonl (vni);
15874   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
15875   mp->is_l2 = bd_index_set;
15876
15877   /* send */
15878   S (mp);
15879
15880   /* wait for reply */
15881   W (ret);
15882   return ret;
15883 }
15884
15885 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
15886
15887 uword
15888 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
15889 {
15890   u32 *action = va_arg (*args, u32 *);
15891   u8 *s = 0;
15892
15893   if (unformat (input, "%s", &s))
15894     {
15895       if (!strcmp ((char *) s, "no-action"))
15896         action[0] = 0;
15897       else if (!strcmp ((char *) s, "natively-forward"))
15898         action[0] = 1;
15899       else if (!strcmp ((char *) s, "send-map-request"))
15900         action[0] = 2;
15901       else if (!strcmp ((char *) s, "drop"))
15902         action[0] = 3;
15903       else
15904         {
15905           clib_warning ("invalid action: '%s'", s);
15906           action[0] = 3;
15907         }
15908     }
15909   else
15910     return 0;
15911
15912   vec_free (s);
15913   return 1;
15914 }
15915
15916 /**
15917  * Add/del remote mapping to/from ONE control plane
15918  *
15919  * @param vam vpp API test context
15920  * @return return code
15921  */
15922 static int
15923 api_one_add_del_remote_mapping (vat_main_t * vam)
15924 {
15925   unformat_input_t *input = vam->input;
15926   vl_api_one_add_del_remote_mapping_t *mp;
15927   u32 vni = 0;
15928   lisp_eid_vat_t _eid, *eid = &_eid;
15929   lisp_eid_vat_t _seid, *seid = &_seid;
15930   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
15931   u32 action = ~0, p, w, data_len;
15932   ip4_address_t rloc4;
15933   ip6_address_t rloc6;
15934   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
15935   int ret;
15936
15937   memset (&rloc, 0, sizeof (rloc));
15938
15939   /* Parse args required to build the message */
15940   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15941     {
15942       if (unformat (input, "del-all"))
15943         {
15944           del_all = 1;
15945         }
15946       else if (unformat (input, "del"))
15947         {
15948           is_add = 0;
15949         }
15950       else if (unformat (input, "add"))
15951         {
15952           is_add = 1;
15953         }
15954       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
15955         {
15956           eid_set = 1;
15957         }
15958       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
15959         {
15960           seid_set = 1;
15961         }
15962       else if (unformat (input, "vni %d", &vni))
15963         {
15964           ;
15965         }
15966       else if (unformat (input, "p %d w %d", &p, &w))
15967         {
15968           if (!curr_rloc)
15969             {
15970               errmsg ("No RLOC configured for setting priority/weight!");
15971               return -99;
15972             }
15973           curr_rloc->priority = p;
15974           curr_rloc->weight = w;
15975         }
15976       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
15977         {
15978           rloc.is_ip4 = 1;
15979           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
15980           vec_add1 (rlocs, rloc);
15981           curr_rloc = &rlocs[vec_len (rlocs) - 1];
15982         }
15983       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
15984         {
15985           rloc.is_ip4 = 0;
15986           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
15987           vec_add1 (rlocs, rloc);
15988           curr_rloc = &rlocs[vec_len (rlocs) - 1];
15989         }
15990       else if (unformat (input, "action %U",
15991                          unformat_negative_mapping_action, &action))
15992         {
15993           ;
15994         }
15995       else
15996         {
15997           clib_warning ("parse error '%U'", format_unformat_error, input);
15998           return -99;
15999         }
16000     }
16001
16002   if (0 == eid_set)
16003     {
16004       errmsg ("missing params!");
16005       return -99;
16006     }
16007
16008   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
16009     {
16010       errmsg ("no action set for negative map-reply!");
16011       return -99;
16012     }
16013
16014   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
16015
16016   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
16017   mp->is_add = is_add;
16018   mp->vni = htonl (vni);
16019   mp->action = (u8) action;
16020   mp->is_src_dst = seid_set;
16021   mp->eid_len = eid->len;
16022   mp->seid_len = seid->len;
16023   mp->del_all = del_all;
16024   mp->eid_type = eid->type;
16025   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
16026   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
16027
16028   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
16029   clib_memcpy (mp->rlocs, rlocs, data_len);
16030   vec_free (rlocs);
16031
16032   /* send it... */
16033   S (mp);
16034
16035   /* Wait for a reply... */
16036   W (ret);
16037   return ret;
16038 }
16039
16040 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
16041
16042 /**
16043  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
16044  * forwarding entries in data-plane accordingly.
16045  *
16046  * @param vam vpp API test context
16047  * @return return code
16048  */
16049 static int
16050 api_one_add_del_adjacency (vat_main_t * vam)
16051 {
16052   unformat_input_t *input = vam->input;
16053   vl_api_one_add_del_adjacency_t *mp;
16054   u32 vni = 0;
16055   ip4_address_t leid4, reid4;
16056   ip6_address_t leid6, reid6;
16057   u8 reid_mac[6] = { 0 };
16058   u8 leid_mac[6] = { 0 };
16059   u8 reid_type, leid_type;
16060   u32 leid_len = 0, reid_len = 0, len;
16061   u8 is_add = 1;
16062   int ret;
16063
16064   leid_type = reid_type = (u8) ~ 0;
16065
16066   /* Parse args required to build the message */
16067   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16068     {
16069       if (unformat (input, "del"))
16070         {
16071           is_add = 0;
16072         }
16073       else if (unformat (input, "add"))
16074         {
16075           is_add = 1;
16076         }
16077       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
16078                          &reid4, &len))
16079         {
16080           reid_type = 0;        /* ipv4 */
16081           reid_len = len;
16082         }
16083       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
16084                          &reid6, &len))
16085         {
16086           reid_type = 1;        /* ipv6 */
16087           reid_len = len;
16088         }
16089       else if (unformat (input, "reid %U", unformat_ethernet_address,
16090                          reid_mac))
16091         {
16092           reid_type = 2;        /* mac */
16093         }
16094       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
16095                          &leid4, &len))
16096         {
16097           leid_type = 0;        /* ipv4 */
16098           leid_len = len;
16099         }
16100       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
16101                          &leid6, &len))
16102         {
16103           leid_type = 1;        /* ipv6 */
16104           leid_len = len;
16105         }
16106       else if (unformat (input, "leid %U", unformat_ethernet_address,
16107                          leid_mac))
16108         {
16109           leid_type = 2;        /* mac */
16110         }
16111       else if (unformat (input, "vni %d", &vni))
16112         {
16113           ;
16114         }
16115       else
16116         {
16117           errmsg ("parse error '%U'", format_unformat_error, input);
16118           return -99;
16119         }
16120     }
16121
16122   if ((u8) ~ 0 == reid_type)
16123     {
16124       errmsg ("missing params!");
16125       return -99;
16126     }
16127
16128   if (leid_type != reid_type)
16129     {
16130       errmsg ("remote and local EIDs are of different types!");
16131       return -99;
16132     }
16133
16134   M (ONE_ADD_DEL_ADJACENCY, mp);
16135   mp->is_add = is_add;
16136   mp->vni = htonl (vni);
16137   mp->leid_len = leid_len;
16138   mp->reid_len = reid_len;
16139   mp->eid_type = reid_type;
16140
16141   switch (mp->eid_type)
16142     {
16143     case 0:
16144       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
16145       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
16146       break;
16147     case 1:
16148       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
16149       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
16150       break;
16151     case 2:
16152       clib_memcpy (mp->leid, leid_mac, 6);
16153       clib_memcpy (mp->reid, reid_mac, 6);
16154       break;
16155     default:
16156       errmsg ("unknown EID type %d!", mp->eid_type);
16157       return 0;
16158     }
16159
16160   /* send it... */
16161   S (mp);
16162
16163   /* Wait for a reply... */
16164   W (ret);
16165   return ret;
16166 }
16167
16168 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
16169
16170 uword
16171 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
16172 {
16173   u32 *mode = va_arg (*args, u32 *);
16174
16175   if (unformat (input, "lisp"))
16176     *mode = 0;
16177   else if (unformat (input, "vxlan"))
16178     *mode = 1;
16179   else
16180     return 0;
16181
16182   return 1;
16183 }
16184
16185 static int
16186 api_gpe_get_encap_mode (vat_main_t * vam)
16187 {
16188   vl_api_gpe_get_encap_mode_t *mp;
16189   int ret;
16190
16191   /* Construct the API message */
16192   M (GPE_GET_ENCAP_MODE, mp);
16193
16194   /* send it... */
16195   S (mp);
16196
16197   /* Wait for a reply... */
16198   W (ret);
16199   return ret;
16200 }
16201
16202 static int
16203 api_gpe_set_encap_mode (vat_main_t * vam)
16204 {
16205   unformat_input_t *input = vam->input;
16206   vl_api_gpe_set_encap_mode_t *mp;
16207   int ret;
16208   u32 mode = 0;
16209
16210   /* Parse args required to build the message */
16211   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16212     {
16213       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
16214         ;
16215       else
16216         break;
16217     }
16218
16219   /* Construct the API message */
16220   M (GPE_SET_ENCAP_MODE, mp);
16221
16222   mp->mode = mode;
16223
16224   /* send it... */
16225   S (mp);
16226
16227   /* Wait for a reply... */
16228   W (ret);
16229   return ret;
16230 }
16231
16232 static int
16233 api_lisp_gpe_add_del_iface (vat_main_t * vam)
16234 {
16235   unformat_input_t *input = vam->input;
16236   vl_api_gpe_add_del_iface_t *mp;
16237   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
16238   u32 dp_table = 0, vni = 0;
16239   int ret;
16240
16241   /* Parse args required to build the message */
16242   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16243     {
16244       if (unformat (input, "up"))
16245         {
16246           action_set = 1;
16247           is_add = 1;
16248         }
16249       else if (unformat (input, "down"))
16250         {
16251           action_set = 1;
16252           is_add = 0;
16253         }
16254       else if (unformat (input, "table_id %d", &dp_table))
16255         {
16256           dp_table_set = 1;
16257         }
16258       else if (unformat (input, "bd_id %d", &dp_table))
16259         {
16260           dp_table_set = 1;
16261           is_l2 = 1;
16262         }
16263       else if (unformat (input, "vni %d", &vni))
16264         {
16265           vni_set = 1;
16266         }
16267       else
16268         break;
16269     }
16270
16271   if (action_set == 0)
16272     {
16273       errmsg ("Action not set");
16274       return -99;
16275     }
16276   if (dp_table_set == 0 || vni_set == 0)
16277     {
16278       errmsg ("vni and dp_table must be set");
16279       return -99;
16280     }
16281
16282   /* Construct the API message */
16283   M (GPE_ADD_DEL_IFACE, mp);
16284
16285   mp->is_add = is_add;
16286   mp->dp_table = clib_host_to_net_u32 (dp_table);
16287   mp->is_l2 = is_l2;
16288   mp->vni = clib_host_to_net_u32 (vni);
16289
16290   /* send it... */
16291   S (mp);
16292
16293   /* Wait for a reply... */
16294   W (ret);
16295   return ret;
16296 }
16297
16298 static int
16299 api_one_map_register_fallback_threshold (vat_main_t * vam)
16300 {
16301   unformat_input_t *input = vam->input;
16302   vl_api_one_map_register_fallback_threshold_t *mp;
16303   u32 value = 0;
16304   u8 is_set = 0;
16305   int ret;
16306
16307   /* Parse args required to build the message */
16308   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16309     {
16310       if (unformat (input, "%u", &value))
16311         is_set = 1;
16312       else
16313         {
16314           clib_warning ("parse error '%U'", format_unformat_error, input);
16315           return -99;
16316         }
16317     }
16318
16319   if (!is_set)
16320     {
16321       errmsg ("fallback threshold value is missing!");
16322       return -99;
16323     }
16324
16325   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
16326   mp->value = clib_host_to_net_u32 (value);
16327
16328   /* send it... */
16329   S (mp);
16330
16331   /* Wait for a reply... */
16332   W (ret);
16333   return ret;
16334 }
16335
16336 static int
16337 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
16338 {
16339   vl_api_show_one_map_register_fallback_threshold_t *mp;
16340   int ret;
16341
16342   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
16343
16344   /* send it... */
16345   S (mp);
16346
16347   /* Wait for a reply... */
16348   W (ret);
16349   return ret;
16350 }
16351
16352 static int
16353 api_one_map_register_set_ttl (vat_main_t * vam)
16354 {
16355   unformat_input_t *input = vam->input;
16356   vl_api_one_map_register_set_ttl_t *mp;
16357   u32 ttl = 0;
16358   u8 is_set = 0;
16359   int ret;
16360
16361   /* Parse args required to build the message */
16362   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16363     {
16364       if (unformat (input, "%u", &ttl))
16365         is_set = 1;
16366       else
16367         {
16368           clib_warning ("parse error '%U'", format_unformat_error, input);
16369           return -99;
16370         }
16371     }
16372
16373   if (!is_set)
16374     {
16375       errmsg ("TTL value missing!");
16376       return -99;
16377     }
16378
16379   M (ONE_MAP_REGISTER_SET_TTL, mp);
16380   mp->ttl = clib_host_to_net_u32 (ttl);
16381
16382   /* send it... */
16383   S (mp);
16384
16385   /* Wait for a reply... */
16386   W (ret);
16387   return ret;
16388 }
16389
16390 static int
16391 api_show_one_map_register_ttl (vat_main_t * vam)
16392 {
16393   vl_api_show_one_map_register_ttl_t *mp;
16394   int ret;
16395
16396   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
16397
16398   /* send it... */
16399   S (mp);
16400
16401   /* Wait for a reply... */
16402   W (ret);
16403   return ret;
16404 }
16405
16406 /**
16407  * Add/del map request itr rlocs from ONE control plane and updates
16408  *
16409  * @param vam vpp API test context
16410  * @return return code
16411  */
16412 static int
16413 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
16414 {
16415   unformat_input_t *input = vam->input;
16416   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
16417   u8 *locator_set_name = 0;
16418   u8 locator_set_name_set = 0;
16419   u8 is_add = 1;
16420   int ret;
16421
16422   /* Parse args required to build the message */
16423   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16424     {
16425       if (unformat (input, "del"))
16426         {
16427           is_add = 0;
16428         }
16429       else if (unformat (input, "%_%v%_", &locator_set_name))
16430         {
16431           locator_set_name_set = 1;
16432         }
16433       else
16434         {
16435           clib_warning ("parse error '%U'", format_unformat_error, input);
16436           return -99;
16437         }
16438     }
16439
16440   if (is_add && !locator_set_name_set)
16441     {
16442       errmsg ("itr-rloc is not set!");
16443       return -99;
16444     }
16445
16446   if (is_add && vec_len (locator_set_name) > 64)
16447     {
16448       errmsg ("itr-rloc locator-set name too long");
16449       vec_free (locator_set_name);
16450       return -99;
16451     }
16452
16453   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
16454   mp->is_add = is_add;
16455   if (is_add)
16456     {
16457       clib_memcpy (mp->locator_set_name, locator_set_name,
16458                    vec_len (locator_set_name));
16459     }
16460   else
16461     {
16462       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
16463     }
16464   vec_free (locator_set_name);
16465
16466   /* send it... */
16467   S (mp);
16468
16469   /* Wait for a reply... */
16470   W (ret);
16471   return ret;
16472 }
16473
16474 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
16475
16476 static int
16477 api_one_locator_dump (vat_main_t * vam)
16478 {
16479   unformat_input_t *input = vam->input;
16480   vl_api_one_locator_dump_t *mp;
16481   vl_api_control_ping_t *mp_ping;
16482   u8 is_index_set = 0, is_name_set = 0;
16483   u8 *ls_name = 0;
16484   u32 ls_index = ~0;
16485   int ret;
16486
16487   /* Parse args required to build the message */
16488   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16489     {
16490       if (unformat (input, "ls_name %_%v%_", &ls_name))
16491         {
16492           is_name_set = 1;
16493         }
16494       else if (unformat (input, "ls_index %d", &ls_index))
16495         {
16496           is_index_set = 1;
16497         }
16498       else
16499         {
16500           errmsg ("parse error '%U'", format_unformat_error, input);
16501           return -99;
16502         }
16503     }
16504
16505   if (!is_index_set && !is_name_set)
16506     {
16507       errmsg ("error: expected one of index or name!");
16508       return -99;
16509     }
16510
16511   if (is_index_set && is_name_set)
16512     {
16513       errmsg ("error: only one param expected!");
16514       return -99;
16515     }
16516
16517   if (vec_len (ls_name) > 62)
16518     {
16519       errmsg ("error: locator set name too long!");
16520       return -99;
16521     }
16522
16523   if (!vam->json_output)
16524     {
16525       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
16526     }
16527
16528   M (ONE_LOCATOR_DUMP, mp);
16529   mp->is_index_set = is_index_set;
16530
16531   if (is_index_set)
16532     mp->ls_index = clib_host_to_net_u32 (ls_index);
16533   else
16534     {
16535       vec_add1 (ls_name, 0);
16536       strncpy ((char *) mp->ls_name, (char *) ls_name,
16537                sizeof (mp->ls_name) - 1);
16538     }
16539
16540   /* send it... */
16541   S (mp);
16542
16543   /* Use a control ping for synchronization */
16544   M (CONTROL_PING, mp_ping);
16545   S (mp_ping);
16546
16547   /* Wait for a reply... */
16548   W (ret);
16549   return ret;
16550 }
16551
16552 #define api_lisp_locator_dump api_one_locator_dump
16553
16554 static int
16555 api_one_locator_set_dump (vat_main_t * vam)
16556 {
16557   vl_api_one_locator_set_dump_t *mp;
16558   vl_api_control_ping_t *mp_ping;
16559   unformat_input_t *input = vam->input;
16560   u8 filter = 0;
16561   int ret;
16562
16563   /* Parse args required to build the message */
16564   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16565     {
16566       if (unformat (input, "local"))
16567         {
16568           filter = 1;
16569         }
16570       else if (unformat (input, "remote"))
16571         {
16572           filter = 2;
16573         }
16574       else
16575         {
16576           errmsg ("parse error '%U'", format_unformat_error, input);
16577           return -99;
16578         }
16579     }
16580
16581   if (!vam->json_output)
16582     {
16583       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
16584     }
16585
16586   M (ONE_LOCATOR_SET_DUMP, mp);
16587
16588   mp->filter = filter;
16589
16590   /* send it... */
16591   S (mp);
16592
16593   /* Use a control ping for synchronization */
16594   M (CONTROL_PING, mp_ping);
16595   S (mp_ping);
16596
16597   /* Wait for a reply... */
16598   W (ret);
16599   return ret;
16600 }
16601
16602 #define api_lisp_locator_set_dump api_one_locator_set_dump
16603
16604 static int
16605 api_one_eid_table_map_dump (vat_main_t * vam)
16606 {
16607   u8 is_l2 = 0;
16608   u8 mode_set = 0;
16609   unformat_input_t *input = vam->input;
16610   vl_api_one_eid_table_map_dump_t *mp;
16611   vl_api_control_ping_t *mp_ping;
16612   int ret;
16613
16614   /* Parse args required to build the message */
16615   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16616     {
16617       if (unformat (input, "l2"))
16618         {
16619           is_l2 = 1;
16620           mode_set = 1;
16621         }
16622       else if (unformat (input, "l3"))
16623         {
16624           is_l2 = 0;
16625           mode_set = 1;
16626         }
16627       else
16628         {
16629           errmsg ("parse error '%U'", format_unformat_error, input);
16630           return -99;
16631         }
16632     }
16633
16634   if (!mode_set)
16635     {
16636       errmsg ("expected one of 'l2' or 'l3' parameter!");
16637       return -99;
16638     }
16639
16640   if (!vam->json_output)
16641     {
16642       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
16643     }
16644
16645   M (ONE_EID_TABLE_MAP_DUMP, mp);
16646   mp->is_l2 = is_l2;
16647
16648   /* send it... */
16649   S (mp);
16650
16651   /* Use a control ping for synchronization */
16652   M (CONTROL_PING, mp_ping);
16653   S (mp_ping);
16654
16655   /* Wait for a reply... */
16656   W (ret);
16657   return ret;
16658 }
16659
16660 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
16661
16662 static int
16663 api_one_eid_table_vni_dump (vat_main_t * vam)
16664 {
16665   vl_api_one_eid_table_vni_dump_t *mp;
16666   vl_api_control_ping_t *mp_ping;
16667   int ret;
16668
16669   if (!vam->json_output)
16670     {
16671       print (vam->ofp, "VNI");
16672     }
16673
16674   M (ONE_EID_TABLE_VNI_DUMP, mp);
16675
16676   /* send it... */
16677   S (mp);
16678
16679   /* Use a control ping for synchronization */
16680   M (CONTROL_PING, mp_ping);
16681   S (mp_ping);
16682
16683   /* Wait for a reply... */
16684   W (ret);
16685   return ret;
16686 }
16687
16688 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
16689
16690 static int
16691 api_one_eid_table_dump (vat_main_t * vam)
16692 {
16693   unformat_input_t *i = vam->input;
16694   vl_api_one_eid_table_dump_t *mp;
16695   vl_api_control_ping_t *mp_ping;
16696   struct in_addr ip4;
16697   struct in6_addr ip6;
16698   u8 mac[6];
16699   u8 eid_type = ~0, eid_set = 0;
16700   u32 prefix_length = ~0, t, vni = 0;
16701   u8 filter = 0;
16702   int ret;
16703   lisp_nsh_api_t nsh;
16704
16705   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16706     {
16707       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
16708         {
16709           eid_set = 1;
16710           eid_type = 0;
16711           prefix_length = t;
16712         }
16713       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
16714         {
16715           eid_set = 1;
16716           eid_type = 1;
16717           prefix_length = t;
16718         }
16719       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
16720         {
16721           eid_set = 1;
16722           eid_type = 2;
16723         }
16724       else if (unformat (i, "eid %U", unformat_nsh_address, &nsh))
16725         {
16726           eid_set = 1;
16727           eid_type = 3;
16728         }
16729       else if (unformat (i, "vni %d", &t))
16730         {
16731           vni = t;
16732         }
16733       else if (unformat (i, "local"))
16734         {
16735           filter = 1;
16736         }
16737       else if (unformat (i, "remote"))
16738         {
16739           filter = 2;
16740         }
16741       else
16742         {
16743           errmsg ("parse error '%U'", format_unformat_error, i);
16744           return -99;
16745         }
16746     }
16747
16748   if (!vam->json_output)
16749     {
16750       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
16751              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
16752     }
16753
16754   M (ONE_EID_TABLE_DUMP, mp);
16755
16756   mp->filter = filter;
16757   if (eid_set)
16758     {
16759       mp->eid_set = 1;
16760       mp->vni = htonl (vni);
16761       mp->eid_type = eid_type;
16762       switch (eid_type)
16763         {
16764         case 0:
16765           mp->prefix_length = prefix_length;
16766           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
16767           break;
16768         case 1:
16769           mp->prefix_length = prefix_length;
16770           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
16771           break;
16772         case 2:
16773           clib_memcpy (mp->eid, mac, sizeof (mac));
16774           break;
16775         case 3:
16776           clib_memcpy (mp->eid, &nsh, sizeof (nsh));
16777           break;
16778         default:
16779           errmsg ("unknown EID type %d!", eid_type);
16780           return -99;
16781         }
16782     }
16783
16784   /* send it... */
16785   S (mp);
16786
16787   /* Use a control ping for synchronization */
16788   M (CONTROL_PING, mp_ping);
16789   S (mp_ping);
16790
16791   /* Wait for a reply... */
16792   W (ret);
16793   return ret;
16794 }
16795
16796 #define api_lisp_eid_table_dump api_one_eid_table_dump
16797
16798 static int
16799 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
16800 {
16801   unformat_input_t *i = vam->input;
16802   vl_api_gpe_fwd_entries_get_t *mp;
16803   u8 vni_set = 0;
16804   u32 vni = ~0;
16805   int ret;
16806
16807   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16808     {
16809       if (unformat (i, "vni %d", &vni))
16810         {
16811           vni_set = 1;
16812         }
16813       else
16814         {
16815           errmsg ("parse error '%U'", format_unformat_error, i);
16816           return -99;
16817         }
16818     }
16819
16820   if (!vni_set)
16821     {
16822       errmsg ("vni not set!");
16823       return -99;
16824     }
16825
16826   if (!vam->json_output)
16827     {
16828       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
16829              "leid", "reid");
16830     }
16831
16832   M (GPE_FWD_ENTRIES_GET, mp);
16833   mp->vni = clib_host_to_net_u32 (vni);
16834
16835   /* send it... */
16836   S (mp);
16837
16838   /* Wait for a reply... */
16839   W (ret);
16840   return ret;
16841 }
16842
16843 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
16844 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
16845 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
16846 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
16847 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
16848 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
16849 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
16850 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
16851
16852 static int
16853 api_one_adjacencies_get (vat_main_t * vam)
16854 {
16855   unformat_input_t *i = vam->input;
16856   vl_api_one_adjacencies_get_t *mp;
16857   u8 vni_set = 0;
16858   u32 vni = ~0;
16859   int ret;
16860
16861   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16862     {
16863       if (unformat (i, "vni %d", &vni))
16864         {
16865           vni_set = 1;
16866         }
16867       else
16868         {
16869           errmsg ("parse error '%U'", format_unformat_error, i);
16870           return -99;
16871         }
16872     }
16873
16874   if (!vni_set)
16875     {
16876       errmsg ("vni not set!");
16877       return -99;
16878     }
16879
16880   if (!vam->json_output)
16881     {
16882       print (vam->ofp, "%s %40s", "leid", "reid");
16883     }
16884
16885   M (ONE_ADJACENCIES_GET, mp);
16886   mp->vni = clib_host_to_net_u32 (vni);
16887
16888   /* send it... */
16889   S (mp);
16890
16891   /* Wait for a reply... */
16892   W (ret);
16893   return ret;
16894 }
16895
16896 #define api_lisp_adjacencies_get api_one_adjacencies_get
16897
16898 static int
16899 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
16900 {
16901   unformat_input_t *i = vam->input;
16902   vl_api_gpe_native_fwd_rpaths_get_t *mp;
16903   int ret;
16904   u8 ip_family_set = 0, is_ip4 = 1;
16905
16906   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16907     {
16908       if (unformat (i, "ip4"))
16909         {
16910           ip_family_set = 1;
16911           is_ip4 = 1;
16912         }
16913       else if (unformat (i, "ip6"))
16914         {
16915           ip_family_set = 1;
16916           is_ip4 = 0;
16917         }
16918       else
16919         {
16920           errmsg ("parse error '%U'", format_unformat_error, i);
16921           return -99;
16922         }
16923     }
16924
16925   if (!ip_family_set)
16926     {
16927       errmsg ("ip family not set!");
16928       return -99;
16929     }
16930
16931   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
16932   mp->is_ip4 = is_ip4;
16933
16934   /* send it... */
16935   S (mp);
16936
16937   /* Wait for a reply... */
16938   W (ret);
16939   return ret;
16940 }
16941
16942 static int
16943 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
16944 {
16945   vl_api_gpe_fwd_entry_vnis_get_t *mp;
16946   int ret;
16947
16948   if (!vam->json_output)
16949     {
16950       print (vam->ofp, "VNIs");
16951     }
16952
16953   M (GPE_FWD_ENTRY_VNIS_GET, mp);
16954
16955   /* send it... */
16956   S (mp);
16957
16958   /* Wait for a reply... */
16959   W (ret);
16960   return ret;
16961 }
16962
16963 static int
16964 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
16965 {
16966   unformat_input_t *i = vam->input;
16967   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
16968   int ret = 0;
16969   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
16970   struct in_addr ip4;
16971   struct in6_addr ip6;
16972   u32 table_id = 0, nh_sw_if_index = ~0;
16973
16974   memset (&ip4, 0, sizeof (ip4));
16975   memset (&ip6, 0, sizeof (ip6));
16976
16977   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16978     {
16979       if (unformat (i, "del"))
16980         is_add = 0;
16981       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
16982                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
16983         {
16984           ip_set = 1;
16985           is_ip4 = 1;
16986         }
16987       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
16988                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
16989         {
16990           ip_set = 1;
16991           is_ip4 = 0;
16992         }
16993       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
16994         {
16995           ip_set = 1;
16996           is_ip4 = 1;
16997           nh_sw_if_index = ~0;
16998         }
16999       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
17000         {
17001           ip_set = 1;
17002           is_ip4 = 0;
17003           nh_sw_if_index = ~0;
17004         }
17005       else if (unformat (i, "table %d", &table_id))
17006         ;
17007       else
17008         {
17009           errmsg ("parse error '%U'", format_unformat_error, i);
17010           return -99;
17011         }
17012     }
17013
17014   if (!ip_set)
17015     {
17016       errmsg ("nh addr not set!");
17017       return -99;
17018     }
17019
17020   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
17021   mp->is_add = is_add;
17022   mp->table_id = clib_host_to_net_u32 (table_id);
17023   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
17024   mp->is_ip4 = is_ip4;
17025   if (is_ip4)
17026     clib_memcpy (mp->nh_addr, &ip4, sizeof (ip4));
17027   else
17028     clib_memcpy (mp->nh_addr, &ip6, sizeof (ip6));
17029
17030   /* send it... */
17031   S (mp);
17032
17033   /* Wait for a reply... */
17034   W (ret);
17035   return ret;
17036 }
17037
17038 static int
17039 api_one_map_server_dump (vat_main_t * vam)
17040 {
17041   vl_api_one_map_server_dump_t *mp;
17042   vl_api_control_ping_t *mp_ping;
17043   int ret;
17044
17045   if (!vam->json_output)
17046     {
17047       print (vam->ofp, "%=20s", "Map server");
17048     }
17049
17050   M (ONE_MAP_SERVER_DUMP, mp);
17051   /* send it... */
17052   S (mp);
17053
17054   /* Use a control ping for synchronization */
17055   M (CONTROL_PING, mp_ping);
17056   S (mp_ping);
17057
17058   /* Wait for a reply... */
17059   W (ret);
17060   return ret;
17061 }
17062
17063 #define api_lisp_map_server_dump api_one_map_server_dump
17064
17065 static int
17066 api_one_map_resolver_dump (vat_main_t * vam)
17067 {
17068   vl_api_one_map_resolver_dump_t *mp;
17069   vl_api_control_ping_t *mp_ping;
17070   int ret;
17071
17072   if (!vam->json_output)
17073     {
17074       print (vam->ofp, "%=20s", "Map resolver");
17075     }
17076
17077   M (ONE_MAP_RESOLVER_DUMP, mp);
17078   /* send it... */
17079   S (mp);
17080
17081   /* Use a control ping for synchronization */
17082   M (CONTROL_PING, mp_ping);
17083   S (mp_ping);
17084
17085   /* Wait for a reply... */
17086   W (ret);
17087   return ret;
17088 }
17089
17090 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
17091
17092 static int
17093 api_one_stats_flush (vat_main_t * vam)
17094 {
17095   vl_api_one_stats_flush_t *mp;
17096   int ret = 0;
17097
17098   M (ONE_STATS_FLUSH, mp);
17099   S (mp);
17100   W (ret);
17101   return ret;
17102 }
17103
17104 static int
17105 api_one_stats_dump (vat_main_t * vam)
17106 {
17107   vl_api_one_stats_dump_t *mp;
17108   vl_api_control_ping_t *mp_ping;
17109   int ret;
17110
17111   M (ONE_STATS_DUMP, mp);
17112   /* send it... */
17113   S (mp);
17114
17115   /* Use a control ping for synchronization */
17116   M (CONTROL_PING, mp_ping);
17117   S (mp_ping);
17118
17119   /* Wait for a reply... */
17120   W (ret);
17121   return ret;
17122 }
17123
17124 static int
17125 api_show_one_status (vat_main_t * vam)
17126 {
17127   vl_api_show_one_status_t *mp;
17128   int ret;
17129
17130   if (!vam->json_output)
17131     {
17132       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
17133     }
17134
17135   M (SHOW_ONE_STATUS, mp);
17136   /* send it... */
17137   S (mp);
17138   /* Wait for a reply... */
17139   W (ret);
17140   return ret;
17141 }
17142
17143 #define api_show_lisp_status api_show_one_status
17144
17145 static int
17146 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
17147 {
17148   vl_api_gpe_fwd_entry_path_dump_t *mp;
17149   vl_api_control_ping_t *mp_ping;
17150   unformat_input_t *i = vam->input;
17151   u32 fwd_entry_index = ~0;
17152   int ret;
17153
17154   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17155     {
17156       if (unformat (i, "index %d", &fwd_entry_index))
17157         ;
17158       else
17159         break;
17160     }
17161
17162   if (~0 == fwd_entry_index)
17163     {
17164       errmsg ("no index specified!");
17165       return -99;
17166     }
17167
17168   if (!vam->json_output)
17169     {
17170       print (vam->ofp, "first line");
17171     }
17172
17173   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
17174
17175   /* send it... */
17176   S (mp);
17177   /* Use a control ping for synchronization */
17178   M (CONTROL_PING, mp_ping);
17179   S (mp_ping);
17180
17181   /* Wait for a reply... */
17182   W (ret);
17183   return ret;
17184 }
17185
17186 static int
17187 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
17188 {
17189   vl_api_one_get_map_request_itr_rlocs_t *mp;
17190   int ret;
17191
17192   if (!vam->json_output)
17193     {
17194       print (vam->ofp, "%=20s", "itr-rlocs:");
17195     }
17196
17197   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
17198   /* send it... */
17199   S (mp);
17200   /* Wait for a reply... */
17201   W (ret);
17202   return ret;
17203 }
17204
17205 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
17206
17207 static int
17208 api_af_packet_create (vat_main_t * vam)
17209 {
17210   unformat_input_t *i = vam->input;
17211   vl_api_af_packet_create_t *mp;
17212   u8 *host_if_name = 0;
17213   u8 hw_addr[6];
17214   u8 random_hw_addr = 1;
17215   int ret;
17216
17217   memset (hw_addr, 0, sizeof (hw_addr));
17218
17219   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17220     {
17221       if (unformat (i, "name %s", &host_if_name))
17222         vec_add1 (host_if_name, 0);
17223       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
17224         random_hw_addr = 0;
17225       else
17226         break;
17227     }
17228
17229   if (!vec_len (host_if_name))
17230     {
17231       errmsg ("host-interface name must be specified");
17232       return -99;
17233     }
17234
17235   if (vec_len (host_if_name) > 64)
17236     {
17237       errmsg ("host-interface name too long");
17238       return -99;
17239     }
17240
17241   M (AF_PACKET_CREATE, mp);
17242
17243   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
17244   clib_memcpy (mp->hw_addr, hw_addr, 6);
17245   mp->use_random_hw_addr = random_hw_addr;
17246   vec_free (host_if_name);
17247
17248   S (mp);
17249
17250   /* *INDENT-OFF* */
17251   W2 (ret,
17252       ({
17253         if (ret == 0)
17254           fprintf (vam->ofp ? vam->ofp : stderr,
17255                    " new sw_if_index = %d\n", vam->sw_if_index);
17256       }));
17257   /* *INDENT-ON* */
17258   return ret;
17259 }
17260
17261 static int
17262 api_af_packet_delete (vat_main_t * vam)
17263 {
17264   unformat_input_t *i = vam->input;
17265   vl_api_af_packet_delete_t *mp;
17266   u8 *host_if_name = 0;
17267   int ret;
17268
17269   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17270     {
17271       if (unformat (i, "name %s", &host_if_name))
17272         vec_add1 (host_if_name, 0);
17273       else
17274         break;
17275     }
17276
17277   if (!vec_len (host_if_name))
17278     {
17279       errmsg ("host-interface name must be specified");
17280       return -99;
17281     }
17282
17283   if (vec_len (host_if_name) > 64)
17284     {
17285       errmsg ("host-interface name too long");
17286       return -99;
17287     }
17288
17289   M (AF_PACKET_DELETE, mp);
17290
17291   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
17292   vec_free (host_if_name);
17293
17294   S (mp);
17295   W (ret);
17296   return ret;
17297 }
17298
17299 static int
17300 api_policer_add_del (vat_main_t * vam)
17301 {
17302   unformat_input_t *i = vam->input;
17303   vl_api_policer_add_del_t *mp;
17304   u8 is_add = 1;
17305   u8 *name = 0;
17306   u32 cir = 0;
17307   u32 eir = 0;
17308   u64 cb = 0;
17309   u64 eb = 0;
17310   u8 rate_type = 0;
17311   u8 round_type = 0;
17312   u8 type = 0;
17313   u8 color_aware = 0;
17314   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
17315   int ret;
17316
17317   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
17318   conform_action.dscp = 0;
17319   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
17320   exceed_action.dscp = 0;
17321   violate_action.action_type = SSE2_QOS_ACTION_DROP;
17322   violate_action.dscp = 0;
17323
17324   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17325     {
17326       if (unformat (i, "del"))
17327         is_add = 0;
17328       else if (unformat (i, "name %s", &name))
17329         vec_add1 (name, 0);
17330       else if (unformat (i, "cir %u", &cir))
17331         ;
17332       else if (unformat (i, "eir %u", &eir))
17333         ;
17334       else if (unformat (i, "cb %u", &cb))
17335         ;
17336       else if (unformat (i, "eb %u", &eb))
17337         ;
17338       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
17339                          &rate_type))
17340         ;
17341       else if (unformat (i, "round_type %U", unformat_policer_round_type,
17342                          &round_type))
17343         ;
17344       else if (unformat (i, "type %U", unformat_policer_type, &type))
17345         ;
17346       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
17347                          &conform_action))
17348         ;
17349       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
17350                          &exceed_action))
17351         ;
17352       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
17353                          &violate_action))
17354         ;
17355       else if (unformat (i, "color-aware"))
17356         color_aware = 1;
17357       else
17358         break;
17359     }
17360
17361   if (!vec_len (name))
17362     {
17363       errmsg ("policer name must be specified");
17364       return -99;
17365     }
17366
17367   if (vec_len (name) > 64)
17368     {
17369       errmsg ("policer name too long");
17370       return -99;
17371     }
17372
17373   M (POLICER_ADD_DEL, mp);
17374
17375   clib_memcpy (mp->name, name, vec_len (name));
17376   vec_free (name);
17377   mp->is_add = is_add;
17378   mp->cir = cir;
17379   mp->eir = eir;
17380   mp->cb = cb;
17381   mp->eb = eb;
17382   mp->rate_type = rate_type;
17383   mp->round_type = round_type;
17384   mp->type = type;
17385   mp->conform_action_type = conform_action.action_type;
17386   mp->conform_dscp = conform_action.dscp;
17387   mp->exceed_action_type = exceed_action.action_type;
17388   mp->exceed_dscp = exceed_action.dscp;
17389   mp->violate_action_type = violate_action.action_type;
17390   mp->violate_dscp = violate_action.dscp;
17391   mp->color_aware = color_aware;
17392
17393   S (mp);
17394   W (ret);
17395   return ret;
17396 }
17397
17398 static int
17399 api_policer_dump (vat_main_t * vam)
17400 {
17401   unformat_input_t *i = vam->input;
17402   vl_api_policer_dump_t *mp;
17403   vl_api_control_ping_t *mp_ping;
17404   u8 *match_name = 0;
17405   u8 match_name_valid = 0;
17406   int ret;
17407
17408   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17409     {
17410       if (unformat (i, "name %s", &match_name))
17411         {
17412           vec_add1 (match_name, 0);
17413           match_name_valid = 1;
17414         }
17415       else
17416         break;
17417     }
17418
17419   M (POLICER_DUMP, mp);
17420   mp->match_name_valid = match_name_valid;
17421   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
17422   vec_free (match_name);
17423   /* send it... */
17424   S (mp);
17425
17426   /* Use a control ping for synchronization */
17427   M (CONTROL_PING, mp_ping);
17428   S (mp_ping);
17429
17430   /* Wait for a reply... */
17431   W (ret);
17432   return ret;
17433 }
17434
17435 static int
17436 api_policer_classify_set_interface (vat_main_t * vam)
17437 {
17438   unformat_input_t *i = vam->input;
17439   vl_api_policer_classify_set_interface_t *mp;
17440   u32 sw_if_index;
17441   int sw_if_index_set;
17442   u32 ip4_table_index = ~0;
17443   u32 ip6_table_index = ~0;
17444   u32 l2_table_index = ~0;
17445   u8 is_add = 1;
17446   int ret;
17447
17448   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17449     {
17450       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17451         sw_if_index_set = 1;
17452       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17453         sw_if_index_set = 1;
17454       else if (unformat (i, "del"))
17455         is_add = 0;
17456       else if (unformat (i, "ip4-table %d", &ip4_table_index))
17457         ;
17458       else if (unformat (i, "ip6-table %d", &ip6_table_index))
17459         ;
17460       else if (unformat (i, "l2-table %d", &l2_table_index))
17461         ;
17462       else
17463         {
17464           clib_warning ("parse error '%U'", format_unformat_error, i);
17465           return -99;
17466         }
17467     }
17468
17469   if (sw_if_index_set == 0)
17470     {
17471       errmsg ("missing interface name or sw_if_index");
17472       return -99;
17473     }
17474
17475   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
17476
17477   mp->sw_if_index = ntohl (sw_if_index);
17478   mp->ip4_table_index = ntohl (ip4_table_index);
17479   mp->ip6_table_index = ntohl (ip6_table_index);
17480   mp->l2_table_index = ntohl (l2_table_index);
17481   mp->is_add = is_add;
17482
17483   S (mp);
17484   W (ret);
17485   return ret;
17486 }
17487
17488 static int
17489 api_policer_classify_dump (vat_main_t * vam)
17490 {
17491   unformat_input_t *i = vam->input;
17492   vl_api_policer_classify_dump_t *mp;
17493   vl_api_control_ping_t *mp_ping;
17494   u8 type = POLICER_CLASSIFY_N_TABLES;
17495   int ret;
17496
17497   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
17498     ;
17499   else
17500     {
17501       errmsg ("classify table type must be specified");
17502       return -99;
17503     }
17504
17505   if (!vam->json_output)
17506     {
17507       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
17508     }
17509
17510   M (POLICER_CLASSIFY_DUMP, mp);
17511   mp->type = type;
17512   /* send it... */
17513   S (mp);
17514
17515   /* Use a control ping for synchronization */
17516   M (CONTROL_PING, mp_ping);
17517   S (mp_ping);
17518
17519   /* Wait for a reply... */
17520   W (ret);
17521   return ret;
17522 }
17523
17524 static int
17525 api_netmap_create (vat_main_t * vam)
17526 {
17527   unformat_input_t *i = vam->input;
17528   vl_api_netmap_create_t *mp;
17529   u8 *if_name = 0;
17530   u8 hw_addr[6];
17531   u8 random_hw_addr = 1;
17532   u8 is_pipe = 0;
17533   u8 is_master = 0;
17534   int ret;
17535
17536   memset (hw_addr, 0, sizeof (hw_addr));
17537
17538   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17539     {
17540       if (unformat (i, "name %s", &if_name))
17541         vec_add1 (if_name, 0);
17542       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
17543         random_hw_addr = 0;
17544       else if (unformat (i, "pipe"))
17545         is_pipe = 1;
17546       else if (unformat (i, "master"))
17547         is_master = 1;
17548       else if (unformat (i, "slave"))
17549         is_master = 0;
17550       else
17551         break;
17552     }
17553
17554   if (!vec_len (if_name))
17555     {
17556       errmsg ("interface name must be specified");
17557       return -99;
17558     }
17559
17560   if (vec_len (if_name) > 64)
17561     {
17562       errmsg ("interface name too long");
17563       return -99;
17564     }
17565
17566   M (NETMAP_CREATE, mp);
17567
17568   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
17569   clib_memcpy (mp->hw_addr, hw_addr, 6);
17570   mp->use_random_hw_addr = random_hw_addr;
17571   mp->is_pipe = is_pipe;
17572   mp->is_master = is_master;
17573   vec_free (if_name);
17574
17575   S (mp);
17576   W (ret);
17577   return ret;
17578 }
17579
17580 static int
17581 api_netmap_delete (vat_main_t * vam)
17582 {
17583   unformat_input_t *i = vam->input;
17584   vl_api_netmap_delete_t *mp;
17585   u8 *if_name = 0;
17586   int ret;
17587
17588   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17589     {
17590       if (unformat (i, "name %s", &if_name))
17591         vec_add1 (if_name, 0);
17592       else
17593         break;
17594     }
17595
17596   if (!vec_len (if_name))
17597     {
17598       errmsg ("interface name must be specified");
17599       return -99;
17600     }
17601
17602   if (vec_len (if_name) > 64)
17603     {
17604       errmsg ("interface name too long");
17605       return -99;
17606     }
17607
17608   M (NETMAP_DELETE, mp);
17609
17610   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
17611   vec_free (if_name);
17612
17613   S (mp);
17614   W (ret);
17615   return ret;
17616 }
17617
17618 static void
17619 vl_api_mpls_fib_path_print (vat_main_t * vam, vl_api_fib_path2_t * fp)
17620 {
17621   if (fp->afi == IP46_TYPE_IP6)
17622     print (vam->ofp,
17623            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
17624            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
17625            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
17626            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
17627            format_ip6_address, fp->next_hop);
17628   else if (fp->afi == IP46_TYPE_IP4)
17629     print (vam->ofp,
17630            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
17631            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
17632            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
17633            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
17634            format_ip4_address, fp->next_hop);
17635 }
17636
17637 static void
17638 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
17639                                  vl_api_fib_path2_t * fp)
17640 {
17641   struct in_addr ip4;
17642   struct in6_addr ip6;
17643
17644   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
17645   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
17646   vat_json_object_add_uint (node, "is_local", fp->is_local);
17647   vat_json_object_add_uint (node, "is_drop", fp->is_drop);
17648   vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
17649   vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
17650   vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
17651   if (fp->afi == IP46_TYPE_IP4)
17652     {
17653       clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
17654       vat_json_object_add_ip4 (node, "next_hop", ip4);
17655     }
17656   else if (fp->afi == IP46_TYPE_IP6)
17657     {
17658       clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
17659       vat_json_object_add_ip6 (node, "next_hop", ip6);
17660     }
17661 }
17662
17663 static void
17664 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
17665 {
17666   vat_main_t *vam = &vat_main;
17667   int count = ntohl (mp->mt_count);
17668   vl_api_fib_path2_t *fp;
17669   i32 i;
17670
17671   print (vam->ofp, "[%d]: sw_if_index %d via:",
17672          ntohl (mp->mt_tunnel_index), ntohl (mp->mt_sw_if_index));
17673   fp = mp->mt_paths;
17674   for (i = 0; i < count; i++)
17675     {
17676       vl_api_mpls_fib_path_print (vam, fp);
17677       fp++;
17678     }
17679
17680   print (vam->ofp, "");
17681 }
17682
17683 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
17684 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
17685
17686 static void
17687 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
17688 {
17689   vat_main_t *vam = &vat_main;
17690   vat_json_node_t *node = NULL;
17691   int count = ntohl (mp->mt_count);
17692   vl_api_fib_path2_t *fp;
17693   i32 i;
17694
17695   if (VAT_JSON_ARRAY != vam->json_tree.type)
17696     {
17697       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17698       vat_json_init_array (&vam->json_tree);
17699     }
17700   node = vat_json_array_add (&vam->json_tree);
17701
17702   vat_json_init_object (node);
17703   vat_json_object_add_uint (node, "tunnel_index",
17704                             ntohl (mp->mt_tunnel_index));
17705   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->mt_sw_if_index));
17706
17707   vat_json_object_add_uint (node, "l2_only", mp->mt_l2_only);
17708
17709   fp = mp->mt_paths;
17710   for (i = 0; i < count; i++)
17711     {
17712       vl_api_mpls_fib_path_json_print (node, fp);
17713       fp++;
17714     }
17715 }
17716
17717 static int
17718 api_mpls_tunnel_dump (vat_main_t * vam)
17719 {
17720   vl_api_mpls_tunnel_dump_t *mp;
17721   vl_api_control_ping_t *mp_ping;
17722   i32 index = -1;
17723   int ret;
17724
17725   /* Parse args required to build the message */
17726   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
17727     {
17728       if (!unformat (vam->input, "tunnel_index %d", &index))
17729         {
17730           index = -1;
17731           break;
17732         }
17733     }
17734
17735   print (vam->ofp, "  tunnel_index %d", index);
17736
17737   M (MPLS_TUNNEL_DUMP, mp);
17738   mp->tunnel_index = htonl (index);
17739   S (mp);
17740
17741   /* Use a control ping for synchronization */
17742   M (CONTROL_PING, mp_ping);
17743   S (mp_ping);
17744
17745   W (ret);
17746   return ret;
17747 }
17748
17749 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
17750 #define vl_api_mpls_fib_details_t_print vl_noop_handler
17751
17752
17753 static void
17754 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
17755 {
17756   vat_main_t *vam = &vat_main;
17757   int count = ntohl (mp->count);
17758   vl_api_fib_path2_t *fp;
17759   int i;
17760
17761   print (vam->ofp,
17762          "table-id %d, label %u, ess_bit %u",
17763          ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
17764   fp = mp->path;
17765   for (i = 0; i < count; i++)
17766     {
17767       vl_api_mpls_fib_path_print (vam, fp);
17768       fp++;
17769     }
17770 }
17771
17772 static void vl_api_mpls_fib_details_t_handler_json
17773   (vl_api_mpls_fib_details_t * mp)
17774 {
17775   vat_main_t *vam = &vat_main;
17776   int count = ntohl (mp->count);
17777   vat_json_node_t *node = NULL;
17778   vl_api_fib_path2_t *fp;
17779   int i;
17780
17781   if (VAT_JSON_ARRAY != vam->json_tree.type)
17782     {
17783       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17784       vat_json_init_array (&vam->json_tree);
17785     }
17786   node = vat_json_array_add (&vam->json_tree);
17787
17788   vat_json_init_object (node);
17789   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
17790   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
17791   vat_json_object_add_uint (node, "label", ntohl (mp->label));
17792   vat_json_object_add_uint (node, "path_count", count);
17793   fp = mp->path;
17794   for (i = 0; i < count; i++)
17795     {
17796       vl_api_mpls_fib_path_json_print (node, fp);
17797       fp++;
17798     }
17799 }
17800
17801 static int
17802 api_mpls_fib_dump (vat_main_t * vam)
17803 {
17804   vl_api_mpls_fib_dump_t *mp;
17805   vl_api_control_ping_t *mp_ping;
17806   int ret;
17807
17808   M (MPLS_FIB_DUMP, mp);
17809   S (mp);
17810
17811   /* Use a control ping for synchronization */
17812   M (CONTROL_PING, mp_ping);
17813   S (mp_ping);
17814
17815   W (ret);
17816   return ret;
17817 }
17818
17819 #define vl_api_ip_fib_details_t_endian vl_noop_handler
17820 #define vl_api_ip_fib_details_t_print vl_noop_handler
17821
17822 static void
17823 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
17824 {
17825   vat_main_t *vam = &vat_main;
17826   int count = ntohl (mp->count);
17827   vl_api_fib_path_t *fp;
17828   int i;
17829
17830   print (vam->ofp,
17831          "table-id %d, prefix %U/%d",
17832          ntohl (mp->table_id), format_ip4_address, mp->address,
17833          mp->address_length);
17834   fp = mp->path;
17835   for (i = 0; i < count; i++)
17836     {
17837       if (fp->afi == IP46_TYPE_IP6)
17838         print (vam->ofp,
17839                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
17840                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
17841                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
17842                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
17843                format_ip6_address, fp->next_hop);
17844       else if (fp->afi == IP46_TYPE_IP4)
17845         print (vam->ofp,
17846                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
17847                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
17848                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
17849                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
17850                format_ip4_address, fp->next_hop);
17851       fp++;
17852     }
17853 }
17854
17855 static void vl_api_ip_fib_details_t_handler_json
17856   (vl_api_ip_fib_details_t * mp)
17857 {
17858   vat_main_t *vam = &vat_main;
17859   int count = ntohl (mp->count);
17860   vat_json_node_t *node = NULL;
17861   struct in_addr ip4;
17862   struct in6_addr ip6;
17863   vl_api_fib_path_t *fp;
17864   int i;
17865
17866   if (VAT_JSON_ARRAY != vam->json_tree.type)
17867     {
17868       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17869       vat_json_init_array (&vam->json_tree);
17870     }
17871   node = vat_json_array_add (&vam->json_tree);
17872
17873   vat_json_init_object (node);
17874   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
17875   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
17876   vat_json_object_add_ip4 (node, "prefix", ip4);
17877   vat_json_object_add_uint (node, "mask_length", mp->address_length);
17878   vat_json_object_add_uint (node, "path_count", count);
17879   fp = mp->path;
17880   for (i = 0; i < count; i++)
17881     {
17882       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
17883       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
17884       vat_json_object_add_uint (node, "is_local", fp->is_local);
17885       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
17886       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
17887       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
17888       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
17889       if (fp->afi == IP46_TYPE_IP4)
17890         {
17891           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
17892           vat_json_object_add_ip4 (node, "next_hop", ip4);
17893         }
17894       else if (fp->afi == IP46_TYPE_IP6)
17895         {
17896           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
17897           vat_json_object_add_ip6 (node, "next_hop", ip6);
17898         }
17899     }
17900 }
17901
17902 static int
17903 api_ip_fib_dump (vat_main_t * vam)
17904 {
17905   vl_api_ip_fib_dump_t *mp;
17906   vl_api_control_ping_t *mp_ping;
17907   int ret;
17908
17909   M (IP_FIB_DUMP, mp);
17910   S (mp);
17911
17912   /* Use a control ping for synchronization */
17913   M (CONTROL_PING, mp_ping);
17914   S (mp_ping);
17915
17916   W (ret);
17917   return ret;
17918 }
17919
17920 static int
17921 api_ip_mfib_dump (vat_main_t * vam)
17922 {
17923   vl_api_ip_mfib_dump_t *mp;
17924   vl_api_control_ping_t *mp_ping;
17925   int ret;
17926
17927   M (IP_MFIB_DUMP, mp);
17928   S (mp);
17929
17930   /* Use a control ping for synchronization */
17931   M (CONTROL_PING, mp_ping);
17932   S (mp_ping);
17933
17934   W (ret);
17935   return ret;
17936 }
17937
17938 static void vl_api_ip_neighbor_details_t_handler
17939   (vl_api_ip_neighbor_details_t * mp)
17940 {
17941   vat_main_t *vam = &vat_main;
17942
17943   print (vam->ofp, "%c %U %U",
17944          (mp->is_static) ? 'S' : 'D',
17945          format_ethernet_address, &mp->mac_address,
17946          (mp->is_ipv6) ? format_ip6_address : format_ip4_address,
17947          &mp->ip_address);
17948 }
17949
17950 static void vl_api_ip_neighbor_details_t_handler_json
17951   (vl_api_ip_neighbor_details_t * mp)
17952 {
17953
17954   vat_main_t *vam = &vat_main;
17955   vat_json_node_t *node;
17956   struct in_addr ip4;
17957   struct in6_addr ip6;
17958
17959   if (VAT_JSON_ARRAY != vam->json_tree.type)
17960     {
17961       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17962       vat_json_init_array (&vam->json_tree);
17963     }
17964   node = vat_json_array_add (&vam->json_tree);
17965
17966   vat_json_init_object (node);
17967   vat_json_object_add_string_copy (node, "flag",
17968                                    (mp->is_static) ? (u8 *) "static" : (u8 *)
17969                                    "dynamic");
17970
17971   vat_json_object_add_string_copy (node, "link_layer",
17972                                    format (0, "%U", format_ethernet_address,
17973                                            &mp->mac_address));
17974
17975   if (mp->is_ipv6)
17976     {
17977       clib_memcpy (&ip6, &mp->ip_address, sizeof (ip6));
17978       vat_json_object_add_ip6 (node, "ip_address", ip6);
17979     }
17980   else
17981     {
17982       clib_memcpy (&ip4, &mp->ip_address, sizeof (ip4));
17983       vat_json_object_add_ip4 (node, "ip_address", ip4);
17984     }
17985 }
17986
17987 static int
17988 api_ip_neighbor_dump (vat_main_t * vam)
17989 {
17990   unformat_input_t *i = vam->input;
17991   vl_api_ip_neighbor_dump_t *mp;
17992   vl_api_control_ping_t *mp_ping;
17993   u8 is_ipv6 = 0;
17994   u32 sw_if_index = ~0;
17995   int ret;
17996
17997   /* Parse args required to build the message */
17998   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17999     {
18000       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18001         ;
18002       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18003         ;
18004       else if (unformat (i, "ip6"))
18005         is_ipv6 = 1;
18006       else
18007         break;
18008     }
18009
18010   if (sw_if_index == ~0)
18011     {
18012       errmsg ("missing interface name or sw_if_index");
18013       return -99;
18014     }
18015
18016   M (IP_NEIGHBOR_DUMP, mp);
18017   mp->is_ipv6 = (u8) is_ipv6;
18018   mp->sw_if_index = ntohl (sw_if_index);
18019   S (mp);
18020
18021   /* Use a control ping for synchronization */
18022   M (CONTROL_PING, mp_ping);
18023   S (mp_ping);
18024
18025   W (ret);
18026   return ret;
18027 }
18028
18029 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
18030 #define vl_api_ip6_fib_details_t_print vl_noop_handler
18031
18032 static void
18033 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
18034 {
18035   vat_main_t *vam = &vat_main;
18036   int count = ntohl (mp->count);
18037   vl_api_fib_path_t *fp;
18038   int i;
18039
18040   print (vam->ofp,
18041          "table-id %d, prefix %U/%d",
18042          ntohl (mp->table_id), format_ip6_address, mp->address,
18043          mp->address_length);
18044   fp = mp->path;
18045   for (i = 0; i < count; i++)
18046     {
18047       if (fp->afi == IP46_TYPE_IP6)
18048         print (vam->ofp,
18049                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
18050                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
18051                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
18052                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
18053                format_ip6_address, fp->next_hop);
18054       else if (fp->afi == IP46_TYPE_IP4)
18055         print (vam->ofp,
18056                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
18057                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
18058                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
18059                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
18060                format_ip4_address, fp->next_hop);
18061       fp++;
18062     }
18063 }
18064
18065 static void vl_api_ip6_fib_details_t_handler_json
18066   (vl_api_ip6_fib_details_t * mp)
18067 {
18068   vat_main_t *vam = &vat_main;
18069   int count = ntohl (mp->count);
18070   vat_json_node_t *node = NULL;
18071   struct in_addr ip4;
18072   struct in6_addr ip6;
18073   vl_api_fib_path_t *fp;
18074   int i;
18075
18076   if (VAT_JSON_ARRAY != vam->json_tree.type)
18077     {
18078       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18079       vat_json_init_array (&vam->json_tree);
18080     }
18081   node = vat_json_array_add (&vam->json_tree);
18082
18083   vat_json_init_object (node);
18084   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
18085   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
18086   vat_json_object_add_ip6 (node, "prefix", ip6);
18087   vat_json_object_add_uint (node, "mask_length", mp->address_length);
18088   vat_json_object_add_uint (node, "path_count", count);
18089   fp = mp->path;
18090   for (i = 0; i < count; i++)
18091     {
18092       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
18093       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
18094       vat_json_object_add_uint (node, "is_local", fp->is_local);
18095       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
18096       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
18097       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
18098       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
18099       if (fp->afi == IP46_TYPE_IP4)
18100         {
18101           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
18102           vat_json_object_add_ip4 (node, "next_hop", ip4);
18103         }
18104       else if (fp->afi == IP46_TYPE_IP6)
18105         {
18106           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
18107           vat_json_object_add_ip6 (node, "next_hop", ip6);
18108         }
18109     }
18110 }
18111
18112 static int
18113 api_ip6_fib_dump (vat_main_t * vam)
18114 {
18115   vl_api_ip6_fib_dump_t *mp;
18116   vl_api_control_ping_t *mp_ping;
18117   int ret;
18118
18119   M (IP6_FIB_DUMP, mp);
18120   S (mp);
18121
18122   /* Use a control ping for synchronization */
18123   M (CONTROL_PING, mp_ping);
18124   S (mp_ping);
18125
18126   W (ret);
18127   return ret;
18128 }
18129
18130 static int
18131 api_ip6_mfib_dump (vat_main_t * vam)
18132 {
18133   vl_api_ip6_mfib_dump_t *mp;
18134   vl_api_control_ping_t *mp_ping;
18135   int ret;
18136
18137   M (IP6_MFIB_DUMP, mp);
18138   S (mp);
18139
18140   /* Use a control ping for synchronization */
18141   M (CONTROL_PING, mp_ping);
18142   S (mp_ping);
18143
18144   W (ret);
18145   return ret;
18146 }
18147
18148 int
18149 api_classify_table_ids (vat_main_t * vam)
18150 {
18151   vl_api_classify_table_ids_t *mp;
18152   int ret;
18153
18154   /* Construct the API message */
18155   M (CLASSIFY_TABLE_IDS, mp);
18156   mp->context = 0;
18157
18158   S (mp);
18159   W (ret);
18160   return ret;
18161 }
18162
18163 int
18164 api_classify_table_by_interface (vat_main_t * vam)
18165 {
18166   unformat_input_t *input = vam->input;
18167   vl_api_classify_table_by_interface_t *mp;
18168
18169   u32 sw_if_index = ~0;
18170   int ret;
18171   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18172     {
18173       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18174         ;
18175       else if (unformat (input, "sw_if_index %d", &sw_if_index))
18176         ;
18177       else
18178         break;
18179     }
18180   if (sw_if_index == ~0)
18181     {
18182       errmsg ("missing interface name or sw_if_index");
18183       return -99;
18184     }
18185
18186   /* Construct the API message */
18187   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
18188   mp->context = 0;
18189   mp->sw_if_index = ntohl (sw_if_index);
18190
18191   S (mp);
18192   W (ret);
18193   return ret;
18194 }
18195
18196 int
18197 api_classify_table_info (vat_main_t * vam)
18198 {
18199   unformat_input_t *input = vam->input;
18200   vl_api_classify_table_info_t *mp;
18201
18202   u32 table_id = ~0;
18203   int ret;
18204   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18205     {
18206       if (unformat (input, "table_id %d", &table_id))
18207         ;
18208       else
18209         break;
18210     }
18211   if (table_id == ~0)
18212     {
18213       errmsg ("missing table id");
18214       return -99;
18215     }
18216
18217   /* Construct the API message */
18218   M (CLASSIFY_TABLE_INFO, mp);
18219   mp->context = 0;
18220   mp->table_id = ntohl (table_id);
18221
18222   S (mp);
18223   W (ret);
18224   return ret;
18225 }
18226
18227 int
18228 api_classify_session_dump (vat_main_t * vam)
18229 {
18230   unformat_input_t *input = vam->input;
18231   vl_api_classify_session_dump_t *mp;
18232   vl_api_control_ping_t *mp_ping;
18233
18234   u32 table_id = ~0;
18235   int ret;
18236   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18237     {
18238       if (unformat (input, "table_id %d", &table_id))
18239         ;
18240       else
18241         break;
18242     }
18243   if (table_id == ~0)
18244     {
18245       errmsg ("missing table id");
18246       return -99;
18247     }
18248
18249   /* Construct the API message */
18250   M (CLASSIFY_SESSION_DUMP, mp);
18251   mp->context = 0;
18252   mp->table_id = ntohl (table_id);
18253   S (mp);
18254
18255   /* Use a control ping for synchronization */
18256   M (CONTROL_PING, mp_ping);
18257   S (mp_ping);
18258
18259   W (ret);
18260   return ret;
18261 }
18262
18263 static void
18264 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
18265 {
18266   vat_main_t *vam = &vat_main;
18267
18268   print (vam->ofp, "collector_address %U, collector_port %d, "
18269          "src_address %U, vrf_id %d, path_mtu %u, "
18270          "template_interval %u, udp_checksum %d",
18271          format_ip4_address, mp->collector_address,
18272          ntohs (mp->collector_port),
18273          format_ip4_address, mp->src_address,
18274          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
18275          ntohl (mp->template_interval), mp->udp_checksum);
18276
18277   vam->retval = 0;
18278   vam->result_ready = 1;
18279 }
18280
18281 static void
18282   vl_api_ipfix_exporter_details_t_handler_json
18283   (vl_api_ipfix_exporter_details_t * mp)
18284 {
18285   vat_main_t *vam = &vat_main;
18286   vat_json_node_t node;
18287   struct in_addr collector_address;
18288   struct in_addr src_address;
18289
18290   vat_json_init_object (&node);
18291   clib_memcpy (&collector_address, &mp->collector_address,
18292                sizeof (collector_address));
18293   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
18294   vat_json_object_add_uint (&node, "collector_port",
18295                             ntohs (mp->collector_port));
18296   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
18297   vat_json_object_add_ip4 (&node, "src_address", src_address);
18298   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
18299   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
18300   vat_json_object_add_uint (&node, "template_interval",
18301                             ntohl (mp->template_interval));
18302   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
18303
18304   vat_json_print (vam->ofp, &node);
18305   vat_json_free (&node);
18306   vam->retval = 0;
18307   vam->result_ready = 1;
18308 }
18309
18310 int
18311 api_ipfix_exporter_dump (vat_main_t * vam)
18312 {
18313   vl_api_ipfix_exporter_dump_t *mp;
18314   int ret;
18315
18316   /* Construct the API message */
18317   M (IPFIX_EXPORTER_DUMP, mp);
18318   mp->context = 0;
18319
18320   S (mp);
18321   W (ret);
18322   return ret;
18323 }
18324
18325 static int
18326 api_ipfix_classify_stream_dump (vat_main_t * vam)
18327 {
18328   vl_api_ipfix_classify_stream_dump_t *mp;
18329   int ret;
18330
18331   /* Construct the API message */
18332   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
18333   mp->context = 0;
18334
18335   S (mp);
18336   W (ret);
18337   return ret;
18338   /* NOTREACHED */
18339   return 0;
18340 }
18341
18342 static void
18343   vl_api_ipfix_classify_stream_details_t_handler
18344   (vl_api_ipfix_classify_stream_details_t * mp)
18345 {
18346   vat_main_t *vam = &vat_main;
18347   print (vam->ofp, "domain_id %d, src_port %d",
18348          ntohl (mp->domain_id), ntohs (mp->src_port));
18349   vam->retval = 0;
18350   vam->result_ready = 1;
18351 }
18352
18353 static void
18354   vl_api_ipfix_classify_stream_details_t_handler_json
18355   (vl_api_ipfix_classify_stream_details_t * mp)
18356 {
18357   vat_main_t *vam = &vat_main;
18358   vat_json_node_t node;
18359
18360   vat_json_init_object (&node);
18361   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
18362   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
18363
18364   vat_json_print (vam->ofp, &node);
18365   vat_json_free (&node);
18366   vam->retval = 0;
18367   vam->result_ready = 1;
18368 }
18369
18370 static int
18371 api_ipfix_classify_table_dump (vat_main_t * vam)
18372 {
18373   vl_api_ipfix_classify_table_dump_t *mp;
18374   vl_api_control_ping_t *mp_ping;
18375   int ret;
18376
18377   if (!vam->json_output)
18378     {
18379       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
18380              "transport_protocol");
18381     }
18382
18383   /* Construct the API message */
18384   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
18385
18386   /* send it... */
18387   S (mp);
18388
18389   /* Use a control ping for synchronization */
18390   M (CONTROL_PING, mp_ping);
18391   S (mp_ping);
18392
18393   W (ret);
18394   return ret;
18395 }
18396
18397 static void
18398   vl_api_ipfix_classify_table_details_t_handler
18399   (vl_api_ipfix_classify_table_details_t * mp)
18400 {
18401   vat_main_t *vam = &vat_main;
18402   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
18403          mp->transport_protocol);
18404 }
18405
18406 static void
18407   vl_api_ipfix_classify_table_details_t_handler_json
18408   (vl_api_ipfix_classify_table_details_t * mp)
18409 {
18410   vat_json_node_t *node = NULL;
18411   vat_main_t *vam = &vat_main;
18412
18413   if (VAT_JSON_ARRAY != vam->json_tree.type)
18414     {
18415       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18416       vat_json_init_array (&vam->json_tree);
18417     }
18418
18419   node = vat_json_array_add (&vam->json_tree);
18420   vat_json_init_object (node);
18421
18422   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
18423   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
18424   vat_json_object_add_uint (node, "transport_protocol",
18425                             mp->transport_protocol);
18426 }
18427
18428 static int
18429 api_sw_interface_span_enable_disable (vat_main_t * vam)
18430 {
18431   unformat_input_t *i = vam->input;
18432   vl_api_sw_interface_span_enable_disable_t *mp;
18433   u32 src_sw_if_index = ~0;
18434   u32 dst_sw_if_index = ~0;
18435   u8 state = 3;
18436   int ret;
18437   u8 is_l2 = 0;
18438
18439   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18440     {
18441       if (unformat
18442           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
18443         ;
18444       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
18445         ;
18446       else
18447         if (unformat
18448             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
18449         ;
18450       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
18451         ;
18452       else if (unformat (i, "disable"))
18453         state = 0;
18454       else if (unformat (i, "rx"))
18455         state = 1;
18456       else if (unformat (i, "tx"))
18457         state = 2;
18458       else if (unformat (i, "both"))
18459         state = 3;
18460       else if (unformat (i, "l2"))
18461         is_l2 = 1;
18462       else
18463         break;
18464     }
18465
18466   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
18467
18468   mp->sw_if_index_from = htonl (src_sw_if_index);
18469   mp->sw_if_index_to = htonl (dst_sw_if_index);
18470   mp->state = state;
18471   mp->is_l2 = is_l2;
18472
18473   S (mp);
18474   W (ret);
18475   return ret;
18476 }
18477
18478 static void
18479 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
18480                                             * mp)
18481 {
18482   vat_main_t *vam = &vat_main;
18483   u8 *sw_if_from_name = 0;
18484   u8 *sw_if_to_name = 0;
18485   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
18486   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
18487   char *states[] = { "none", "rx", "tx", "both" };
18488   hash_pair_t *p;
18489
18490   /* *INDENT-OFF* */
18491   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
18492   ({
18493     if ((u32) p->value[0] == sw_if_index_from)
18494       {
18495         sw_if_from_name = (u8 *)(p->key);
18496         if (sw_if_to_name)
18497           break;
18498       }
18499     if ((u32) p->value[0] == sw_if_index_to)
18500       {
18501         sw_if_to_name = (u8 *)(p->key);
18502         if (sw_if_from_name)
18503           break;
18504       }
18505   }));
18506   /* *INDENT-ON* */
18507   print (vam->ofp, "%20s => %20s (%s)",
18508          sw_if_from_name, sw_if_to_name, states[mp->state]);
18509 }
18510
18511 static void
18512   vl_api_sw_interface_span_details_t_handler_json
18513   (vl_api_sw_interface_span_details_t * mp)
18514 {
18515   vat_main_t *vam = &vat_main;
18516   vat_json_node_t *node = NULL;
18517   u8 *sw_if_from_name = 0;
18518   u8 *sw_if_to_name = 0;
18519   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
18520   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
18521   hash_pair_t *p;
18522
18523   /* *INDENT-OFF* */
18524   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
18525   ({
18526     if ((u32) p->value[0] == sw_if_index_from)
18527       {
18528         sw_if_from_name = (u8 *)(p->key);
18529         if (sw_if_to_name)
18530           break;
18531       }
18532     if ((u32) p->value[0] == sw_if_index_to)
18533       {
18534         sw_if_to_name = (u8 *)(p->key);
18535         if (sw_if_from_name)
18536           break;
18537       }
18538   }));
18539   /* *INDENT-ON* */
18540
18541   if (VAT_JSON_ARRAY != vam->json_tree.type)
18542     {
18543       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18544       vat_json_init_array (&vam->json_tree);
18545     }
18546   node = vat_json_array_add (&vam->json_tree);
18547
18548   vat_json_init_object (node);
18549   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
18550   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
18551   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
18552   if (0 != sw_if_to_name)
18553     {
18554       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
18555     }
18556   vat_json_object_add_uint (node, "state", mp->state);
18557 }
18558
18559 static int
18560 api_sw_interface_span_dump (vat_main_t * vam)
18561 {
18562   unformat_input_t *input = vam->input;
18563   vl_api_sw_interface_span_dump_t *mp;
18564   vl_api_control_ping_t *mp_ping;
18565   u8 is_l2 = 0;
18566   int ret;
18567
18568   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18569     {
18570       if (unformat (input, "l2"))
18571         is_l2 = 1;
18572       else
18573         break;
18574     }
18575
18576   M (SW_INTERFACE_SPAN_DUMP, mp);
18577   mp->is_l2 = is_l2;
18578   S (mp);
18579
18580   /* Use a control ping for synchronization */
18581   M (CONTROL_PING, mp_ping);
18582   S (mp_ping);
18583
18584   W (ret);
18585   return ret;
18586 }
18587
18588 int
18589 api_pg_create_interface (vat_main_t * vam)
18590 {
18591   unformat_input_t *input = vam->input;
18592   vl_api_pg_create_interface_t *mp;
18593
18594   u32 if_id = ~0;
18595   int ret;
18596   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18597     {
18598       if (unformat (input, "if_id %d", &if_id))
18599         ;
18600       else
18601         break;
18602     }
18603   if (if_id == ~0)
18604     {
18605       errmsg ("missing pg interface index");
18606       return -99;
18607     }
18608
18609   /* Construct the API message */
18610   M (PG_CREATE_INTERFACE, mp);
18611   mp->context = 0;
18612   mp->interface_id = ntohl (if_id);
18613
18614   S (mp);
18615   W (ret);
18616   return ret;
18617 }
18618
18619 int
18620 api_pg_capture (vat_main_t * vam)
18621 {
18622   unformat_input_t *input = vam->input;
18623   vl_api_pg_capture_t *mp;
18624
18625   u32 if_id = ~0;
18626   u8 enable = 1;
18627   u32 count = 1;
18628   u8 pcap_file_set = 0;
18629   u8 *pcap_file = 0;
18630   int ret;
18631   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18632     {
18633       if (unformat (input, "if_id %d", &if_id))
18634         ;
18635       else if (unformat (input, "pcap %s", &pcap_file))
18636         pcap_file_set = 1;
18637       else if (unformat (input, "count %d", &count))
18638         ;
18639       else if (unformat (input, "disable"))
18640         enable = 0;
18641       else
18642         break;
18643     }
18644   if (if_id == ~0)
18645     {
18646       errmsg ("missing pg interface index");
18647       return -99;
18648     }
18649   if (pcap_file_set > 0)
18650     {
18651       if (vec_len (pcap_file) > 255)
18652         {
18653           errmsg ("pcap file name is too long");
18654           return -99;
18655         }
18656     }
18657
18658   u32 name_len = vec_len (pcap_file);
18659   /* Construct the API message */
18660   M (PG_CAPTURE, mp);
18661   mp->context = 0;
18662   mp->interface_id = ntohl (if_id);
18663   mp->is_enabled = enable;
18664   mp->count = ntohl (count);
18665   mp->pcap_name_length = ntohl (name_len);
18666   if (pcap_file_set != 0)
18667     {
18668       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
18669     }
18670   vec_free (pcap_file);
18671
18672   S (mp);
18673   W (ret);
18674   return ret;
18675 }
18676
18677 int
18678 api_pg_enable_disable (vat_main_t * vam)
18679 {
18680   unformat_input_t *input = vam->input;
18681   vl_api_pg_enable_disable_t *mp;
18682
18683   u8 enable = 1;
18684   u8 stream_name_set = 0;
18685   u8 *stream_name = 0;
18686   int ret;
18687   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18688     {
18689       if (unformat (input, "stream %s", &stream_name))
18690         stream_name_set = 1;
18691       else if (unformat (input, "disable"))
18692         enable = 0;
18693       else
18694         break;
18695     }
18696
18697   if (stream_name_set > 0)
18698     {
18699       if (vec_len (stream_name) > 255)
18700         {
18701           errmsg ("stream name too long");
18702           return -99;
18703         }
18704     }
18705
18706   u32 name_len = vec_len (stream_name);
18707   /* Construct the API message */
18708   M (PG_ENABLE_DISABLE, mp);
18709   mp->context = 0;
18710   mp->is_enabled = enable;
18711   if (stream_name_set != 0)
18712     {
18713       mp->stream_name_length = ntohl (name_len);
18714       clib_memcpy (mp->stream_name, stream_name, name_len);
18715     }
18716   vec_free (stream_name);
18717
18718   S (mp);
18719   W (ret);
18720   return ret;
18721 }
18722
18723 int
18724 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
18725 {
18726   unformat_input_t *input = vam->input;
18727   vl_api_ip_source_and_port_range_check_add_del_t *mp;
18728
18729   u16 *low_ports = 0;
18730   u16 *high_ports = 0;
18731   u16 this_low;
18732   u16 this_hi;
18733   ip4_address_t ip4_addr;
18734   ip6_address_t ip6_addr;
18735   u32 length;
18736   u32 tmp, tmp2;
18737   u8 prefix_set = 0;
18738   u32 vrf_id = ~0;
18739   u8 is_add = 1;
18740   u8 is_ipv6 = 0;
18741   int ret;
18742
18743   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18744     {
18745       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
18746         {
18747           prefix_set = 1;
18748         }
18749       else
18750         if (unformat
18751             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
18752         {
18753           prefix_set = 1;
18754           is_ipv6 = 1;
18755         }
18756       else if (unformat (input, "vrf %d", &vrf_id))
18757         ;
18758       else if (unformat (input, "del"))
18759         is_add = 0;
18760       else if (unformat (input, "port %d", &tmp))
18761         {
18762           if (tmp == 0 || tmp > 65535)
18763             {
18764               errmsg ("port %d out of range", tmp);
18765               return -99;
18766             }
18767           this_low = tmp;
18768           this_hi = this_low + 1;
18769           vec_add1 (low_ports, this_low);
18770           vec_add1 (high_ports, this_hi);
18771         }
18772       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
18773         {
18774           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
18775             {
18776               errmsg ("incorrect range parameters");
18777               return -99;
18778             }
18779           this_low = tmp;
18780           /* Note: in debug CLI +1 is added to high before
18781              passing to real fn that does "the work"
18782              (ip_source_and_port_range_check_add_del).
18783              This fn is a wrapper around the binary API fn a
18784              control plane will call, which expects this increment
18785              to have occurred. Hence letting the binary API control
18786              plane fn do the increment for consistency between VAT
18787              and other control planes.
18788            */
18789           this_hi = tmp2;
18790           vec_add1 (low_ports, this_low);
18791           vec_add1 (high_ports, this_hi);
18792         }
18793       else
18794         break;
18795     }
18796
18797   if (prefix_set == 0)
18798     {
18799       errmsg ("<address>/<mask> not specified");
18800       return -99;
18801     }
18802
18803   if (vrf_id == ~0)
18804     {
18805       errmsg ("VRF ID required, not specified");
18806       return -99;
18807     }
18808
18809   if (vrf_id == 0)
18810     {
18811       errmsg
18812         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
18813       return -99;
18814     }
18815
18816   if (vec_len (low_ports) == 0)
18817     {
18818       errmsg ("At least one port or port range required");
18819       return -99;
18820     }
18821
18822   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
18823
18824   mp->is_add = is_add;
18825
18826   if (is_ipv6)
18827     {
18828       mp->is_ipv6 = 1;
18829       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
18830     }
18831   else
18832     {
18833       mp->is_ipv6 = 0;
18834       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
18835     }
18836
18837   mp->mask_length = length;
18838   mp->number_of_ranges = vec_len (low_ports);
18839
18840   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
18841   vec_free (low_ports);
18842
18843   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
18844   vec_free (high_ports);
18845
18846   mp->vrf_id = ntohl (vrf_id);
18847
18848   S (mp);
18849   W (ret);
18850   return ret;
18851 }
18852
18853 int
18854 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
18855 {
18856   unformat_input_t *input = vam->input;
18857   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
18858   u32 sw_if_index = ~0;
18859   int vrf_set = 0;
18860   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
18861   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
18862   u8 is_add = 1;
18863   int ret;
18864
18865   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18866     {
18867       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18868         ;
18869       else if (unformat (input, "sw_if_index %d", &sw_if_index))
18870         ;
18871       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
18872         vrf_set = 1;
18873       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
18874         vrf_set = 1;
18875       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
18876         vrf_set = 1;
18877       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
18878         vrf_set = 1;
18879       else if (unformat (input, "del"))
18880         is_add = 0;
18881       else
18882         break;
18883     }
18884
18885   if (sw_if_index == ~0)
18886     {
18887       errmsg ("Interface required but not specified");
18888       return -99;
18889     }
18890
18891   if (vrf_set == 0)
18892     {
18893       errmsg ("VRF ID required but not specified");
18894       return -99;
18895     }
18896
18897   if (tcp_out_vrf_id == 0
18898       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
18899     {
18900       errmsg
18901         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
18902       return -99;
18903     }
18904
18905   /* Construct the API message */
18906   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
18907
18908   mp->sw_if_index = ntohl (sw_if_index);
18909   mp->is_add = is_add;
18910   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
18911   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
18912   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
18913   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
18914
18915   /* send it... */
18916   S (mp);
18917
18918   /* Wait for a reply... */
18919   W (ret);
18920   return ret;
18921 }
18922
18923 static int
18924 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
18925 {
18926   unformat_input_t *i = vam->input;
18927   vl_api_ipsec_gre_add_del_tunnel_t *mp;
18928   u32 local_sa_id = 0;
18929   u32 remote_sa_id = 0;
18930   ip4_address_t src_address;
18931   ip4_address_t dst_address;
18932   u8 is_add = 1;
18933   int ret;
18934
18935   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18936     {
18937       if (unformat (i, "local_sa %d", &local_sa_id))
18938         ;
18939       else if (unformat (i, "remote_sa %d", &remote_sa_id))
18940         ;
18941       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
18942         ;
18943       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
18944         ;
18945       else if (unformat (i, "del"))
18946         is_add = 0;
18947       else
18948         {
18949           clib_warning ("parse error '%U'", format_unformat_error, i);
18950           return -99;
18951         }
18952     }
18953
18954   M (IPSEC_GRE_ADD_DEL_TUNNEL, mp);
18955
18956   mp->local_sa_id = ntohl (local_sa_id);
18957   mp->remote_sa_id = ntohl (remote_sa_id);
18958   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
18959   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
18960   mp->is_add = is_add;
18961
18962   S (mp);
18963   W (ret);
18964   return ret;
18965 }
18966
18967 static int
18968 api_punt (vat_main_t * vam)
18969 {
18970   unformat_input_t *i = vam->input;
18971   vl_api_punt_t *mp;
18972   u32 ipv = ~0;
18973   u32 protocol = ~0;
18974   u32 port = ~0;
18975   int is_add = 1;
18976   int ret;
18977
18978   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18979     {
18980       if (unformat (i, "ip %d", &ipv))
18981         ;
18982       else if (unformat (i, "protocol %d", &protocol))
18983         ;
18984       else if (unformat (i, "port %d", &port))
18985         ;
18986       else if (unformat (i, "del"))
18987         is_add = 0;
18988       else
18989         {
18990           clib_warning ("parse error '%U'", format_unformat_error, i);
18991           return -99;
18992         }
18993     }
18994
18995   M (PUNT, mp);
18996
18997   mp->is_add = (u8) is_add;
18998   mp->ipv = (u8) ipv;
18999   mp->l4_protocol = (u8) protocol;
19000   mp->l4_port = htons ((u16) port);
19001
19002   S (mp);
19003   W (ret);
19004   return ret;
19005 }
19006
19007 static void vl_api_ipsec_gre_tunnel_details_t_handler
19008   (vl_api_ipsec_gre_tunnel_details_t * mp)
19009 {
19010   vat_main_t *vam = &vat_main;
19011
19012   print (vam->ofp, "%11d%15U%15U%14d%14d",
19013          ntohl (mp->sw_if_index),
19014          format_ip4_address, &mp->src_address,
19015          format_ip4_address, &mp->dst_address,
19016          ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
19017 }
19018
19019 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
19020   (vl_api_ipsec_gre_tunnel_details_t * mp)
19021 {
19022   vat_main_t *vam = &vat_main;
19023   vat_json_node_t *node = NULL;
19024   struct in_addr ip4;
19025
19026   if (VAT_JSON_ARRAY != vam->json_tree.type)
19027     {
19028       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19029       vat_json_init_array (&vam->json_tree);
19030     }
19031   node = vat_json_array_add (&vam->json_tree);
19032
19033   vat_json_init_object (node);
19034   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
19035   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
19036   vat_json_object_add_ip4 (node, "src_address", ip4);
19037   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
19038   vat_json_object_add_ip4 (node, "dst_address", ip4);
19039   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
19040   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
19041 }
19042
19043 static int
19044 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
19045 {
19046   unformat_input_t *i = vam->input;
19047   vl_api_ipsec_gre_tunnel_dump_t *mp;
19048   vl_api_control_ping_t *mp_ping;
19049   u32 sw_if_index;
19050   u8 sw_if_index_set = 0;
19051   int ret;
19052
19053   /* Parse args required to build the message */
19054   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19055     {
19056       if (unformat (i, "sw_if_index %d", &sw_if_index))
19057         sw_if_index_set = 1;
19058       else
19059         break;
19060     }
19061
19062   if (sw_if_index_set == 0)
19063     {
19064       sw_if_index = ~0;
19065     }
19066
19067   if (!vam->json_output)
19068     {
19069       print (vam->ofp, "%11s%15s%15s%14s%14s",
19070              "sw_if_index", "src_address", "dst_address",
19071              "local_sa_id", "remote_sa_id");
19072     }
19073
19074   /* Get list of gre-tunnel interfaces */
19075   M (IPSEC_GRE_TUNNEL_DUMP, mp);
19076
19077   mp->sw_if_index = htonl (sw_if_index);
19078
19079   S (mp);
19080
19081   /* Use a control ping for synchronization */
19082   M (CONTROL_PING, mp_ping);
19083   S (mp_ping);
19084
19085   W (ret);
19086   return ret;
19087 }
19088
19089 static int
19090 api_delete_subif (vat_main_t * vam)
19091 {
19092   unformat_input_t *i = vam->input;
19093   vl_api_delete_subif_t *mp;
19094   u32 sw_if_index = ~0;
19095   int ret;
19096
19097   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19098     {
19099       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19100         ;
19101       if (unformat (i, "sw_if_index %d", &sw_if_index))
19102         ;
19103       else
19104         break;
19105     }
19106
19107   if (sw_if_index == ~0)
19108     {
19109       errmsg ("missing sw_if_index");
19110       return -99;
19111     }
19112
19113   /* Construct the API message */
19114   M (DELETE_SUBIF, mp);
19115   mp->sw_if_index = ntohl (sw_if_index);
19116
19117   S (mp);
19118   W (ret);
19119   return ret;
19120 }
19121
19122 #define foreach_pbb_vtr_op      \
19123 _("disable",  L2_VTR_DISABLED)  \
19124 _("pop",  L2_VTR_POP_2)         \
19125 _("push",  L2_VTR_PUSH_2)
19126
19127 static int
19128 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
19129 {
19130   unformat_input_t *i = vam->input;
19131   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
19132   u32 sw_if_index = ~0, vtr_op = ~0;
19133   u16 outer_tag = ~0;
19134   u8 dmac[6], smac[6];
19135   u8 dmac_set = 0, smac_set = 0;
19136   u16 vlanid = 0;
19137   u32 sid = ~0;
19138   u32 tmp;
19139   int ret;
19140
19141   /* Shut up coverity */
19142   memset (dmac, 0, sizeof (dmac));
19143   memset (smac, 0, sizeof (smac));
19144
19145   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19146     {
19147       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19148         ;
19149       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19150         ;
19151       else if (unformat (i, "vtr_op %d", &vtr_op))
19152         ;
19153 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
19154       foreach_pbb_vtr_op
19155 #undef _
19156         else if (unformat (i, "translate_pbb_stag"))
19157         {
19158           if (unformat (i, "%d", &tmp))
19159             {
19160               vtr_op = L2_VTR_TRANSLATE_2_1;
19161               outer_tag = tmp;
19162             }
19163           else
19164             {
19165               errmsg
19166                 ("translate_pbb_stag operation requires outer tag definition");
19167               return -99;
19168             }
19169         }
19170       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
19171         dmac_set++;
19172       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
19173         smac_set++;
19174       else if (unformat (i, "sid %d", &sid))
19175         ;
19176       else if (unformat (i, "vlanid %d", &tmp))
19177         vlanid = tmp;
19178       else
19179         {
19180           clib_warning ("parse error '%U'", format_unformat_error, i);
19181           return -99;
19182         }
19183     }
19184
19185   if ((sw_if_index == ~0) || (vtr_op == ~0))
19186     {
19187       errmsg ("missing sw_if_index or vtr operation");
19188       return -99;
19189     }
19190   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
19191       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
19192     {
19193       errmsg
19194         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
19195       return -99;
19196     }
19197
19198   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
19199   mp->sw_if_index = ntohl (sw_if_index);
19200   mp->vtr_op = ntohl (vtr_op);
19201   mp->outer_tag = ntohs (outer_tag);
19202   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
19203   clib_memcpy (mp->b_smac, smac, sizeof (smac));
19204   mp->b_vlanid = ntohs (vlanid);
19205   mp->i_sid = ntohl (sid);
19206
19207   S (mp);
19208   W (ret);
19209   return ret;
19210 }
19211
19212 static int
19213 api_flow_classify_set_interface (vat_main_t * vam)
19214 {
19215   unformat_input_t *i = vam->input;
19216   vl_api_flow_classify_set_interface_t *mp;
19217   u32 sw_if_index;
19218   int sw_if_index_set;
19219   u32 ip4_table_index = ~0;
19220   u32 ip6_table_index = ~0;
19221   u8 is_add = 1;
19222   int ret;
19223
19224   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19225     {
19226       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19227         sw_if_index_set = 1;
19228       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19229         sw_if_index_set = 1;
19230       else if (unformat (i, "del"))
19231         is_add = 0;
19232       else if (unformat (i, "ip4-table %d", &ip4_table_index))
19233         ;
19234       else if (unformat (i, "ip6-table %d", &ip6_table_index))
19235         ;
19236       else
19237         {
19238           clib_warning ("parse error '%U'", format_unformat_error, i);
19239           return -99;
19240         }
19241     }
19242
19243   if (sw_if_index_set == 0)
19244     {
19245       errmsg ("missing interface name or sw_if_index");
19246       return -99;
19247     }
19248
19249   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
19250
19251   mp->sw_if_index = ntohl (sw_if_index);
19252   mp->ip4_table_index = ntohl (ip4_table_index);
19253   mp->ip6_table_index = ntohl (ip6_table_index);
19254   mp->is_add = is_add;
19255
19256   S (mp);
19257   W (ret);
19258   return ret;
19259 }
19260
19261 static int
19262 api_flow_classify_dump (vat_main_t * vam)
19263 {
19264   unformat_input_t *i = vam->input;
19265   vl_api_flow_classify_dump_t *mp;
19266   vl_api_control_ping_t *mp_ping;
19267   u8 type = FLOW_CLASSIFY_N_TABLES;
19268   int ret;
19269
19270   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
19271     ;
19272   else
19273     {
19274       errmsg ("classify table type must be specified");
19275       return -99;
19276     }
19277
19278   if (!vam->json_output)
19279     {
19280       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
19281     }
19282
19283   M (FLOW_CLASSIFY_DUMP, mp);
19284   mp->type = type;
19285   /* send it... */
19286   S (mp);
19287
19288   /* Use a control ping for synchronization */
19289   M (CONTROL_PING, mp_ping);
19290   S (mp_ping);
19291
19292   /* Wait for a reply... */
19293   W (ret);
19294   return ret;
19295 }
19296
19297 static int
19298 api_feature_enable_disable (vat_main_t * vam)
19299 {
19300   unformat_input_t *i = vam->input;
19301   vl_api_feature_enable_disable_t *mp;
19302   u8 *arc_name = 0;
19303   u8 *feature_name = 0;
19304   u32 sw_if_index = ~0;
19305   u8 enable = 1;
19306   int ret;
19307
19308   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19309     {
19310       if (unformat (i, "arc_name %s", &arc_name))
19311         ;
19312       else if (unformat (i, "feature_name %s", &feature_name))
19313         ;
19314       else
19315         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19316         ;
19317       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19318         ;
19319       else if (unformat (i, "disable"))
19320         enable = 0;
19321       else
19322         break;
19323     }
19324
19325   if (arc_name == 0)
19326     {
19327       errmsg ("missing arc name");
19328       return -99;
19329     }
19330   if (vec_len (arc_name) > 63)
19331     {
19332       errmsg ("arc name too long");
19333     }
19334
19335   if (feature_name == 0)
19336     {
19337       errmsg ("missing feature name");
19338       return -99;
19339     }
19340   if (vec_len (feature_name) > 63)
19341     {
19342       errmsg ("feature name too long");
19343     }
19344
19345   if (sw_if_index == ~0)
19346     {
19347       errmsg ("missing interface name or sw_if_index");
19348       return -99;
19349     }
19350
19351   /* Construct the API message */
19352   M (FEATURE_ENABLE_DISABLE, mp);
19353   mp->sw_if_index = ntohl (sw_if_index);
19354   mp->enable = enable;
19355   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
19356   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
19357   vec_free (arc_name);
19358   vec_free (feature_name);
19359
19360   S (mp);
19361   W (ret);
19362   return ret;
19363 }
19364
19365 static int
19366 api_sw_interface_tag_add_del (vat_main_t * vam)
19367 {
19368   unformat_input_t *i = vam->input;
19369   vl_api_sw_interface_tag_add_del_t *mp;
19370   u32 sw_if_index = ~0;
19371   u8 *tag = 0;
19372   u8 enable = 1;
19373   int ret;
19374
19375   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19376     {
19377       if (unformat (i, "tag %s", &tag))
19378         ;
19379       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19380         ;
19381       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19382         ;
19383       else if (unformat (i, "del"))
19384         enable = 0;
19385       else
19386         break;
19387     }
19388
19389   if (sw_if_index == ~0)
19390     {
19391       errmsg ("missing interface name or sw_if_index");
19392       return -99;
19393     }
19394
19395   if (enable && (tag == 0))
19396     {
19397       errmsg ("no tag specified");
19398       return -99;
19399     }
19400
19401   /* Construct the API message */
19402   M (SW_INTERFACE_TAG_ADD_DEL, mp);
19403   mp->sw_if_index = ntohl (sw_if_index);
19404   mp->is_add = enable;
19405   if (enable)
19406     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
19407   vec_free (tag);
19408
19409   S (mp);
19410   W (ret);
19411   return ret;
19412 }
19413
19414 static void vl_api_l2_xconnect_details_t_handler
19415   (vl_api_l2_xconnect_details_t * mp)
19416 {
19417   vat_main_t *vam = &vat_main;
19418
19419   print (vam->ofp, "%15d%15d",
19420          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
19421 }
19422
19423 static void vl_api_l2_xconnect_details_t_handler_json
19424   (vl_api_l2_xconnect_details_t * mp)
19425 {
19426   vat_main_t *vam = &vat_main;
19427   vat_json_node_t *node = NULL;
19428
19429   if (VAT_JSON_ARRAY != vam->json_tree.type)
19430     {
19431       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19432       vat_json_init_array (&vam->json_tree);
19433     }
19434   node = vat_json_array_add (&vam->json_tree);
19435
19436   vat_json_init_object (node);
19437   vat_json_object_add_uint (node, "rx_sw_if_index",
19438                             ntohl (mp->rx_sw_if_index));
19439   vat_json_object_add_uint (node, "tx_sw_if_index",
19440                             ntohl (mp->tx_sw_if_index));
19441 }
19442
19443 static int
19444 api_l2_xconnect_dump (vat_main_t * vam)
19445 {
19446   vl_api_l2_xconnect_dump_t *mp;
19447   vl_api_control_ping_t *mp_ping;
19448   int ret;
19449
19450   if (!vam->json_output)
19451     {
19452       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
19453     }
19454
19455   M (L2_XCONNECT_DUMP, mp);
19456
19457   S (mp);
19458
19459   /* Use a control ping for synchronization */
19460   M (CONTROL_PING, mp_ping);
19461   S (mp_ping);
19462
19463   W (ret);
19464   return ret;
19465 }
19466
19467 static int
19468 api_sw_interface_set_mtu (vat_main_t * vam)
19469 {
19470   unformat_input_t *i = vam->input;
19471   vl_api_sw_interface_set_mtu_t *mp;
19472   u32 sw_if_index = ~0;
19473   u32 mtu = 0;
19474   int ret;
19475
19476   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19477     {
19478       if (unformat (i, "mtu %d", &mtu))
19479         ;
19480       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19481         ;
19482       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19483         ;
19484       else
19485         break;
19486     }
19487
19488   if (sw_if_index == ~0)
19489     {
19490       errmsg ("missing interface name or sw_if_index");
19491       return -99;
19492     }
19493
19494   if (mtu == 0)
19495     {
19496       errmsg ("no mtu specified");
19497       return -99;
19498     }
19499
19500   /* Construct the API message */
19501   M (SW_INTERFACE_SET_MTU, mp);
19502   mp->sw_if_index = ntohl (sw_if_index);
19503   mp->mtu = ntohs ((u16) mtu);
19504
19505   S (mp);
19506   W (ret);
19507   return ret;
19508 }
19509
19510 static int
19511 api_p2p_ethernet_add (vat_main_t * vam)
19512 {
19513   unformat_input_t *i = vam->input;
19514   vl_api_p2p_ethernet_add_t *mp;
19515   u32 parent_if_index = ~0;
19516   u32 sub_id = ~0;
19517   u8 remote_mac[6];
19518   u8 mac_set = 0;
19519   int ret;
19520
19521   memset (remote_mac, 0, sizeof (remote_mac));
19522   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19523     {
19524       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
19525         ;
19526       else if (unformat (i, "sw_if_index %d", &parent_if_index))
19527         ;
19528       else
19529         if (unformat
19530             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
19531         mac_set++;
19532       else if (unformat (i, "sub_id %d", &sub_id))
19533         ;
19534       else
19535         {
19536           clib_warning ("parse error '%U'", format_unformat_error, i);
19537           return -99;
19538         }
19539     }
19540
19541   if (parent_if_index == ~0)
19542     {
19543       errmsg ("missing interface name or sw_if_index");
19544       return -99;
19545     }
19546   if (mac_set == 0)
19547     {
19548       errmsg ("missing remote mac address");
19549       return -99;
19550     }
19551   if (sub_id == ~0)
19552     {
19553       errmsg ("missing sub-interface id");
19554       return -99;
19555     }
19556
19557   M (P2P_ETHERNET_ADD, mp);
19558   mp->parent_if_index = ntohl (parent_if_index);
19559   mp->subif_id = ntohl (sub_id);
19560   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
19561
19562   S (mp);
19563   W (ret);
19564   return ret;
19565 }
19566
19567 static int
19568 api_p2p_ethernet_del (vat_main_t * vam)
19569 {
19570   unformat_input_t *i = vam->input;
19571   vl_api_p2p_ethernet_del_t *mp;
19572   u32 parent_if_index = ~0;
19573   u8 remote_mac[6];
19574   u8 mac_set = 0;
19575   int ret;
19576
19577   memset (remote_mac, 0, sizeof (remote_mac));
19578   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19579     {
19580       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
19581         ;
19582       else if (unformat (i, "sw_if_index %d", &parent_if_index))
19583         ;
19584       else
19585         if (unformat
19586             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
19587         mac_set++;
19588       else
19589         {
19590           clib_warning ("parse error '%U'", format_unformat_error, i);
19591           return -99;
19592         }
19593     }
19594
19595   if (parent_if_index == ~0)
19596     {
19597       errmsg ("missing interface name or sw_if_index");
19598       return -99;
19599     }
19600   if (mac_set == 0)
19601     {
19602       errmsg ("missing remote mac address");
19603       return -99;
19604     }
19605
19606   M (P2P_ETHERNET_DEL, mp);
19607   mp->parent_if_index = ntohl (parent_if_index);
19608   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
19609
19610   S (mp);
19611   W (ret);
19612   return ret;
19613 }
19614
19615 static int
19616 api_lldp_config (vat_main_t * vam)
19617 {
19618   unformat_input_t *i = vam->input;
19619   vl_api_lldp_config_t *mp;
19620   int tx_hold = 0;
19621   int tx_interval = 0;
19622   u8 *sys_name = NULL;
19623   int ret;
19624
19625   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19626     {
19627       if (unformat (i, "system-name %s", &sys_name))
19628         ;
19629       else if (unformat (i, "tx-hold %d", &tx_hold))
19630         ;
19631       else if (unformat (i, "tx-interval %d", &tx_interval))
19632         ;
19633       else
19634         {
19635           clib_warning ("parse error '%U'", format_unformat_error, i);
19636           return -99;
19637         }
19638     }
19639
19640   vec_add1 (sys_name, 0);
19641
19642   M (LLDP_CONFIG, mp);
19643   mp->tx_hold = htonl (tx_hold);
19644   mp->tx_interval = htonl (tx_interval);
19645   clib_memcpy (mp->system_name, sys_name, vec_len (sys_name));
19646   vec_free (sys_name);
19647
19648   S (mp);
19649   W (ret);
19650   return ret;
19651 }
19652
19653 static int
19654 api_sw_interface_set_lldp (vat_main_t * vam)
19655 {
19656   unformat_input_t *i = vam->input;
19657   vl_api_sw_interface_set_lldp_t *mp;
19658   u32 sw_if_index = ~0;
19659   u32 enable = 1;
19660   u8 *port_desc = NULL;
19661   int ret;
19662
19663   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19664     {
19665       if (unformat (i, "disable"))
19666         enable = 0;
19667       else
19668         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19669         ;
19670       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19671         ;
19672       else if (unformat (i, "port-desc %s", &port_desc))
19673         ;
19674       else
19675         break;
19676     }
19677
19678   if (sw_if_index == ~0)
19679     {
19680       errmsg ("missing interface name or sw_if_index");
19681       return -99;
19682     }
19683
19684   /* Construct the API message */
19685   vec_add1 (port_desc, 0);
19686   M (SW_INTERFACE_SET_LLDP, mp);
19687   mp->sw_if_index = ntohl (sw_if_index);
19688   mp->enable = enable;
19689   clib_memcpy (mp->port_desc, port_desc, vec_len (port_desc));
19690   vec_free (port_desc);
19691
19692   S (mp);
19693   W (ret);
19694   return ret;
19695 }
19696
19697 static int
19698 q_or_quit (vat_main_t * vam)
19699 {
19700 #if VPP_API_TEST_BUILTIN == 0
19701   longjmp (vam->jump_buf, 1);
19702 #endif
19703   return 0;                     /* not so much */
19704 }
19705
19706 static int
19707 q (vat_main_t * vam)
19708 {
19709   return q_or_quit (vam);
19710 }
19711
19712 static int
19713 quit (vat_main_t * vam)
19714 {
19715   return q_or_quit (vam);
19716 }
19717
19718 static int
19719 comment (vat_main_t * vam)
19720 {
19721   return 0;
19722 }
19723
19724 static int
19725 cmd_cmp (void *a1, void *a2)
19726 {
19727   u8 **c1 = a1;
19728   u8 **c2 = a2;
19729
19730   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
19731 }
19732
19733 static int
19734 help (vat_main_t * vam)
19735 {
19736   u8 **cmds = 0;
19737   u8 *name = 0;
19738   hash_pair_t *p;
19739   unformat_input_t *i = vam->input;
19740   int j;
19741
19742   if (unformat (i, "%s", &name))
19743     {
19744       uword *hs;
19745
19746       vec_add1 (name, 0);
19747
19748       hs = hash_get_mem (vam->help_by_name, name);
19749       if (hs)
19750         print (vam->ofp, "usage: %s %s", name, hs[0]);
19751       else
19752         print (vam->ofp, "No such msg / command '%s'", name);
19753       vec_free (name);
19754       return 0;
19755     }
19756
19757   print (vam->ofp, "Help is available for the following:");
19758
19759     /* *INDENT-OFF* */
19760     hash_foreach_pair (p, vam->function_by_name,
19761     ({
19762       vec_add1 (cmds, (u8 *)(p->key));
19763     }));
19764     /* *INDENT-ON* */
19765
19766   vec_sort_with_function (cmds, cmd_cmp);
19767
19768   for (j = 0; j < vec_len (cmds); j++)
19769     print (vam->ofp, "%s", cmds[j]);
19770
19771   vec_free (cmds);
19772   return 0;
19773 }
19774
19775 static int
19776 set (vat_main_t * vam)
19777 {
19778   u8 *name = 0, *value = 0;
19779   unformat_input_t *i = vam->input;
19780
19781   if (unformat (i, "%s", &name))
19782     {
19783       /* The input buffer is a vector, not a string. */
19784       value = vec_dup (i->buffer);
19785       vec_delete (value, i->index, 0);
19786       /* Almost certainly has a trailing newline */
19787       if (value[vec_len (value) - 1] == '\n')
19788         value[vec_len (value) - 1] = 0;
19789       /* Make sure it's a proper string, one way or the other */
19790       vec_add1 (value, 0);
19791       (void) clib_macro_set_value (&vam->macro_main,
19792                                    (char *) name, (char *) value);
19793     }
19794   else
19795     errmsg ("usage: set <name> <value>");
19796
19797   vec_free (name);
19798   vec_free (value);
19799   return 0;
19800 }
19801
19802 static int
19803 unset (vat_main_t * vam)
19804 {
19805   u8 *name = 0;
19806
19807   if (unformat (vam->input, "%s", &name))
19808     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
19809       errmsg ("unset: %s wasn't set", name);
19810   vec_free (name);
19811   return 0;
19812 }
19813
19814 typedef struct
19815 {
19816   u8 *name;
19817   u8 *value;
19818 } macro_sort_t;
19819
19820
19821 static int
19822 macro_sort_cmp (void *a1, void *a2)
19823 {
19824   macro_sort_t *s1 = a1;
19825   macro_sort_t *s2 = a2;
19826
19827   return strcmp ((char *) (s1->name), (char *) (s2->name));
19828 }
19829
19830 static int
19831 dump_macro_table (vat_main_t * vam)
19832 {
19833   macro_sort_t *sort_me = 0, *sm;
19834   int i;
19835   hash_pair_t *p;
19836
19837     /* *INDENT-OFF* */
19838     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
19839     ({
19840       vec_add2 (sort_me, sm, 1);
19841       sm->name = (u8 *)(p->key);
19842       sm->value = (u8 *) (p->value[0]);
19843     }));
19844     /* *INDENT-ON* */
19845
19846   vec_sort_with_function (sort_me, macro_sort_cmp);
19847
19848   if (vec_len (sort_me))
19849     print (vam->ofp, "%-15s%s", "Name", "Value");
19850   else
19851     print (vam->ofp, "The macro table is empty...");
19852
19853   for (i = 0; i < vec_len (sort_me); i++)
19854     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
19855   return 0;
19856 }
19857
19858 static int
19859 dump_node_table (vat_main_t * vam)
19860 {
19861   int i, j;
19862   vlib_node_t *node, *next_node;
19863
19864   if (vec_len (vam->graph_nodes) == 0)
19865     {
19866       print (vam->ofp, "Node table empty, issue get_node_graph...");
19867       return 0;
19868     }
19869
19870   for (i = 0; i < vec_len (vam->graph_nodes); i++)
19871     {
19872       node = vam->graph_nodes[i];
19873       print (vam->ofp, "[%d] %s", i, node->name);
19874       for (j = 0; j < vec_len (node->next_nodes); j++)
19875         {
19876           if (node->next_nodes[j] != ~0)
19877             {
19878               next_node = vam->graph_nodes[node->next_nodes[j]];
19879               print (vam->ofp, "  [%d] %s", j, next_node->name);
19880             }
19881         }
19882     }
19883   return 0;
19884 }
19885
19886 static int
19887 value_sort_cmp (void *a1, void *a2)
19888 {
19889   name_sort_t *n1 = a1;
19890   name_sort_t *n2 = a2;
19891
19892   if (n1->value < n2->value)
19893     return -1;
19894   if (n1->value > n2->value)
19895     return 1;
19896   return 0;
19897 }
19898
19899
19900 static int
19901 dump_msg_api_table (vat_main_t * vam)
19902 {
19903   api_main_t *am = &api_main;
19904   name_sort_t *nses = 0, *ns;
19905   hash_pair_t *hp;
19906   int i;
19907
19908   /* *INDENT-OFF* */
19909   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
19910   ({
19911     vec_add2 (nses, ns, 1);
19912     ns->name = (u8 *)(hp->key);
19913     ns->value = (u32) hp->value[0];
19914   }));
19915   /* *INDENT-ON* */
19916
19917   vec_sort_with_function (nses, value_sort_cmp);
19918
19919   for (i = 0; i < vec_len (nses); i++)
19920     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
19921   vec_free (nses);
19922   return 0;
19923 }
19924
19925 static int
19926 get_msg_id (vat_main_t * vam)
19927 {
19928   u8 *name_and_crc;
19929   u32 message_index;
19930
19931   if (unformat (vam->input, "%s", &name_and_crc))
19932     {
19933       message_index = vl_api_get_msg_index (name_and_crc);
19934       if (message_index == ~0)
19935         {
19936           print (vam->ofp, " '%s' not found", name_and_crc);
19937           return 0;
19938         }
19939       print (vam->ofp, " '%s' has message index %d",
19940              name_and_crc, message_index);
19941       return 0;
19942     }
19943   errmsg ("name_and_crc required...");
19944   return 0;
19945 }
19946
19947 static int
19948 search_node_table (vat_main_t * vam)
19949 {
19950   unformat_input_t *line_input = vam->input;
19951   u8 *node_to_find;
19952   int j;
19953   vlib_node_t *node, *next_node;
19954   uword *p;
19955
19956   if (vam->graph_node_index_by_name == 0)
19957     {
19958       print (vam->ofp, "Node table empty, issue get_node_graph...");
19959       return 0;
19960     }
19961
19962   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
19963     {
19964       if (unformat (line_input, "%s", &node_to_find))
19965         {
19966           vec_add1 (node_to_find, 0);
19967           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
19968           if (p == 0)
19969             {
19970               print (vam->ofp, "%s not found...", node_to_find);
19971               goto out;
19972             }
19973           node = vam->graph_nodes[p[0]];
19974           print (vam->ofp, "[%d] %s", p[0], node->name);
19975           for (j = 0; j < vec_len (node->next_nodes); j++)
19976             {
19977               if (node->next_nodes[j] != ~0)
19978                 {
19979                   next_node = vam->graph_nodes[node->next_nodes[j]];
19980                   print (vam->ofp, "  [%d] %s", j, next_node->name);
19981                 }
19982             }
19983         }
19984
19985       else
19986         {
19987           clib_warning ("parse error '%U'", format_unformat_error,
19988                         line_input);
19989           return -99;
19990         }
19991
19992     out:
19993       vec_free (node_to_find);
19994
19995     }
19996
19997   return 0;
19998 }
19999
20000
20001 static int
20002 script (vat_main_t * vam)
20003 {
20004 #if (VPP_API_TEST_BUILTIN==0)
20005   u8 *s = 0;
20006   char *save_current_file;
20007   unformat_input_t save_input;
20008   jmp_buf save_jump_buf;
20009   u32 save_line_number;
20010
20011   FILE *new_fp, *save_ifp;
20012
20013   if (unformat (vam->input, "%s", &s))
20014     {
20015       new_fp = fopen ((char *) s, "r");
20016       if (new_fp == 0)
20017         {
20018           errmsg ("Couldn't open script file %s", s);
20019           vec_free (s);
20020           return -99;
20021         }
20022     }
20023   else
20024     {
20025       errmsg ("Missing script name");
20026       return -99;
20027     }
20028
20029   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
20030   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
20031   save_ifp = vam->ifp;
20032   save_line_number = vam->input_line_number;
20033   save_current_file = (char *) vam->current_file;
20034
20035   vam->input_line_number = 0;
20036   vam->ifp = new_fp;
20037   vam->current_file = s;
20038   do_one_file (vam);
20039
20040   clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
20041   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
20042   vam->ifp = save_ifp;
20043   vam->input_line_number = save_line_number;
20044   vam->current_file = (u8 *) save_current_file;
20045   vec_free (s);
20046
20047   return 0;
20048 #else
20049   clib_warning ("use the exec command...");
20050   return -99;
20051 #endif
20052 }
20053
20054 static int
20055 echo (vat_main_t * vam)
20056 {
20057   print (vam->ofp, "%v", vam->input->buffer);
20058   return 0;
20059 }
20060
20061 /* List of API message constructors, CLI names map to api_xxx */
20062 #define foreach_vpe_api_msg                                             \
20063 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
20064 _(sw_interface_dump,"")                                                 \
20065 _(sw_interface_set_flags,                                               \
20066   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
20067 _(sw_interface_add_del_address,                                         \
20068   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
20069 _(sw_interface_set_table,                                               \
20070   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
20071 _(sw_interface_set_mpls_enable,                                         \
20072   "<intfc> | sw_if_index [disable | dis]")                              \
20073 _(sw_interface_set_vpath,                                               \
20074   "<intfc> | sw_if_index <id> enable | disable")                        \
20075 _(sw_interface_set_vxlan_bypass,                                        \
20076   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
20077 _(sw_interface_set_l2_xconnect,                                         \
20078   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
20079   "enable | disable")                                                   \
20080 _(sw_interface_set_l2_bridge,                                           \
20081   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
20082   "[shg <split-horizon-group>] [bvi]\n"                                 \
20083   "enable | disable")                                                   \
20084 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
20085 _(bridge_domain_add_del,                                                \
20086   "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") \
20087 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
20088 _(l2fib_add_del,                                                        \
20089   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
20090 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
20091 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
20092 _(l2_flags,                                                             \
20093   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
20094 _(bridge_flags,                                                         \
20095   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
20096 _(tap_connect,                                                          \
20097   "tapname <name> mac <mac-addr> | random-mac [tag <string>]")          \
20098 _(tap_modify,                                                           \
20099   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
20100 _(tap_delete,                                                           \
20101   "<vpp-if-name> | sw_if_index <id>")                                   \
20102 _(sw_interface_tap_dump, "")                                            \
20103 _(ip_table_add_del,                                                     \
20104   "table-id <n> [ipv6]\n")                                              \
20105 _(ip_add_del_route,                                                     \
20106   "<addr>/<mask> via <addr> [table-id <n>]\n"                           \
20107   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
20108   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
20109   "[multipath] [count <n>]")                                            \
20110 _(ip_mroute_add_del,                                                    \
20111   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
20112   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
20113 _(mpls_table_add_del,                                                   \
20114   "table-id <n>\n")                                                     \
20115 _(mpls_route_add_del,                                                   \
20116   "<label> <eos> via <addr> [table-id <n>]\n"                           \
20117   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
20118   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
20119   "[multipath] [count <n>]")                                            \
20120 _(mpls_ip_bind_unbind,                                                  \
20121   "<label> <addr/len>")                                                 \
20122 _(mpls_tunnel_add_del,                                                  \
20123   " via <addr> [table-id <n>]\n"                                        \
20124   "sw_if_index <id>] [l2]  [del]")                                      \
20125 _(proxy_arp_add_del,                                                    \
20126   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
20127 _(proxy_arp_intfc_enable_disable,                                       \
20128   "<intfc> | sw_if_index <id> enable | disable")                        \
20129 _(sw_interface_set_unnumbered,                                          \
20130   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
20131 _(ip_neighbor_add_del,                                                  \
20132   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
20133   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
20134 _(reset_vrf, "vrf <id> [ipv6]")                                         \
20135 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
20136 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
20137   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
20138   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
20139   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
20140 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
20141 _(reset_fib, "vrf <n> [ipv6]")                                          \
20142 _(dhcp_proxy_config,                                                    \
20143   "svr <v46-address> src <v46-address>\n"                               \
20144    "rx_vrf_id <nn> server_vrf_id <nn>  [del]")                          \
20145 _(dhcp_proxy_set_vss,                                                   \
20146   "tbl_id <n> fib_id <n> oui <n> [ipv6] [del]")                         \
20147 _(dhcp_proxy_dump, "ip6")                                               \
20148 _(dhcp_client_config,                                                   \
20149   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
20150 _(set_ip_flow_hash,                                                     \
20151   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
20152 _(sw_interface_ip6_enable_disable,                                      \
20153   "<intfc> | sw_if_index <id> enable | disable")                        \
20154 _(sw_interface_ip6_set_link_local_address,                              \
20155   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
20156 _(ip6nd_proxy_add_del,                                                  \
20157   "<intfc> | sw_if_index <id> <ip6-address>")                           \
20158 _(ip6nd_proxy_dump, "")                                                 \
20159 _(sw_interface_ip6nd_ra_prefix,                                         \
20160   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
20161   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
20162   "[nolink] [isno]")                                                    \
20163 _(sw_interface_ip6nd_ra_config,                                         \
20164   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
20165   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
20166   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
20167 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
20168 _(l2_patch_add_del,                                                     \
20169   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
20170   "enable | disable")                                                   \
20171 _(sr_localsid_add_del,                                                  \
20172   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
20173   "fib-table <num> (end.psp) sw_if_index <num>")                        \
20174 _(classify_add_del_table,                                               \
20175   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
20176   " [del] [del-chain] mask <mask-value>\n"                              \
20177   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
20178   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
20179 _(classify_add_del_session,                                             \
20180   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
20181   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
20182   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
20183   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
20184 _(classify_set_interface_ip_table,                                      \
20185   "<intfc> | sw_if_index <nn> table <nn>")                              \
20186 _(classify_set_interface_l2_tables,                                     \
20187   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
20188   "  [other-table <nn>]")                                               \
20189 _(get_node_index, "node <node-name")                                    \
20190 _(add_node_next, "node <node-name> next <next-node-name>")              \
20191 _(l2tpv3_create_tunnel,                                                 \
20192   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
20193   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
20194   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
20195 _(l2tpv3_set_tunnel_cookies,                                            \
20196   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
20197   "[new_remote_cookie <nn>]\n")                                         \
20198 _(l2tpv3_interface_enable_disable,                                      \
20199   "<intfc> | sw_if_index <nn> enable | disable")                        \
20200 _(l2tpv3_set_lookup_key,                                                \
20201   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
20202 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
20203 _(vxlan_add_del_tunnel,                                                 \
20204   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
20205   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
20206   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
20207 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
20208 _(gre_add_del_tunnel,                                                   \
20209   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [teb] [del]\n")    \
20210 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
20211 _(l2_fib_clear_table, "")                                               \
20212 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
20213 _(l2_interface_vlan_tag_rewrite,                                        \
20214   "<intfc> | sw_if_index <nn> \n"                                       \
20215   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
20216   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
20217 _(create_vhost_user_if,                                                 \
20218         "socket <filename> [server] [renumber <dev_instance>] "         \
20219         "[mac <mac_address>]")                                          \
20220 _(modify_vhost_user_if,                                                 \
20221         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
20222         "[server] [renumber <dev_instance>]")                           \
20223 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
20224 _(sw_interface_vhost_user_dump, "")                                     \
20225 _(show_version, "")                                                     \
20226 _(vxlan_gpe_add_del_tunnel,                                             \
20227   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
20228   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
20229   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
20230   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
20231 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
20232 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
20233 _(interface_name_renumber,                                              \
20234   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
20235 _(input_acl_set_interface,                                              \
20236   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
20237   "  [l2-table <nn>] [del]")                                            \
20238 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
20239 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
20240 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
20241 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
20242 _(ip_dump, "ipv4 | ipv6")                                               \
20243 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
20244 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
20245   "  spid_id <n> ")                                                     \
20246 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
20247   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
20248   "  integ_alg <alg> integ_key <hex>")                                  \
20249 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
20250   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
20251   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
20252   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
20253 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
20254 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
20255   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
20256   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
20257   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n")     \
20258 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
20259 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
20260   "(auth_data 0x<data> | auth_data <data>)")                            \
20261 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
20262   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
20263 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
20264   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
20265   "(local|remote)")                                                     \
20266 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
20267 _(ikev2_set_responder, "<profile_name> interface <interface> address <addr>") \
20268 _(ikev2_set_ike_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
20269 _(ikev2_set_esp_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
20270 _(ikev2_set_sa_lifetime, "<profile_name> <seconds> <jitter> <handover> <max bytes>") \
20271 _(ikev2_initiate_sa_init, "<profile_name>")                             \
20272 _(ikev2_initiate_del_ike_sa, "<ispi>")                                  \
20273 _(ikev2_initiate_del_child_sa, "<ispi>")                                \
20274 _(ikev2_initiate_rekey_child_sa, "<ispi>")                              \
20275 _(delete_loopback,"sw_if_index <nn>")                                   \
20276 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
20277 _(map_add_domain,                                                       \
20278   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
20279   "ip6-src <ip6addr> "                                                  \
20280   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
20281 _(map_del_domain, "index <n>")                                          \
20282 _(map_add_del_rule,                                                     \
20283   "index <n> psid <n> dst <ip6addr> [del]")                             \
20284 _(map_domain_dump, "")                                                  \
20285 _(map_rule_dump, "index <map-domain>")                                  \
20286 _(want_interface_events,  "enable|disable")                             \
20287 _(want_stats,"enable|disable")                                          \
20288 _(get_first_msg_id, "client <name>")                                    \
20289 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
20290 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
20291   "fib-id <nn> [ip4][ip6][default]")                                    \
20292 _(get_node_graph, " ")                                                  \
20293 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
20294 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
20295 _(ioam_disable, "")                                                     \
20296 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
20297                             " sw_if_index <sw_if_index> p <priority> "  \
20298                             "w <weight>] [del]")                        \
20299 _(one_add_del_locator, "locator-set <locator_name> "                    \
20300                         "iface <intf> | sw_if_index <sw_if_index> "     \
20301                         "p <priority> w <weight> [del]")                \
20302 _(one_add_del_local_eid,"vni <vni> eid "                                \
20303                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
20304                          "locator-set <locator_name> [del]"             \
20305                          "[key-id sha1|sha256 secret-key <secret-key>]")\
20306 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
20307 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
20308 _(one_enable_disable, "enable|disable")                                 \
20309 _(one_map_register_enable_disable, "enable|disable")                    \
20310 _(one_map_register_fallback_threshold, "<value>")                       \
20311 _(one_rloc_probe_enable_disable, "enable|disable")                      \
20312 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
20313                                "[seid <seid>] "                         \
20314                                "rloc <locator> p <prio> "               \
20315                                "w <weight> [rloc <loc> ... ] "          \
20316                                "action <action> [del-all]")             \
20317 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
20318                           "<local-eid>")                                \
20319 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
20320 _(one_use_petr, "ip-address> | disable")                                \
20321 _(one_map_request_mode, "src-dst|dst-only")                             \
20322 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
20323 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
20324 _(one_locator_set_dump, "[local | remote]")                             \
20325 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
20326 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
20327                        "[local] | [remote]")                            \
20328 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
20329 _(one_l2_arp_bd_get, "")                                                \
20330 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
20331 _(one_stats_enable_disable, "enable|disalbe")                           \
20332 _(show_one_stats_enable_disable, "")                                    \
20333 _(one_eid_table_vni_dump, "")                                           \
20334 _(one_eid_table_map_dump, "l2|l3")                                      \
20335 _(one_map_resolver_dump, "")                                            \
20336 _(one_map_server_dump, "")                                              \
20337 _(one_adjacencies_get, "vni <vni>")                                     \
20338 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
20339 _(show_one_rloc_probe_state, "")                                        \
20340 _(show_one_map_register_state, "")                                      \
20341 _(show_one_status, "")                                                  \
20342 _(one_stats_dump, "")                                                   \
20343 _(one_stats_flush, "")                                                  \
20344 _(one_get_map_request_itr_rlocs, "")                                    \
20345 _(one_map_register_set_ttl, "<ttl>")                                    \
20346 _(show_one_nsh_mapping, "")                                             \
20347 _(show_one_pitr, "")                                                    \
20348 _(show_one_use_petr, "")                                                \
20349 _(show_one_map_request_mode, "")                                        \
20350 _(show_one_map_register_ttl, "")                                        \
20351 _(show_one_map_register_fallback_threshold, "")                         \
20352 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
20353                             " sw_if_index <sw_if_index> p <priority> "  \
20354                             "w <weight>] [del]")                        \
20355 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
20356                         "iface <intf> | sw_if_index <sw_if_index> "     \
20357                         "p <priority> w <weight> [del]")                \
20358 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
20359                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
20360                          "locator-set <locator_name> [del]"             \
20361                          "[key-id sha1|sha256 secret-key <secret-key>]") \
20362 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
20363 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
20364 _(lisp_enable_disable, "enable|disable")                                \
20365 _(lisp_map_register_enable_disable, "enable|disable")                   \
20366 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
20367 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
20368                                "[seid <seid>] "                         \
20369                                "rloc <locator> p <prio> "               \
20370                                "w <weight> [rloc <loc> ... ] "          \
20371                                "action <action> [del-all]")             \
20372 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
20373                           "<local-eid>")                                \
20374 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
20375 _(lisp_use_petr, "<ip-address> | disable")                              \
20376 _(lisp_map_request_mode, "src-dst|dst-only")                            \
20377 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
20378 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
20379 _(lisp_locator_set_dump, "[local | remote]")                            \
20380 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
20381 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
20382                        "[local] | [remote]")                            \
20383 _(lisp_eid_table_vni_dump, "")                                          \
20384 _(lisp_eid_table_map_dump, "l2|l3")                                     \
20385 _(lisp_map_resolver_dump, "")                                           \
20386 _(lisp_map_server_dump, "")                                             \
20387 _(lisp_adjacencies_get, "vni <vni>")                                    \
20388 _(gpe_fwd_entry_vnis_get, "")                                           \
20389 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
20390 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
20391                                 "[table <table-id>]")                   \
20392 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
20393 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
20394 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
20395 _(gpe_get_encap_mode, "")                                               \
20396 _(lisp_gpe_add_del_iface, "up|down")                                    \
20397 _(lisp_gpe_enable_disable, "enable|disable")                            \
20398 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
20399   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
20400 _(show_lisp_rloc_probe_state, "")                                       \
20401 _(show_lisp_map_register_state, "")                                     \
20402 _(show_lisp_status, "")                                                 \
20403 _(lisp_get_map_request_itr_rlocs, "")                                   \
20404 _(show_lisp_pitr, "")                                                   \
20405 _(show_lisp_use_petr, "")                                               \
20406 _(show_lisp_map_request_mode, "")                                       \
20407 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
20408 _(af_packet_delete, "name <host interface name>")                       \
20409 _(policer_add_del, "name <policer name> <params> [del]")                \
20410 _(policer_dump, "[name <policer name>]")                                \
20411 _(policer_classify_set_interface,                                       \
20412   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
20413   "  [l2-table <nn>] [del]")                                            \
20414 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
20415 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
20416     "[master|slave]")                                                   \
20417 _(netmap_delete, "name <interface name>")                               \
20418 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
20419 _(mpls_fib_dump, "")                                                    \
20420 _(classify_table_ids, "")                                               \
20421 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
20422 _(classify_table_info, "table_id <nn>")                                 \
20423 _(classify_session_dump, "table_id <nn>")                               \
20424 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
20425     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
20426     "[template_interval <nn>] [udp_checksum]")                          \
20427 _(ipfix_exporter_dump, "")                                              \
20428 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
20429 _(ipfix_classify_stream_dump, "")                                       \
20430 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
20431 _(ipfix_classify_table_dump, "")                                        \
20432 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
20433 _(sw_interface_span_dump, "[l2]")                                           \
20434 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
20435 _(pg_create_interface, "if_id <nn>")                                    \
20436 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
20437 _(pg_enable_disable, "[stream <id>] disable")                           \
20438 _(ip_source_and_port_range_check_add_del,                               \
20439   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
20440 _(ip_source_and_port_range_check_interface_add_del,                     \
20441   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
20442   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
20443 _(ipsec_gre_add_del_tunnel,                                             \
20444   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
20445 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
20446 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
20447 _(l2_interface_pbb_tag_rewrite,                                         \
20448   "<intfc> | sw_if_index <nn> \n"                                       \
20449   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
20450   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
20451 _(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
20452 _(flow_classify_set_interface,                                          \
20453   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
20454 _(flow_classify_dump, "type [ip4|ip6]")                                 \
20455 _(ip_fib_dump, "")                                                      \
20456 _(ip_mfib_dump, "")                                                     \
20457 _(ip6_fib_dump, "")                                                     \
20458 _(ip6_mfib_dump, "")                                                    \
20459 _(feature_enable_disable, "arc_name <arc_name> "                        \
20460   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
20461 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
20462 "[disable]")                                                            \
20463 _(l2_xconnect_dump, "")                                                 \
20464 _(sw_interface_set_mtu, "<intfc> | sw_if_index <nn> mtu <nn>")        \
20465 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
20466 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
20467 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
20468 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
20469 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
20470 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>] [disable]")
20471
20472 /* List of command functions, CLI names map directly to functions */
20473 #define foreach_cli_function                                    \
20474 _(comment, "usage: comment <ignore-rest-of-line>")              \
20475 _(dump_interface_table, "usage: dump_interface_table")          \
20476 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
20477 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
20478 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
20479 _(dump_stats_table, "usage: dump_stats_table")                  \
20480 _(dump_macro_table, "usage: dump_macro_table ")                 \
20481 _(dump_node_table, "usage: dump_node_table")                    \
20482 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
20483 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
20484 _(echo, "usage: echo <message>")                                \
20485 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
20486 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
20487 _(help, "usage: help")                                          \
20488 _(q, "usage: quit")                                             \
20489 _(quit, "usage: quit")                                          \
20490 _(search_node_table, "usage: search_node_table <name>...")      \
20491 _(set, "usage: set <variable-name> <value>")                    \
20492 _(script, "usage: script <file-name>")                          \
20493 _(unset, "usage: unset <variable-name>")
20494 #define _(N,n)                                  \
20495     static void vl_api_##n##_t_handler_uni      \
20496     (vl_api_##n##_t * mp)                       \
20497     {                                           \
20498         vat_main_t * vam = &vat_main;           \
20499         if (vam->json_output) {                 \
20500             vl_api_##n##_t_handler_json(mp);    \
20501         } else {                                \
20502             vl_api_##n##_t_handler(mp);         \
20503         }                                       \
20504     }
20505 foreach_vpe_api_reply_msg;
20506 #if VPP_API_TEST_BUILTIN == 0
20507 foreach_standalone_reply_msg;
20508 #endif
20509 #undef _
20510
20511 void
20512 vat_api_hookup (vat_main_t * vam)
20513 {
20514 #define _(N,n)                                                  \
20515     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
20516                            vl_api_##n##_t_handler_uni,          \
20517                            vl_noop_handler,                     \
20518                            vl_api_##n##_t_endian,               \
20519                            vl_api_##n##_t_print,                \
20520                            sizeof(vl_api_##n##_t), 1);
20521   foreach_vpe_api_reply_msg;
20522 #if VPP_API_TEST_BUILTIN == 0
20523   foreach_standalone_reply_msg;
20524 #endif
20525 #undef _
20526
20527 #if (VPP_API_TEST_BUILTIN==0)
20528   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
20529
20530   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
20531
20532   vam->function_by_name = hash_create_string (0, sizeof (uword));
20533
20534   vam->help_by_name = hash_create_string (0, sizeof (uword));
20535 #endif
20536
20537   /* API messages we can send */
20538 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
20539   foreach_vpe_api_msg;
20540 #undef _
20541
20542   /* Help strings */
20543 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
20544   foreach_vpe_api_msg;
20545 #undef _
20546
20547   /* CLI functions */
20548 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
20549   foreach_cli_function;
20550 #undef _
20551
20552   /* Help strings */
20553 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
20554   foreach_cli_function;
20555 #undef _
20556 }
20557
20558 #if VPP_API_TEST_BUILTIN
20559 static clib_error_t *
20560 vat_api_hookup_shim (vlib_main_t * vm)
20561 {
20562   vat_api_hookup (&vat_main);
20563   return 0;
20564 }
20565
20566 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
20567 #endif
20568
20569 /*
20570  * fd.io coding-style-patch-verification: ON
20571  *
20572  * Local Variables:
20573  * eval: (c-set-style "gnu")
20574  * End:
20575  */