e6e4acd9ea673f79611dc68baaf3bc8432594eaf
[vpp.git] / src / vat / api_format.c
1 /*
2  *------------------------------------------------------------------
3  * api_format.c
4  *
5  * Copyright (c) 2014-2016 Cisco and/or its affiliates.
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at:
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *------------------------------------------------------------------
18  */
19
20 #include <vat/vat.h>
21 #include <vlibapi/api.h>
22 #include <vlibmemory/api.h>
23 #include <vlibsocket/api.h>
24 #include <vnet/ip/ip.h>
25 #include <vnet/l2/l2_input.h>
26 #include <vnet/l2tp/l2tp.h>
27 #include <vnet/vxlan/vxlan.h>
28 #include <vnet/gre/gre.h>
29 #include <vnet/vxlan-gpe/vxlan_gpe.h>
30 #include <vnet/lisp-gpe/lisp_gpe.h>
31
32 #include <vpp/api/vpe_msg_enum.h>
33 #include <vnet/l2/l2_classify.h>
34 #include <vnet/l2/l2_vtr.h>
35 #include <vnet/classify/input_acl.h>
36 #include <vnet/classify/policer_classify.h>
37 #include <vnet/classify/flow_classify.h>
38 #include <vnet/mpls/mpls.h>
39 #include <vnet/ipsec/ipsec.h>
40 #include <vnet/ipsec/ikev2.h>
41 #include <inttypes.h>
42 #include <vnet/map/map.h>
43 #include <vnet/cop/cop.h>
44 #include <vnet/ip/ip6_hop_by_hop.h>
45 #include <vnet/ip/ip_source_and_port_range_check.h>
46 #include <vnet/policer/xlate.h>
47 #include <vnet/span/span.h>
48 #include <vnet/policer/policer.h>
49 #include <vnet/policer/police.h>
50 #include <vnet/mfib/mfib_types.h>
51
52 #include "vat/json_format.h"
53
54 #include <inttypes.h>
55 #include <sys/stat.h>
56
57 #define vl_typedefs             /* define message structures */
58 #include <vpp/api/vpe_all_api_h.h>
59 #undef vl_typedefs
60
61 /* declare message handlers for each api */
62
63 #define vl_endianfun            /* define message structures */
64 #include <vpp/api/vpe_all_api_h.h>
65 #undef vl_endianfun
66
67 /* instantiate all the print functions we know about */
68 #define vl_print(handle, ...)
69 #define vl_printfun
70 #include <vpp/api/vpe_all_api_h.h>
71 #undef vl_printfun
72
73 #define __plugin_msg_base 0
74 #include <vlibapi/vat_helper_macros.h>
75
76 f64
77 vat_time_now (vat_main_t * vam)
78 {
79 #if VPP_API_TEST_BUILTIN
80   return vlib_time_now (vam->vlib_main);
81 #else
82   return clib_time_now (&vam->clib_time);
83 #endif
84 }
85
86 void
87 errmsg (char *fmt, ...)
88 {
89   vat_main_t *vam = &vat_main;
90   va_list va;
91   u8 *s;
92
93   va_start (va, fmt);
94   s = va_format (0, fmt, &va);
95   va_end (va);
96
97   vec_add1 (s, 0);
98
99 #if VPP_API_TEST_BUILTIN
100   vlib_cli_output (vam->vlib_main, (char *) s);
101 #else
102   {
103     if (vam->ifp != stdin)
104       fformat (vam->ofp, "%s(%d): \n", vam->current_file,
105                vam->input_line_number);
106     fformat (vam->ofp, (char *) s);
107     fflush (vam->ofp);
108   }
109 #endif
110
111   vec_free (s);
112 }
113
114 #if VPP_API_TEST_BUILTIN == 0
115 static uword
116 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
117 {
118   vat_main_t *vam = va_arg (*args, vat_main_t *);
119   u32 *result = va_arg (*args, u32 *);
120   u8 *if_name;
121   uword *p;
122
123   if (!unformat (input, "%s", &if_name))
124     return 0;
125
126   p = hash_get_mem (vam->sw_if_index_by_interface_name, if_name);
127   if (p == 0)
128     return 0;
129   *result = p[0];
130   return 1;
131 }
132
133 /* Parse an IP4 address %d.%d.%d.%d. */
134 uword
135 unformat_ip4_address (unformat_input_t * input, va_list * args)
136 {
137   u8 *result = va_arg (*args, u8 *);
138   unsigned a[4];
139
140   if (!unformat (input, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]))
141     return 0;
142
143   if (a[0] >= 256 || a[1] >= 256 || a[2] >= 256 || a[3] >= 256)
144     return 0;
145
146   result[0] = a[0];
147   result[1] = a[1];
148   result[2] = a[2];
149   result[3] = a[3];
150
151   return 1;
152 }
153
154 uword
155 unformat_ethernet_address (unformat_input_t * input, va_list * args)
156 {
157   u8 *result = va_arg (*args, u8 *);
158   u32 i, a[6];
159
160   if (!unformat (input, "%_%x:%x:%x:%x:%x:%x%_",
161                  &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]))
162     return 0;
163
164   /* Check range. */
165   for (i = 0; i < 6; i++)
166     if (a[i] >= (1 << 8))
167       return 0;
168
169   for (i = 0; i < 6; i++)
170     result[i] = a[i];
171
172   return 1;
173 }
174
175 /* Returns ethernet type as an int in host byte order. */
176 uword
177 unformat_ethernet_type_host_byte_order (unformat_input_t * input,
178                                         va_list * args)
179 {
180   u16 *result = va_arg (*args, u16 *);
181   int type;
182
183   /* Numeric type. */
184   if (unformat (input, "0x%x", &type) || unformat (input, "%d", &type))
185     {
186       if (type >= (1 << 16))
187         return 0;
188       *result = type;
189       return 1;
190     }
191   return 0;
192 }
193
194 /* Parse an IP6 address. */
195 uword
196 unformat_ip6_address (unformat_input_t * input, va_list * args)
197 {
198   ip6_address_t *result = va_arg (*args, ip6_address_t *);
199   u16 hex_quads[8];
200   uword hex_quad, n_hex_quads, hex_digit, n_hex_digits;
201   uword c, n_colon, double_colon_index;
202
203   n_hex_quads = hex_quad = n_hex_digits = n_colon = 0;
204   double_colon_index = ARRAY_LEN (hex_quads);
205   while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
206     {
207       hex_digit = 16;
208       if (c >= '0' && c <= '9')
209         hex_digit = c - '0';
210       else if (c >= 'a' && c <= 'f')
211         hex_digit = c + 10 - 'a';
212       else if (c >= 'A' && c <= 'F')
213         hex_digit = c + 10 - 'A';
214       else if (c == ':' && n_colon < 2)
215         n_colon++;
216       else
217         {
218           unformat_put_input (input);
219           break;
220         }
221
222       /* Too many hex quads. */
223       if (n_hex_quads >= ARRAY_LEN (hex_quads))
224         return 0;
225
226       if (hex_digit < 16)
227         {
228           hex_quad = (hex_quad << 4) | hex_digit;
229
230           /* Hex quad must fit in 16 bits. */
231           if (n_hex_digits >= 4)
232             return 0;
233
234           n_colon = 0;
235           n_hex_digits++;
236         }
237
238       /* Save position of :: */
239       if (n_colon == 2)
240         {
241           /* More than one :: ? */
242           if (double_colon_index < ARRAY_LEN (hex_quads))
243             return 0;
244           double_colon_index = n_hex_quads;
245         }
246
247       if (n_colon > 0 && n_hex_digits > 0)
248         {
249           hex_quads[n_hex_quads++] = hex_quad;
250           hex_quad = 0;
251           n_hex_digits = 0;
252         }
253     }
254
255   if (n_hex_digits > 0)
256     hex_quads[n_hex_quads++] = hex_quad;
257
258   {
259     word i;
260
261     /* Expand :: to appropriate number of zero hex quads. */
262     if (double_colon_index < ARRAY_LEN (hex_quads))
263       {
264         word n_zero = ARRAY_LEN (hex_quads) - n_hex_quads;
265
266         for (i = n_hex_quads - 1; i >= (signed) double_colon_index; i--)
267           hex_quads[n_zero + i] = hex_quads[i];
268
269         for (i = 0; i < n_zero; i++)
270           hex_quads[double_colon_index + i] = 0;
271
272         n_hex_quads = ARRAY_LEN (hex_quads);
273       }
274
275     /* Too few hex quads given. */
276     if (n_hex_quads < ARRAY_LEN (hex_quads))
277       return 0;
278
279     for (i = 0; i < ARRAY_LEN (hex_quads); i++)
280       result->as_u16[i] = clib_host_to_net_u16 (hex_quads[i]);
281
282     return 1;
283   }
284 }
285
286 uword
287 unformat_ipsec_policy_action (unformat_input_t * input, va_list * args)
288 {
289   u32 *r = va_arg (*args, u32 *);
290
291   if (0);
292 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f;
293   foreach_ipsec_policy_action
294 #undef _
295     else
296     return 0;
297   return 1;
298 }
299
300 uword
301 unformat_ipsec_crypto_alg (unformat_input_t * input, va_list * args)
302 {
303   u32 *r = va_arg (*args, u32 *);
304
305   if (0);
306 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_CRYPTO_ALG_##f;
307   foreach_ipsec_crypto_alg
308 #undef _
309     else
310     return 0;
311   return 1;
312 }
313
314 u8 *
315 format_ipsec_crypto_alg (u8 * s, va_list * args)
316 {
317   u32 i = va_arg (*args, u32);
318   u8 *t = 0;
319
320   switch (i)
321     {
322 #define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break;
323       foreach_ipsec_crypto_alg
324 #undef _
325     default:
326       return format (s, "unknown");
327     }
328   return format (s, "%s", t);
329 }
330
331 uword
332 unformat_ipsec_integ_alg (unformat_input_t * input, va_list * args)
333 {
334   u32 *r = va_arg (*args, u32 *);
335
336   if (0);
337 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_INTEG_ALG_##f;
338   foreach_ipsec_integ_alg
339 #undef _
340     else
341     return 0;
342   return 1;
343 }
344
345 u8 *
346 format_ipsec_integ_alg (u8 * s, va_list * args)
347 {
348   u32 i = va_arg (*args, u32);
349   u8 *t = 0;
350
351   switch (i)
352     {
353 #define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
354       foreach_ipsec_integ_alg
355 #undef _
356     default:
357       return format (s, "unknown");
358     }
359   return format (s, "%s", t);
360 }
361
362 uword
363 unformat_ikev2_auth_method (unformat_input_t * input, va_list * args)
364 {
365   u32 *r = va_arg (*args, u32 *);
366
367   if (0);
368 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_AUTH_METHOD_##f;
369   foreach_ikev2_auth_method
370 #undef _
371     else
372     return 0;
373   return 1;
374 }
375
376 uword
377 unformat_ikev2_id_type (unformat_input_t * input, va_list * args)
378 {
379   u32 *r = va_arg (*args, u32 *);
380
381   if (0);
382 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_ID_TYPE_##f;
383   foreach_ikev2_id_type
384 #undef _
385     else
386     return 0;
387   return 1;
388 }
389 #else /* VPP_API_TEST_BUILTIN == 1 */
390 static uword
391 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
392 {
393   vat_main_t *vam __attribute__ ((unused)) = va_arg (*args, vat_main_t *);
394   vnet_main_t *vnm = vnet_get_main ();
395   u32 *result = va_arg (*args, u32 *);
396   u32 sw_if_index;
397
398   if (!unformat (input, "%U", unformat_vnet_sw_interface, vnm, &sw_if_index))
399     return 0;
400
401   *result = sw_if_index;
402   return 1;
403 }
404 #endif /* VPP_API_TEST_BUILTIN */
405
406 static uword
407 unformat_policer_rate_type (unformat_input_t * input, va_list * args)
408 {
409   u8 *r = va_arg (*args, u8 *);
410
411   if (unformat (input, "kbps"))
412     *r = SSE2_QOS_RATE_KBPS;
413   else if (unformat (input, "pps"))
414     *r = SSE2_QOS_RATE_PPS;
415   else
416     return 0;
417   return 1;
418 }
419
420 static uword
421 unformat_policer_round_type (unformat_input_t * input, va_list * args)
422 {
423   u8 *r = va_arg (*args, u8 *);
424
425   if (unformat (input, "closest"))
426     *r = SSE2_QOS_ROUND_TO_CLOSEST;
427   else if (unformat (input, "up"))
428     *r = SSE2_QOS_ROUND_TO_UP;
429   else if (unformat (input, "down"))
430     *r = SSE2_QOS_ROUND_TO_DOWN;
431   else
432     return 0;
433   return 1;
434 }
435
436 static uword
437 unformat_policer_type (unformat_input_t * input, va_list * args)
438 {
439   u8 *r = va_arg (*args, u8 *);
440
441   if (unformat (input, "1r2c"))
442     *r = SSE2_QOS_POLICER_TYPE_1R2C;
443   else if (unformat (input, "1r3c"))
444     *r = SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697;
445   else if (unformat (input, "2r3c-2698"))
446     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698;
447   else if (unformat (input, "2r3c-4115"))
448     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115;
449   else if (unformat (input, "2r3c-mef5cf1"))
450     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
451   else
452     return 0;
453   return 1;
454 }
455
456 static uword
457 unformat_dscp (unformat_input_t * input, va_list * va)
458 {
459   u8 *r = va_arg (*va, u8 *);
460
461   if (0);
462 #define _(v,f,str) else if (unformat (input, str)) *r = VNET_DSCP_##f;
463   foreach_vnet_dscp
464 #undef _
465     else
466     return 0;
467   return 1;
468 }
469
470 static uword
471 unformat_policer_action_type (unformat_input_t * input, va_list * va)
472 {
473   sse2_qos_pol_action_params_st *a
474     = va_arg (*va, sse2_qos_pol_action_params_st *);
475
476   if (unformat (input, "drop"))
477     a->action_type = SSE2_QOS_ACTION_DROP;
478   else if (unformat (input, "transmit"))
479     a->action_type = SSE2_QOS_ACTION_TRANSMIT;
480   else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp))
481     a->action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
482   else
483     return 0;
484   return 1;
485 }
486
487 static uword
488 unformat_policer_classify_table_type (unformat_input_t * input, va_list * va)
489 {
490   u32 *r = va_arg (*va, u32 *);
491   u32 tid;
492
493   if (unformat (input, "ip4"))
494     tid = POLICER_CLASSIFY_TABLE_IP4;
495   else if (unformat (input, "ip6"))
496     tid = POLICER_CLASSIFY_TABLE_IP6;
497   else if (unformat (input, "l2"))
498     tid = POLICER_CLASSIFY_TABLE_L2;
499   else
500     return 0;
501
502   *r = tid;
503   return 1;
504 }
505
506 static uword
507 unformat_flow_classify_table_type (unformat_input_t * input, va_list * va)
508 {
509   u32 *r = va_arg (*va, u32 *);
510   u32 tid;
511
512   if (unformat (input, "ip4"))
513     tid = FLOW_CLASSIFY_TABLE_IP4;
514   else if (unformat (input, "ip6"))
515     tid = FLOW_CLASSIFY_TABLE_IP6;
516   else
517     return 0;
518
519   *r = tid;
520   return 1;
521 }
522
523 static const char *mfib_flag_names[] = MFIB_ENTRY_NAMES_SHORT;
524 static const char *mfib_flag_long_names[] = MFIB_ENTRY_NAMES_LONG;
525 static const char *mfib_itf_flag_long_names[] = MFIB_ITF_NAMES_LONG;
526 static const char *mfib_itf_flag_names[] = MFIB_ITF_NAMES_SHORT;
527
528 #if (VPP_API_TEST_BUILTIN==0)
529 uword
530 unformat_mfib_itf_flags (unformat_input_t * input, va_list * args)
531 {
532   mfib_itf_flags_t old, *iflags = va_arg (*args, mfib_itf_flags_t *);
533   mfib_itf_attribute_t attr;
534
535   old = *iflags;
536   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
537   {
538     if (unformat (input, mfib_itf_flag_long_names[attr]))
539       *iflags |= (1 << attr);
540   }
541   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
542   {
543     if (unformat (input, mfib_itf_flag_names[attr]))
544       *iflags |= (1 << attr);
545   }
546
547   return (old == *iflags ? 0 : 1);
548 }
549
550 uword
551 unformat_mfib_entry_flags (unformat_input_t * input, va_list * args)
552 {
553   mfib_entry_flags_t old, *eflags = va_arg (*args, mfib_entry_flags_t *);
554   mfib_entry_attribute_t attr;
555
556   old = *eflags;
557   FOR_EACH_MFIB_ATTRIBUTE (attr)
558   {
559     if (unformat (input, mfib_flag_long_names[attr]))
560       *eflags |= (1 << attr);
561   }
562   FOR_EACH_MFIB_ATTRIBUTE (attr)
563   {
564     if (unformat (input, mfib_flag_names[attr]))
565       *eflags |= (1 << attr);
566   }
567
568   return (old == *eflags ? 0 : 1);
569 }
570
571 u8 *
572 format_ip4_address (u8 * s, va_list * args)
573 {
574   u8 *a = va_arg (*args, u8 *);
575   return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
576 }
577
578 u8 *
579 format_ip6_address (u8 * s, va_list * args)
580 {
581   ip6_address_t *a = va_arg (*args, ip6_address_t *);
582   u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
583
584   i_max_n_zero = ARRAY_LEN (a->as_u16);
585   max_n_zeros = 0;
586   i_first_zero = i_max_n_zero;
587   n_zeros = 0;
588   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
589     {
590       u32 is_zero = a->as_u16[i] == 0;
591       if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
592         {
593           i_first_zero = i;
594           n_zeros = 0;
595         }
596       n_zeros += is_zero;
597       if ((!is_zero && n_zeros > max_n_zeros)
598           || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
599         {
600           i_max_n_zero = i_first_zero;
601           max_n_zeros = n_zeros;
602           i_first_zero = ARRAY_LEN (a->as_u16);
603           n_zeros = 0;
604         }
605     }
606
607   last_double_colon = 0;
608   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
609     {
610       if (i == i_max_n_zero && max_n_zeros > 1)
611         {
612           s = format (s, "::");
613           i += max_n_zeros - 1;
614           last_double_colon = 1;
615         }
616       else
617         {
618           s = format (s, "%s%x",
619                       (last_double_colon || i == 0) ? "" : ":",
620                       clib_net_to_host_u16 (a->as_u16[i]));
621           last_double_colon = 0;
622         }
623     }
624
625   return s;
626 }
627
628 /* Format an IP46 address. */
629 u8 *
630 format_ip46_address (u8 * s, va_list * args)
631 {
632   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
633   ip46_type_t type = va_arg (*args, ip46_type_t);
634   int is_ip4 = 1;
635
636   switch (type)
637     {
638     case IP46_TYPE_ANY:
639       is_ip4 = ip46_address_is_ip4 (ip46);
640       break;
641     case IP46_TYPE_IP4:
642       is_ip4 = 1;
643       break;
644     case IP46_TYPE_IP6:
645       is_ip4 = 0;
646       break;
647     }
648
649   return is_ip4 ?
650     format (s, "%U", format_ip4_address, &ip46->ip4) :
651     format (s, "%U", format_ip6_address, &ip46->ip6);
652 }
653
654 u8 *
655 format_ethernet_address (u8 * s, va_list * args)
656 {
657   u8 *a = va_arg (*args, u8 *);
658
659   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
660                  a[0], a[1], a[2], a[3], a[4], a[5]);
661 }
662 #endif
663
664 static void
665 increment_v4_address (ip4_address_t * a)
666 {
667   u32 v;
668
669   v = ntohl (a->as_u32) + 1;
670   a->as_u32 = ntohl (v);
671 }
672
673 static void
674 increment_v6_address (ip6_address_t * a)
675 {
676   u64 v0, v1;
677
678   v0 = clib_net_to_host_u64 (a->as_u64[0]);
679   v1 = clib_net_to_host_u64 (a->as_u64[1]);
680
681   v1 += 1;
682   if (v1 == 0)
683     v0 += 1;
684   a->as_u64[0] = clib_net_to_host_u64 (v0);
685   a->as_u64[1] = clib_net_to_host_u64 (v1);
686 }
687
688 static void
689 increment_mac_address (u64 * mac)
690 {
691   u64 tmp = *mac;
692
693   tmp = clib_net_to_host_u64 (tmp);
694   tmp += 1 << 16;               /* skip unused (least significant) octets */
695   tmp = clib_host_to_net_u64 (tmp);
696   *mac = tmp;
697 }
698
699 static void vl_api_create_loopback_reply_t_handler
700   (vl_api_create_loopback_reply_t * mp)
701 {
702   vat_main_t *vam = &vat_main;
703   i32 retval = ntohl (mp->retval);
704
705   vam->retval = retval;
706   vam->regenerate_interface_table = 1;
707   vam->sw_if_index = ntohl (mp->sw_if_index);
708   vam->result_ready = 1;
709 }
710
711 static void vl_api_create_loopback_reply_t_handler_json
712   (vl_api_create_loopback_reply_t * mp)
713 {
714   vat_main_t *vam = &vat_main;
715   vat_json_node_t node;
716
717   vat_json_init_object (&node);
718   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
719   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
720
721   vat_json_print (vam->ofp, &node);
722   vat_json_free (&node);
723   vam->retval = ntohl (mp->retval);
724   vam->result_ready = 1;
725 }
726
727 static void vl_api_create_loopback_instance_reply_t_handler
728   (vl_api_create_loopback_instance_reply_t * mp)
729 {
730   vat_main_t *vam = &vat_main;
731   i32 retval = ntohl (mp->retval);
732
733   vam->retval = retval;
734   vam->regenerate_interface_table = 1;
735   vam->sw_if_index = ntohl (mp->sw_if_index);
736   vam->result_ready = 1;
737 }
738
739 static void vl_api_create_loopback_instance_reply_t_handler_json
740   (vl_api_create_loopback_instance_reply_t * mp)
741 {
742   vat_main_t *vam = &vat_main;
743   vat_json_node_t node;
744
745   vat_json_init_object (&node);
746   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
747   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
748
749   vat_json_print (vam->ofp, &node);
750   vat_json_free (&node);
751   vam->retval = ntohl (mp->retval);
752   vam->result_ready = 1;
753 }
754
755 static void vl_api_af_packet_create_reply_t_handler
756   (vl_api_af_packet_create_reply_t * mp)
757 {
758   vat_main_t *vam = &vat_main;
759   i32 retval = ntohl (mp->retval);
760
761   vam->retval = retval;
762   vam->regenerate_interface_table = 1;
763   vam->sw_if_index = ntohl (mp->sw_if_index);
764   vam->result_ready = 1;
765 }
766
767 static void vl_api_af_packet_create_reply_t_handler_json
768   (vl_api_af_packet_create_reply_t * mp)
769 {
770   vat_main_t *vam = &vat_main;
771   vat_json_node_t node;
772
773   vat_json_init_object (&node);
774   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
775   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
776
777   vat_json_print (vam->ofp, &node);
778   vat_json_free (&node);
779
780   vam->retval = ntohl (mp->retval);
781   vam->result_ready = 1;
782 }
783
784 static void vl_api_create_vlan_subif_reply_t_handler
785   (vl_api_create_vlan_subif_reply_t * mp)
786 {
787   vat_main_t *vam = &vat_main;
788   i32 retval = ntohl (mp->retval);
789
790   vam->retval = retval;
791   vam->regenerate_interface_table = 1;
792   vam->sw_if_index = ntohl (mp->sw_if_index);
793   vam->result_ready = 1;
794 }
795
796 static void vl_api_create_vlan_subif_reply_t_handler_json
797   (vl_api_create_vlan_subif_reply_t * mp)
798 {
799   vat_main_t *vam = &vat_main;
800   vat_json_node_t node;
801
802   vat_json_init_object (&node);
803   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
804   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
805
806   vat_json_print (vam->ofp, &node);
807   vat_json_free (&node);
808
809   vam->retval = ntohl (mp->retval);
810   vam->result_ready = 1;
811 }
812
813 static void vl_api_create_subif_reply_t_handler
814   (vl_api_create_subif_reply_t * mp)
815 {
816   vat_main_t *vam = &vat_main;
817   i32 retval = ntohl (mp->retval);
818
819   vam->retval = retval;
820   vam->regenerate_interface_table = 1;
821   vam->sw_if_index = ntohl (mp->sw_if_index);
822   vam->result_ready = 1;
823 }
824
825 static void vl_api_create_subif_reply_t_handler_json
826   (vl_api_create_subif_reply_t * mp)
827 {
828   vat_main_t *vam = &vat_main;
829   vat_json_node_t node;
830
831   vat_json_init_object (&node);
832   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
833   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
834
835   vat_json_print (vam->ofp, &node);
836   vat_json_free (&node);
837
838   vam->retval = ntohl (mp->retval);
839   vam->result_ready = 1;
840 }
841
842 static void vl_api_interface_name_renumber_reply_t_handler
843   (vl_api_interface_name_renumber_reply_t * mp)
844 {
845   vat_main_t *vam = &vat_main;
846   i32 retval = ntohl (mp->retval);
847
848   vam->retval = retval;
849   vam->regenerate_interface_table = 1;
850   vam->result_ready = 1;
851 }
852
853 static void vl_api_interface_name_renumber_reply_t_handler_json
854   (vl_api_interface_name_renumber_reply_t * mp)
855 {
856   vat_main_t *vam = &vat_main;
857   vat_json_node_t node;
858
859   vat_json_init_object (&node);
860   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
861
862   vat_json_print (vam->ofp, &node);
863   vat_json_free (&node);
864
865   vam->retval = ntohl (mp->retval);
866   vam->result_ready = 1;
867 }
868
869 /*
870  * Special-case: build the interface table, maintain
871  * the next loopback sw_if_index vbl.
872  */
873 static void vl_api_sw_interface_details_t_handler
874   (vl_api_sw_interface_details_t * mp)
875 {
876   vat_main_t *vam = &vat_main;
877   u8 *s = format (0, "%s%c", mp->interface_name, 0);
878
879   hash_set_mem (vam->sw_if_index_by_interface_name, s,
880                 ntohl (mp->sw_if_index));
881
882   /* In sub interface case, fill the sub interface table entry */
883   if (mp->sw_if_index != mp->sup_sw_if_index)
884     {
885       sw_interface_subif_t *sub = NULL;
886
887       vec_add2 (vam->sw_if_subif_table, sub, 1);
888
889       vec_validate (sub->interface_name, strlen ((char *) s) + 1);
890       strncpy ((char *) sub->interface_name, (char *) s,
891                vec_len (sub->interface_name));
892       sub->sw_if_index = ntohl (mp->sw_if_index);
893       sub->sub_id = ntohl (mp->sub_id);
894
895       sub->sub_dot1ad = mp->sub_dot1ad;
896       sub->sub_number_of_tags = mp->sub_number_of_tags;
897       sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
898       sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
899       sub->sub_exact_match = mp->sub_exact_match;
900       sub->sub_default = mp->sub_default;
901       sub->sub_outer_vlan_id_any = mp->sub_outer_vlan_id_any;
902       sub->sub_inner_vlan_id_any = mp->sub_inner_vlan_id_any;
903
904       /* vlan tag rewrite */
905       sub->vtr_op = ntohl (mp->vtr_op);
906       sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
907       sub->vtr_tag1 = ntohl (mp->vtr_tag1);
908       sub->vtr_tag2 = ntohl (mp->vtr_tag2);
909     }
910 }
911
912 static void vl_api_sw_interface_details_t_handler_json
913   (vl_api_sw_interface_details_t * mp)
914 {
915   vat_main_t *vam = &vat_main;
916   vat_json_node_t *node = NULL;
917
918   if (VAT_JSON_ARRAY != vam->json_tree.type)
919     {
920       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
921       vat_json_init_array (&vam->json_tree);
922     }
923   node = vat_json_array_add (&vam->json_tree);
924
925   vat_json_init_object (node);
926   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
927   vat_json_object_add_uint (node, "sup_sw_if_index",
928                             ntohl (mp->sup_sw_if_index));
929   vat_json_object_add_uint (node, "l2_address_length",
930                             ntohl (mp->l2_address_length));
931   vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
932                              sizeof (mp->l2_address));
933   vat_json_object_add_string_copy (node, "interface_name",
934                                    mp->interface_name);
935   vat_json_object_add_uint (node, "admin_up_down", mp->admin_up_down);
936   vat_json_object_add_uint (node, "link_up_down", mp->link_up_down);
937   vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
938   vat_json_object_add_uint (node, "link_speed", mp->link_speed);
939   vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
940   vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
941   vat_json_object_add_uint (node, "sub_dot1ad", mp->sub_dot1ad);
942   vat_json_object_add_uint (node, "sub_number_of_tags",
943                             mp->sub_number_of_tags);
944   vat_json_object_add_uint (node, "sub_outer_vlan_id",
945                             ntohs (mp->sub_outer_vlan_id));
946   vat_json_object_add_uint (node, "sub_inner_vlan_id",
947                             ntohs (mp->sub_inner_vlan_id));
948   vat_json_object_add_uint (node, "sub_exact_match", mp->sub_exact_match);
949   vat_json_object_add_uint (node, "sub_default", mp->sub_default);
950   vat_json_object_add_uint (node, "sub_outer_vlan_id_any",
951                             mp->sub_outer_vlan_id_any);
952   vat_json_object_add_uint (node, "sub_inner_vlan_id_any",
953                             mp->sub_inner_vlan_id_any);
954   vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
955   vat_json_object_add_uint (node, "vtr_push_dot1q",
956                             ntohl (mp->vtr_push_dot1q));
957   vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
958   vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
959   if (mp->sub_dot1ah)
960     {
961       vat_json_object_add_string_copy (node, "pbb_vtr_dmac",
962                                        format (0, "%U",
963                                                format_ethernet_address,
964                                                &mp->b_dmac));
965       vat_json_object_add_string_copy (node, "pbb_vtr_smac",
966                                        format (0, "%U",
967                                                format_ethernet_address,
968                                                &mp->b_smac));
969       vat_json_object_add_uint (node, "pbb_vtr_b_vlanid", mp->b_vlanid);
970       vat_json_object_add_uint (node, "pbb_vtr_i_sid", mp->i_sid);
971     }
972 }
973
974 #if VPP_API_TEST_BUILTIN == 0
975 static void vl_api_sw_interface_set_flags_t_handler
976   (vl_api_sw_interface_set_flags_t * mp)
977 {
978   vat_main_t *vam = &vat_main;
979   if (vam->interface_event_display)
980     errmsg ("interface flags: sw_if_index %d %s %s",
981             ntohl (mp->sw_if_index),
982             mp->admin_up_down ? "admin-up" : "admin-down",
983             mp->link_up_down ? "link-up" : "link-down");
984 }
985 #endif
986
987 static void vl_api_sw_interface_set_flags_t_handler_json
988   (vl_api_sw_interface_set_flags_t * mp)
989 {
990   /* JSON output not supported */
991 }
992
993 static void
994 vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
995 {
996   vat_main_t *vam = &vat_main;
997   i32 retval = ntohl (mp->retval);
998
999   vam->retval = retval;
1000   vam->shmem_result = (u8 *) mp->reply_in_shmem;
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 = (u8 *) (mp->reply_in_shmem);
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: address %U new mac %U sw_if_index %d",
1259           mp->mac_ip ? "mac/ip binding" : "address resolution",
1260           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: address %U new mac %U sw_if_index %d",
1275           mp->mac_ip ? "mac/ip binding" : "address resolution",
1276           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 /*
1287  * Special-case: build the bridge domain table, maintain
1288  * the next bd id vbl.
1289  */
1290 static void vl_api_bridge_domain_details_t_handler
1291   (vl_api_bridge_domain_details_t * mp)
1292 {
1293   vat_main_t *vam = &vat_main;
1294   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1295
1296   print (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-3s",
1297          " ID", "LRN", "FWD", "FLD", "BVI", "#IF");
1298
1299   print (vam->ofp, "%3d %3d %3d %3d %3d %3d",
1300          ntohl (mp->bd_id), mp->learn, mp->forward,
1301          mp->flood, ntohl (mp->bvi_sw_if_index), n_sw_ifs);
1302
1303   if (n_sw_ifs)
1304     print (vam->ofp, "\n\n%s %s  %s", "sw_if_index", "SHG", "Interface Name");
1305 }
1306
1307 static void vl_api_bridge_domain_details_t_handler_json
1308   (vl_api_bridge_domain_details_t * mp)
1309 {
1310   vat_main_t *vam = &vat_main;
1311   vat_json_node_t *node, *array = NULL;
1312
1313   if (VAT_JSON_ARRAY != vam->json_tree.type)
1314     {
1315       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1316       vat_json_init_array (&vam->json_tree);
1317     }
1318   node = vat_json_array_add (&vam->json_tree);
1319
1320   vat_json_init_object (node);
1321   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1322   vat_json_object_add_uint (node, "flood", mp->flood);
1323   vat_json_object_add_uint (node, "forward", mp->forward);
1324   vat_json_object_add_uint (node, "learn", mp->learn);
1325   vat_json_object_add_uint (node, "bvi_sw_if_index",
1326                             ntohl (mp->bvi_sw_if_index));
1327   vat_json_object_add_uint (node, "n_sw_ifs", ntohl (mp->n_sw_ifs));
1328   array = vat_json_object_add (node, "sw_if");
1329   vat_json_init_array (array);
1330 }
1331
1332 /*
1333  * Special-case: build the bridge domain sw if table.
1334  */
1335 static void vl_api_bridge_domain_sw_if_details_t_handler
1336   (vl_api_bridge_domain_sw_if_details_t * mp)
1337 {
1338   vat_main_t *vam = &vat_main;
1339   hash_pair_t *p;
1340   u8 *sw_if_name = 0;
1341   u32 sw_if_index;
1342
1343   sw_if_index = ntohl (mp->sw_if_index);
1344   /* *INDENT-OFF* */
1345   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1346   ({
1347     if ((u32) p->value[0] == sw_if_index)
1348       {
1349         sw_if_name = (u8 *)(p->key);
1350         break;
1351       }
1352   }));
1353   /* *INDENT-ON* */
1354
1355   print (vam->ofp, "%7d     %3d  %s", sw_if_index,
1356          mp->shg, sw_if_name ? (char *) sw_if_name :
1357          "sw_if_index not found!");
1358 }
1359
1360 static void vl_api_bridge_domain_sw_if_details_t_handler_json
1361   (vl_api_bridge_domain_sw_if_details_t * mp)
1362 {
1363   vat_main_t *vam = &vat_main;
1364   vat_json_node_t *node = NULL;
1365   uword last_index = 0;
1366
1367   ASSERT (VAT_JSON_ARRAY == vam->json_tree.type);
1368   ASSERT (vec_len (vam->json_tree.array) >= 1);
1369   last_index = vec_len (vam->json_tree.array) - 1;
1370   node = &vam->json_tree.array[last_index];
1371   node = vat_json_object_get_element (node, "sw_if");
1372   ASSERT (NULL != node);
1373   node = vat_json_array_add (node);
1374
1375   vat_json_init_object (node);
1376   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1377   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
1378   vat_json_object_add_uint (node, "shg", mp->shg);
1379 }
1380
1381 static void vl_api_control_ping_reply_t_handler
1382   (vl_api_control_ping_reply_t * mp)
1383 {
1384   vat_main_t *vam = &vat_main;
1385   i32 retval = ntohl (mp->retval);
1386   if (vam->async_mode)
1387     {
1388       vam->async_errors += (retval < 0);
1389     }
1390   else
1391     {
1392       vam->retval = retval;
1393       vam->result_ready = 1;
1394     }
1395 }
1396
1397 static void vl_api_control_ping_reply_t_handler_json
1398   (vl_api_control_ping_reply_t * mp)
1399 {
1400   vat_main_t *vam = &vat_main;
1401   i32 retval = ntohl (mp->retval);
1402
1403   if (VAT_JSON_NONE != vam->json_tree.type)
1404     {
1405       vat_json_print (vam->ofp, &vam->json_tree);
1406       vat_json_free (&vam->json_tree);
1407       vam->json_tree.type = VAT_JSON_NONE;
1408     }
1409   else
1410     {
1411       /* just print [] */
1412       vat_json_init_array (&vam->json_tree);
1413       vat_json_print (vam->ofp, &vam->json_tree);
1414       vam->json_tree.type = VAT_JSON_NONE;
1415     }
1416
1417   vam->retval = retval;
1418   vam->result_ready = 1;
1419 }
1420
1421 static void
1422 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1423 {
1424   vat_main_t *vam = &vat_main;
1425   i32 retval = ntohl (mp->retval);
1426   if (vam->async_mode)
1427     {
1428       vam->async_errors += (retval < 0);
1429     }
1430   else
1431     {
1432       vam->retval = retval;
1433       vam->result_ready = 1;
1434     }
1435 }
1436
1437 static void vl_api_l2_flags_reply_t_handler_json
1438   (vl_api_l2_flags_reply_t * mp)
1439 {
1440   vat_main_t *vam = &vat_main;
1441   vat_json_node_t node;
1442
1443   vat_json_init_object (&node);
1444   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1445   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1446                             ntohl (mp->resulting_feature_bitmap));
1447
1448   vat_json_print (vam->ofp, &node);
1449   vat_json_free (&node);
1450
1451   vam->retval = ntohl (mp->retval);
1452   vam->result_ready = 1;
1453 }
1454
1455 static void vl_api_bridge_flags_reply_t_handler
1456   (vl_api_bridge_flags_reply_t * mp)
1457 {
1458   vat_main_t *vam = &vat_main;
1459   i32 retval = ntohl (mp->retval);
1460   if (vam->async_mode)
1461     {
1462       vam->async_errors += (retval < 0);
1463     }
1464   else
1465     {
1466       vam->retval = retval;
1467       vam->result_ready = 1;
1468     }
1469 }
1470
1471 static void vl_api_bridge_flags_reply_t_handler_json
1472   (vl_api_bridge_flags_reply_t * mp)
1473 {
1474   vat_main_t *vam = &vat_main;
1475   vat_json_node_t node;
1476
1477   vat_json_init_object (&node);
1478   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1479   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1480                             ntohl (mp->resulting_feature_bitmap));
1481
1482   vat_json_print (vam->ofp, &node);
1483   vat_json_free (&node);
1484
1485   vam->retval = ntohl (mp->retval);
1486   vam->result_ready = 1;
1487 }
1488
1489 static void vl_api_tap_connect_reply_t_handler
1490   (vl_api_tap_connect_reply_t * mp)
1491 {
1492   vat_main_t *vam = &vat_main;
1493   i32 retval = ntohl (mp->retval);
1494   if (vam->async_mode)
1495     {
1496       vam->async_errors += (retval < 0);
1497     }
1498   else
1499     {
1500       vam->retval = retval;
1501       vam->sw_if_index = ntohl (mp->sw_if_index);
1502       vam->result_ready = 1;
1503     }
1504
1505 }
1506
1507 static void vl_api_tap_connect_reply_t_handler_json
1508   (vl_api_tap_connect_reply_t * mp)
1509 {
1510   vat_main_t *vam = &vat_main;
1511   vat_json_node_t node;
1512
1513   vat_json_init_object (&node);
1514   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1515   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1516
1517   vat_json_print (vam->ofp, &node);
1518   vat_json_free (&node);
1519
1520   vam->retval = ntohl (mp->retval);
1521   vam->result_ready = 1;
1522
1523 }
1524
1525 static void
1526 vl_api_tap_modify_reply_t_handler (vl_api_tap_modify_reply_t * mp)
1527 {
1528   vat_main_t *vam = &vat_main;
1529   i32 retval = ntohl (mp->retval);
1530   if (vam->async_mode)
1531     {
1532       vam->async_errors += (retval < 0);
1533     }
1534   else
1535     {
1536       vam->retval = retval;
1537       vam->sw_if_index = ntohl (mp->sw_if_index);
1538       vam->result_ready = 1;
1539     }
1540 }
1541
1542 static void vl_api_tap_modify_reply_t_handler_json
1543   (vl_api_tap_modify_reply_t * mp)
1544 {
1545   vat_main_t *vam = &vat_main;
1546   vat_json_node_t node;
1547
1548   vat_json_init_object (&node);
1549   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1550   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1551
1552   vat_json_print (vam->ofp, &node);
1553   vat_json_free (&node);
1554
1555   vam->retval = ntohl (mp->retval);
1556   vam->result_ready = 1;
1557 }
1558
1559 static void
1560 vl_api_tap_delete_reply_t_handler (vl_api_tap_delete_reply_t * mp)
1561 {
1562   vat_main_t *vam = &vat_main;
1563   i32 retval = ntohl (mp->retval);
1564   if (vam->async_mode)
1565     {
1566       vam->async_errors += (retval < 0);
1567     }
1568   else
1569     {
1570       vam->retval = retval;
1571       vam->result_ready = 1;
1572     }
1573 }
1574
1575 static void vl_api_tap_delete_reply_t_handler_json
1576   (vl_api_tap_delete_reply_t * mp)
1577 {
1578   vat_main_t *vam = &vat_main;
1579   vat_json_node_t node;
1580
1581   vat_json_init_object (&node);
1582   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1583
1584   vat_json_print (vam->ofp, &node);
1585   vat_json_free (&node);
1586
1587   vam->retval = ntohl (mp->retval);
1588   vam->result_ready = 1;
1589 }
1590
1591 static void vl_api_mpls_tunnel_add_del_reply_t_handler
1592   (vl_api_mpls_tunnel_add_del_reply_t * mp)
1593 {
1594   vat_main_t *vam = &vat_main;
1595   i32 retval = ntohl (mp->retval);
1596   if (vam->async_mode)
1597     {
1598       vam->async_errors += (retval < 0);
1599     }
1600   else
1601     {
1602       vam->retval = retval;
1603       vam->result_ready = 1;
1604     }
1605 }
1606
1607 static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
1608   (vl_api_mpls_tunnel_add_del_reply_t * mp)
1609 {
1610   vat_main_t *vam = &vat_main;
1611   vat_json_node_t node;
1612
1613   vat_json_init_object (&node);
1614   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1615   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
1616                             ntohl (mp->sw_if_index));
1617
1618   vat_json_print (vam->ofp, &node);
1619   vat_json_free (&node);
1620
1621   vam->retval = ntohl (mp->retval);
1622   vam->result_ready = 1;
1623 }
1624
1625 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
1626   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1627 {
1628   vat_main_t *vam = &vat_main;
1629   i32 retval = ntohl (mp->retval);
1630   if (vam->async_mode)
1631     {
1632       vam->async_errors += (retval < 0);
1633     }
1634   else
1635     {
1636       vam->retval = retval;
1637       vam->sw_if_index = ntohl (mp->sw_if_index);
1638       vam->result_ready = 1;
1639     }
1640 }
1641
1642 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
1643   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1644 {
1645   vat_main_t *vam = &vat_main;
1646   vat_json_node_t node;
1647
1648   vat_json_init_object (&node);
1649   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1650   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1651
1652   vat_json_print (vam->ofp, &node);
1653   vat_json_free (&node);
1654
1655   vam->retval = ntohl (mp->retval);
1656   vam->result_ready = 1;
1657 }
1658
1659
1660 static void vl_api_one_add_del_locator_set_reply_t_handler
1661   (vl_api_one_add_del_locator_set_reply_t * mp)
1662 {
1663   vat_main_t *vam = &vat_main;
1664   i32 retval = ntohl (mp->retval);
1665   if (vam->async_mode)
1666     {
1667       vam->async_errors += (retval < 0);
1668     }
1669   else
1670     {
1671       vam->retval = retval;
1672       vam->result_ready = 1;
1673     }
1674 }
1675
1676 static void vl_api_one_add_del_locator_set_reply_t_handler_json
1677   (vl_api_one_add_del_locator_set_reply_t * mp)
1678 {
1679   vat_main_t *vam = &vat_main;
1680   vat_json_node_t node;
1681
1682   vat_json_init_object (&node);
1683   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1684   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
1685
1686   vat_json_print (vam->ofp, &node);
1687   vat_json_free (&node);
1688
1689   vam->retval = ntohl (mp->retval);
1690   vam->result_ready = 1;
1691 }
1692
1693 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
1694   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1695 {
1696   vat_main_t *vam = &vat_main;
1697   i32 retval = ntohl (mp->retval);
1698   if (vam->async_mode)
1699     {
1700       vam->async_errors += (retval < 0);
1701     }
1702   else
1703     {
1704       vam->retval = retval;
1705       vam->sw_if_index = ntohl (mp->sw_if_index);
1706       vam->result_ready = 1;
1707     }
1708 }
1709
1710 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
1711   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1712 {
1713   vat_main_t *vam = &vat_main;
1714   vat_json_node_t node;
1715
1716   vat_json_init_object (&node);
1717   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1718   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1719
1720   vat_json_print (vam->ofp, &node);
1721   vat_json_free (&node);
1722
1723   vam->retval = ntohl (mp->retval);
1724   vam->result_ready = 1;
1725 }
1726
1727 static void vl_api_gre_add_del_tunnel_reply_t_handler
1728   (vl_api_gre_add_del_tunnel_reply_t * mp)
1729 {
1730   vat_main_t *vam = &vat_main;
1731   i32 retval = ntohl (mp->retval);
1732   if (vam->async_mode)
1733     {
1734       vam->async_errors += (retval < 0);
1735     }
1736   else
1737     {
1738       vam->retval = retval;
1739       vam->sw_if_index = ntohl (mp->sw_if_index);
1740       vam->result_ready = 1;
1741     }
1742 }
1743
1744 static void vl_api_gre_add_del_tunnel_reply_t_handler_json
1745   (vl_api_gre_add_del_tunnel_reply_t * mp)
1746 {
1747   vat_main_t *vam = &vat_main;
1748   vat_json_node_t node;
1749
1750   vat_json_init_object (&node);
1751   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1752   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1753
1754   vat_json_print (vam->ofp, &node);
1755   vat_json_free (&node);
1756
1757   vam->retval = ntohl (mp->retval);
1758   vam->result_ready = 1;
1759 }
1760
1761 static void vl_api_create_vhost_user_if_reply_t_handler
1762   (vl_api_create_vhost_user_if_reply_t * mp)
1763 {
1764   vat_main_t *vam = &vat_main;
1765   i32 retval = ntohl (mp->retval);
1766   if (vam->async_mode)
1767     {
1768       vam->async_errors += (retval < 0);
1769     }
1770   else
1771     {
1772       vam->retval = retval;
1773       vam->sw_if_index = ntohl (mp->sw_if_index);
1774       vam->result_ready = 1;
1775     }
1776 }
1777
1778 static void vl_api_create_vhost_user_if_reply_t_handler_json
1779   (vl_api_create_vhost_user_if_reply_t * mp)
1780 {
1781   vat_main_t *vam = &vat_main;
1782   vat_json_node_t node;
1783
1784   vat_json_init_object (&node);
1785   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1786   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1787
1788   vat_json_print (vam->ofp, &node);
1789   vat_json_free (&node);
1790
1791   vam->retval = ntohl (mp->retval);
1792   vam->result_ready = 1;
1793 }
1794
1795 static void vl_api_ip_address_details_t_handler
1796   (vl_api_ip_address_details_t * mp)
1797 {
1798   vat_main_t *vam = &vat_main;
1799   static ip_address_details_t empty_ip_address_details = { {0} };
1800   ip_address_details_t *address = NULL;
1801   ip_details_t *current_ip_details = NULL;
1802   ip_details_t *details = NULL;
1803
1804   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
1805
1806   if (!details || vam->current_sw_if_index >= vec_len (details)
1807       || !details[vam->current_sw_if_index].present)
1808     {
1809       errmsg ("ip address details arrived but not stored");
1810       errmsg ("ip_dump should be called first");
1811       return;
1812     }
1813
1814   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
1815
1816 #define addresses (current_ip_details->addr)
1817
1818   vec_validate_init_empty (addresses, vec_len (addresses),
1819                            empty_ip_address_details);
1820
1821   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
1822
1823   clib_memcpy (&address->ip, &mp->ip, sizeof (address->ip));
1824   address->prefix_length = mp->prefix_length;
1825 #undef addresses
1826 }
1827
1828 static void vl_api_ip_address_details_t_handler_json
1829   (vl_api_ip_address_details_t * mp)
1830 {
1831   vat_main_t *vam = &vat_main;
1832   vat_json_node_t *node = NULL;
1833   struct in6_addr ip6;
1834   struct in_addr ip4;
1835
1836   if (VAT_JSON_ARRAY != vam->json_tree.type)
1837     {
1838       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1839       vat_json_init_array (&vam->json_tree);
1840     }
1841   node = vat_json_array_add (&vam->json_tree);
1842
1843   vat_json_init_object (node);
1844   if (vam->is_ipv6)
1845     {
1846       clib_memcpy (&ip6, mp->ip, sizeof (ip6));
1847       vat_json_object_add_ip6 (node, "ip", ip6);
1848     }
1849   else
1850     {
1851       clib_memcpy (&ip4, mp->ip, sizeof (ip4));
1852       vat_json_object_add_ip4 (node, "ip", ip4);
1853     }
1854   vat_json_object_add_uint (node, "prefix_length", mp->prefix_length);
1855 }
1856
1857 static void
1858 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
1859 {
1860   vat_main_t *vam = &vat_main;
1861   static ip_details_t empty_ip_details = { 0 };
1862   ip_details_t *ip = NULL;
1863   u32 sw_if_index = ~0;
1864
1865   sw_if_index = ntohl (mp->sw_if_index);
1866
1867   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1868                            sw_if_index, empty_ip_details);
1869
1870   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1871                          sw_if_index);
1872
1873   ip->present = 1;
1874 }
1875
1876 static void
1877 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
1878 {
1879   vat_main_t *vam = &vat_main;
1880
1881   if (VAT_JSON_ARRAY != vam->json_tree.type)
1882     {
1883       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1884       vat_json_init_array (&vam->json_tree);
1885     }
1886   vat_json_array_add_uint (&vam->json_tree,
1887                            clib_net_to_host_u32 (mp->sw_if_index));
1888 }
1889
1890 static void vl_api_map_domain_details_t_handler_json
1891   (vl_api_map_domain_details_t * mp)
1892 {
1893   vat_json_node_t *node = NULL;
1894   vat_main_t *vam = &vat_main;
1895   struct in6_addr ip6;
1896   struct in_addr ip4;
1897
1898   if (VAT_JSON_ARRAY != vam->json_tree.type)
1899     {
1900       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1901       vat_json_init_array (&vam->json_tree);
1902     }
1903
1904   node = vat_json_array_add (&vam->json_tree);
1905   vat_json_init_object (node);
1906
1907   vat_json_object_add_uint (node, "domain_index",
1908                             clib_net_to_host_u32 (mp->domain_index));
1909   clib_memcpy (&ip6, mp->ip6_prefix, sizeof (ip6));
1910   vat_json_object_add_ip6 (node, "ip6_prefix", ip6);
1911   clib_memcpy (&ip4, mp->ip4_prefix, sizeof (ip4));
1912   vat_json_object_add_ip4 (node, "ip4_prefix", ip4);
1913   clib_memcpy (&ip6, mp->ip6_src, sizeof (ip6));
1914   vat_json_object_add_ip6 (node, "ip6_src", ip6);
1915   vat_json_object_add_int (node, "ip6_prefix_len", mp->ip6_prefix_len);
1916   vat_json_object_add_int (node, "ip4_prefix_len", mp->ip4_prefix_len);
1917   vat_json_object_add_int (node, "ip6_src_len", mp->ip6_src_len);
1918   vat_json_object_add_int (node, "ea_bits_len", mp->ea_bits_len);
1919   vat_json_object_add_int (node, "psid_offset", mp->psid_offset);
1920   vat_json_object_add_int (node, "psid_length", mp->psid_length);
1921   vat_json_object_add_uint (node, "flags", mp->flags);
1922   vat_json_object_add_uint (node, "mtu", clib_net_to_host_u16 (mp->mtu));
1923   vat_json_object_add_int (node, "is_translation", mp->is_translation);
1924 }
1925
1926 static void vl_api_map_domain_details_t_handler
1927   (vl_api_map_domain_details_t * mp)
1928 {
1929   vat_main_t *vam = &vat_main;
1930
1931   if (mp->is_translation)
1932     {
1933       print (vam->ofp,
1934              "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U/%d (ip6-src) index: %u",
1935              format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1936              format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1937              format_ip6_address, mp->ip6_src, mp->ip6_src_len,
1938              clib_net_to_host_u32 (mp->domain_index));
1939     }
1940   else
1941     {
1942       print (vam->ofp,
1943              "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U (ip6-src) index: %u",
1944              format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1945              format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1946              format_ip6_address, mp->ip6_src,
1947              clib_net_to_host_u32 (mp->domain_index));
1948     }
1949   print (vam->ofp, "  ea-len %d psid-offset %d psid-len %d mtu %d %s",
1950          mp->ea_bits_len, mp->psid_offset, mp->psid_length, mp->mtu,
1951          mp->is_translation ? "map-t" : "");
1952 }
1953
1954 static void vl_api_map_rule_details_t_handler_json
1955   (vl_api_map_rule_details_t * mp)
1956 {
1957   struct in6_addr ip6;
1958   vat_json_node_t *node = NULL;
1959   vat_main_t *vam = &vat_main;
1960
1961   if (VAT_JSON_ARRAY != vam->json_tree.type)
1962     {
1963       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1964       vat_json_init_array (&vam->json_tree);
1965     }
1966
1967   node = vat_json_array_add (&vam->json_tree);
1968   vat_json_init_object (node);
1969
1970   vat_json_object_add_uint (node, "psid", clib_net_to_host_u16 (mp->psid));
1971   clib_memcpy (&ip6, mp->ip6_dst, sizeof (ip6));
1972   vat_json_object_add_ip6 (node, "ip6_dst", ip6);
1973 }
1974
1975 static void
1976 vl_api_map_rule_details_t_handler (vl_api_map_rule_details_t * mp)
1977 {
1978   vat_main_t *vam = &vat_main;
1979   print (vam->ofp, " %d (psid) %U (ip6-dst)",
1980          clib_net_to_host_u16 (mp->psid), format_ip6_address, mp->ip6_dst);
1981 }
1982
1983 static void
1984 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
1985 {
1986   errmsg ("DHCP compl event: pid %d %s hostname %s host_addr %U "
1987           "router_addr %U host_mac %U",
1988           mp->pid, mp->is_ipv6 ? "ipv6" : "ipv4", mp->hostname,
1989           format_ip4_address, &mp->host_address,
1990           format_ip4_address, &mp->router_address,
1991           format_ethernet_address, mp->host_mac);
1992 }
1993
1994 static void vl_api_dhcp_compl_event_t_handler_json
1995   (vl_api_dhcp_compl_event_t * mp)
1996 {
1997   /* JSON output not supported */
1998 }
1999
2000 static void
2001 set_simple_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
2002                               u32 counter)
2003 {
2004   vat_main_t *vam = &vat_main;
2005   static u64 default_counter = 0;
2006
2007   vec_validate_init_empty (vam->simple_interface_counters, vnet_counter_type,
2008                            NULL);
2009   vec_validate_init_empty (vam->simple_interface_counters[vnet_counter_type],
2010                            sw_if_index, default_counter);
2011   vam->simple_interface_counters[vnet_counter_type][sw_if_index] = counter;
2012 }
2013
2014 static void
2015 set_combined_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
2016                                 interface_counter_t counter)
2017 {
2018   vat_main_t *vam = &vat_main;
2019   static interface_counter_t default_counter = { 0, };
2020
2021   vec_validate_init_empty (vam->combined_interface_counters,
2022                            vnet_counter_type, NULL);
2023   vec_validate_init_empty (vam->combined_interface_counters
2024                            [vnet_counter_type], sw_if_index, default_counter);
2025   vam->combined_interface_counters[vnet_counter_type][sw_if_index] = counter;
2026 }
2027
2028 static void vl_api_vnet_interface_counters_t_handler
2029   (vl_api_vnet_interface_counters_t * mp)
2030 {
2031   /* not supported */
2032 }
2033
2034 static void vl_api_vnet_interface_counters_t_handler_json
2035   (vl_api_vnet_interface_counters_t * mp)
2036 {
2037   interface_counter_t counter;
2038   vlib_counter_t *v;
2039   u64 *v_packets;
2040   u64 packets;
2041   u32 count;
2042   u32 first_sw_if_index;
2043   int i;
2044
2045   count = ntohl (mp->count);
2046   first_sw_if_index = ntohl (mp->first_sw_if_index);
2047
2048   if (!mp->is_combined)
2049     {
2050       v_packets = (u64 *) & mp->data;
2051       for (i = 0; i < count; i++)
2052         {
2053           packets =
2054             clib_net_to_host_u64 (clib_mem_unaligned (v_packets, u64));
2055           set_simple_interface_counter (mp->vnet_counter_type,
2056                                         first_sw_if_index + i, packets);
2057           v_packets++;
2058         }
2059     }
2060   else
2061     {
2062       v = (vlib_counter_t *) & mp->data;
2063       for (i = 0; i < count; i++)
2064         {
2065           counter.packets =
2066             clib_net_to_host_u64 (clib_mem_unaligned (&v->packets, u64));
2067           counter.bytes =
2068             clib_net_to_host_u64 (clib_mem_unaligned (&v->bytes, u64));
2069           set_combined_interface_counter (mp->vnet_counter_type,
2070                                           first_sw_if_index + i, counter);
2071           v++;
2072         }
2073     }
2074 }
2075
2076 static u32
2077 ip4_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2078 {
2079   vat_main_t *vam = &vat_main;
2080   u32 i;
2081
2082   for (i = 0; i < vec_len (vam->ip4_fib_counters_vrf_id_by_index); i++)
2083     {
2084       if (vam->ip4_fib_counters_vrf_id_by_index[i] == vrf_id)
2085         {
2086           return i;
2087         }
2088     }
2089   return ~0;
2090 }
2091
2092 static u32
2093 ip6_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2094 {
2095   vat_main_t *vam = &vat_main;
2096   u32 i;
2097
2098   for (i = 0; i < vec_len (vam->ip6_fib_counters_vrf_id_by_index); i++)
2099     {
2100       if (vam->ip6_fib_counters_vrf_id_by_index[i] == vrf_id)
2101         {
2102           return i;
2103         }
2104     }
2105   return ~0;
2106 }
2107
2108 static void vl_api_vnet_ip4_fib_counters_t_handler
2109   (vl_api_vnet_ip4_fib_counters_t * mp)
2110 {
2111   /* not supported */
2112 }
2113
2114 static void vl_api_vnet_ip4_fib_counters_t_handler_json
2115   (vl_api_vnet_ip4_fib_counters_t * mp)
2116 {
2117   vat_main_t *vam = &vat_main;
2118   vl_api_ip4_fib_counter_t *v;
2119   ip4_fib_counter_t *counter;
2120   struct in_addr ip4;
2121   u32 vrf_id;
2122   u32 vrf_index;
2123   u32 count;
2124   int i;
2125
2126   vrf_id = ntohl (mp->vrf_id);
2127   vrf_index = ip4_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2128   if (~0 == vrf_index)
2129     {
2130       vrf_index = vec_len (vam->ip4_fib_counters_vrf_id_by_index);
2131       vec_validate (vam->ip4_fib_counters_vrf_id_by_index, vrf_index);
2132       vam->ip4_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2133       vec_validate (vam->ip4_fib_counters, vrf_index);
2134       vam->ip4_fib_counters[vrf_index] = NULL;
2135     }
2136
2137   vec_free (vam->ip4_fib_counters[vrf_index]);
2138   v = (vl_api_ip4_fib_counter_t *) & mp->c;
2139   count = ntohl (mp->count);
2140   for (i = 0; i < count; i++)
2141     {
2142       vec_validate (vam->ip4_fib_counters[vrf_index], i);
2143       counter = &vam->ip4_fib_counters[vrf_index][i];
2144       clib_memcpy (&ip4, &v->address, sizeof (ip4));
2145       counter->address = ip4;
2146       counter->address_length = v->address_length;
2147       counter->packets = clib_net_to_host_u64 (v->packets);
2148       counter->bytes = clib_net_to_host_u64 (v->bytes);
2149       v++;
2150     }
2151 }
2152
2153 static void vl_api_vnet_ip4_nbr_counters_t_handler
2154   (vl_api_vnet_ip4_nbr_counters_t * mp)
2155 {
2156   /* not supported */
2157 }
2158
2159 static void vl_api_vnet_ip4_nbr_counters_t_handler_json
2160   (vl_api_vnet_ip4_nbr_counters_t * mp)
2161 {
2162   vat_main_t *vam = &vat_main;
2163   vl_api_ip4_nbr_counter_t *v;
2164   ip4_nbr_counter_t *counter;
2165   u32 sw_if_index;
2166   u32 count;
2167   int i;
2168
2169   sw_if_index = ntohl (mp->sw_if_index);
2170   count = ntohl (mp->count);
2171   vec_validate (vam->ip4_nbr_counters, sw_if_index);
2172
2173   if (mp->begin)
2174     vec_free (vam->ip4_nbr_counters[sw_if_index]);
2175
2176   v = (vl_api_ip4_nbr_counter_t *) & mp->c;
2177   for (i = 0; i < count; i++)
2178     {
2179       vec_validate (vam->ip4_nbr_counters[sw_if_index], i);
2180       counter = &vam->ip4_nbr_counters[sw_if_index][i];
2181       counter->address.s_addr = v->address;
2182       counter->packets = clib_net_to_host_u64 (v->packets);
2183       counter->bytes = clib_net_to_host_u64 (v->bytes);
2184       counter->linkt = v->link_type;
2185       v++;
2186     }
2187 }
2188
2189 static void vl_api_vnet_ip6_fib_counters_t_handler
2190   (vl_api_vnet_ip6_fib_counters_t * mp)
2191 {
2192   /* not supported */
2193 }
2194
2195 static void vl_api_vnet_ip6_fib_counters_t_handler_json
2196   (vl_api_vnet_ip6_fib_counters_t * mp)
2197 {
2198   vat_main_t *vam = &vat_main;
2199   vl_api_ip6_fib_counter_t *v;
2200   ip6_fib_counter_t *counter;
2201   struct in6_addr ip6;
2202   u32 vrf_id;
2203   u32 vrf_index;
2204   u32 count;
2205   int i;
2206
2207   vrf_id = ntohl (mp->vrf_id);
2208   vrf_index = ip6_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2209   if (~0 == vrf_index)
2210     {
2211       vrf_index = vec_len (vam->ip6_fib_counters_vrf_id_by_index);
2212       vec_validate (vam->ip6_fib_counters_vrf_id_by_index, vrf_index);
2213       vam->ip6_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2214       vec_validate (vam->ip6_fib_counters, vrf_index);
2215       vam->ip6_fib_counters[vrf_index] = NULL;
2216     }
2217
2218   vec_free (vam->ip6_fib_counters[vrf_index]);
2219   v = (vl_api_ip6_fib_counter_t *) & mp->c;
2220   count = ntohl (mp->count);
2221   for (i = 0; i < count; i++)
2222     {
2223       vec_validate (vam->ip6_fib_counters[vrf_index], i);
2224       counter = &vam->ip6_fib_counters[vrf_index][i];
2225       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2226       counter->address = ip6;
2227       counter->address_length = v->address_length;
2228       counter->packets = clib_net_to_host_u64 (v->packets);
2229       counter->bytes = clib_net_to_host_u64 (v->bytes);
2230       v++;
2231     }
2232 }
2233
2234 static void vl_api_vnet_ip6_nbr_counters_t_handler
2235   (vl_api_vnet_ip6_nbr_counters_t * mp)
2236 {
2237   /* not supported */
2238 }
2239
2240 static void vl_api_vnet_ip6_nbr_counters_t_handler_json
2241   (vl_api_vnet_ip6_nbr_counters_t * mp)
2242 {
2243   vat_main_t *vam = &vat_main;
2244   vl_api_ip6_nbr_counter_t *v;
2245   ip6_nbr_counter_t *counter;
2246   struct in6_addr ip6;
2247   u32 sw_if_index;
2248   u32 count;
2249   int i;
2250
2251   sw_if_index = ntohl (mp->sw_if_index);
2252   count = ntohl (mp->count);
2253   vec_validate (vam->ip6_nbr_counters, sw_if_index);
2254
2255   if (mp->begin)
2256     vec_free (vam->ip6_nbr_counters[sw_if_index]);
2257
2258   v = (vl_api_ip6_nbr_counter_t *) & mp->c;
2259   for (i = 0; i < count; i++)
2260     {
2261       vec_validate (vam->ip6_nbr_counters[sw_if_index], i);
2262       counter = &vam->ip6_nbr_counters[sw_if_index][i];
2263       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2264       counter->address = ip6;
2265       counter->packets = clib_net_to_host_u64 (v->packets);
2266       counter->bytes = clib_net_to_host_u64 (v->bytes);
2267       v++;
2268     }
2269 }
2270
2271 static void vl_api_get_first_msg_id_reply_t_handler
2272   (vl_api_get_first_msg_id_reply_t * mp)
2273 {
2274   vat_main_t *vam = &vat_main;
2275   i32 retval = ntohl (mp->retval);
2276
2277   if (vam->async_mode)
2278     {
2279       vam->async_errors += (retval < 0);
2280     }
2281   else
2282     {
2283       vam->retval = retval;
2284       vam->result_ready = 1;
2285     }
2286   if (retval >= 0)
2287     {
2288       errmsg ("first message id %d", ntohs (mp->first_msg_id));
2289     }
2290 }
2291
2292 static void vl_api_get_first_msg_id_reply_t_handler_json
2293   (vl_api_get_first_msg_id_reply_t * mp)
2294 {
2295   vat_main_t *vam = &vat_main;
2296   vat_json_node_t node;
2297
2298   vat_json_init_object (&node);
2299   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2300   vat_json_object_add_uint (&node, "first_msg_id",
2301                             (uint) ntohs (mp->first_msg_id));
2302
2303   vat_json_print (vam->ofp, &node);
2304   vat_json_free (&node);
2305
2306   vam->retval = ntohl (mp->retval);
2307   vam->result_ready = 1;
2308 }
2309
2310 static void vl_api_get_node_graph_reply_t_handler
2311   (vl_api_get_node_graph_reply_t * mp)
2312 {
2313   vat_main_t *vam = &vat_main;
2314   api_main_t *am = &api_main;
2315   i32 retval = ntohl (mp->retval);
2316   u8 *pvt_copy, *reply;
2317   void *oldheap;
2318   vlib_node_t *node;
2319   int i;
2320
2321   if (vam->async_mode)
2322     {
2323       vam->async_errors += (retval < 0);
2324     }
2325   else
2326     {
2327       vam->retval = retval;
2328       vam->result_ready = 1;
2329     }
2330
2331   /* "Should never happen..." */
2332   if (retval != 0)
2333     return;
2334
2335   reply = (u8 *) (mp->reply_in_shmem);
2336   pvt_copy = vec_dup (reply);
2337
2338   /* Toss the shared-memory original... */
2339   pthread_mutex_lock (&am->vlib_rp->mutex);
2340   oldheap = svm_push_data_heap (am->vlib_rp);
2341
2342   vec_free (reply);
2343
2344   svm_pop_heap (oldheap);
2345   pthread_mutex_unlock (&am->vlib_rp->mutex);
2346
2347   if (vam->graph_nodes)
2348     {
2349       hash_free (vam->graph_node_index_by_name);
2350
2351       for (i = 0; i < vec_len (vam->graph_nodes); i++)
2352         {
2353           node = vam->graph_nodes[i];
2354           vec_free (node->name);
2355           vec_free (node->next_nodes);
2356           vec_free (node);
2357         }
2358       vec_free (vam->graph_nodes);
2359     }
2360
2361   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2362   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2363   vec_free (pvt_copy);
2364
2365   for (i = 0; i < vec_len (vam->graph_nodes); i++)
2366     {
2367       node = vam->graph_nodes[i];
2368       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2369     }
2370 }
2371
2372 static void vl_api_get_node_graph_reply_t_handler_json
2373   (vl_api_get_node_graph_reply_t * mp)
2374 {
2375   vat_main_t *vam = &vat_main;
2376   api_main_t *am = &api_main;
2377   void *oldheap;
2378   vat_json_node_t node;
2379   u8 *reply;
2380
2381   /* $$$$ make this real? */
2382   vat_json_init_object (&node);
2383   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2384   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2385
2386   reply = (u8 *) (mp->reply_in_shmem);
2387
2388   /* Toss the shared-memory original... */
2389   pthread_mutex_lock (&am->vlib_rp->mutex);
2390   oldheap = svm_push_data_heap (am->vlib_rp);
2391
2392   vec_free (reply);
2393
2394   svm_pop_heap (oldheap);
2395   pthread_mutex_unlock (&am->vlib_rp->mutex);
2396
2397   vat_json_print (vam->ofp, &node);
2398   vat_json_free (&node);
2399
2400   vam->retval = ntohl (mp->retval);
2401   vam->result_ready = 1;
2402 }
2403
2404 static void
2405 vl_api_one_locator_details_t_handler (vl_api_one_locator_details_t * mp)
2406 {
2407   vat_main_t *vam = &vat_main;
2408   u8 *s = 0;
2409
2410   if (mp->local)
2411     {
2412       s = format (s, "%=16d%=16d%=16d",
2413                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
2414     }
2415   else
2416     {
2417       s = format (s, "%=16U%=16d%=16d",
2418                   mp->is_ipv6 ? format_ip6_address :
2419                   format_ip4_address,
2420                   mp->ip_address, mp->priority, mp->weight);
2421     }
2422
2423   print (vam->ofp, "%v", s);
2424   vec_free (s);
2425 }
2426
2427 static void
2428 vl_api_one_locator_details_t_handler_json (vl_api_one_locator_details_t * mp)
2429 {
2430   vat_main_t *vam = &vat_main;
2431   vat_json_node_t *node = NULL;
2432   struct in6_addr ip6;
2433   struct in_addr ip4;
2434
2435   if (VAT_JSON_ARRAY != vam->json_tree.type)
2436     {
2437       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2438       vat_json_init_array (&vam->json_tree);
2439     }
2440   node = vat_json_array_add (&vam->json_tree);
2441   vat_json_init_object (node);
2442
2443   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2444   vat_json_object_add_uint (node, "priority", mp->priority);
2445   vat_json_object_add_uint (node, "weight", mp->weight);
2446
2447   if (mp->local)
2448     vat_json_object_add_uint (node, "sw_if_index",
2449                               clib_net_to_host_u32 (mp->sw_if_index));
2450   else
2451     {
2452       if (mp->is_ipv6)
2453         {
2454           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2455           vat_json_object_add_ip6 (node, "address", ip6);
2456         }
2457       else
2458         {
2459           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2460           vat_json_object_add_ip4 (node, "address", ip4);
2461         }
2462     }
2463 }
2464
2465 static void
2466 vl_api_one_locator_set_details_t_handler (vl_api_one_locator_set_details_t *
2467                                           mp)
2468 {
2469   vat_main_t *vam = &vat_main;
2470   u8 *ls_name = 0;
2471
2472   ls_name = format (0, "%s", mp->ls_name);
2473
2474   print (vam->ofp, "%=10d%=15v", clib_net_to_host_u32 (mp->ls_index),
2475          ls_name);
2476   vec_free (ls_name);
2477 }
2478
2479 static void
2480   vl_api_one_locator_set_details_t_handler_json
2481   (vl_api_one_locator_set_details_t * mp)
2482 {
2483   vat_main_t *vam = &vat_main;
2484   vat_json_node_t *node = 0;
2485   u8 *ls_name = 0;
2486
2487   ls_name = format (0, "%s", mp->ls_name);
2488   vec_add1 (ls_name, 0);
2489
2490   if (VAT_JSON_ARRAY != vam->json_tree.type)
2491     {
2492       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2493       vat_json_init_array (&vam->json_tree);
2494     }
2495   node = vat_json_array_add (&vam->json_tree);
2496
2497   vat_json_init_object (node);
2498   vat_json_object_add_string_copy (node, "ls_name", ls_name);
2499   vat_json_object_add_uint (node, "ls_index",
2500                             clib_net_to_host_u32 (mp->ls_index));
2501   vec_free (ls_name);
2502 }
2503
2504 static u8 *
2505 format_lisp_flat_eid (u8 * s, va_list * args)
2506 {
2507   u32 type = va_arg (*args, u32);
2508   u8 *eid = va_arg (*args, u8 *);
2509   u32 eid_len = va_arg (*args, u32);
2510
2511   switch (type)
2512     {
2513     case 0:
2514       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
2515     case 1:
2516       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
2517     case 2:
2518       return format (s, "%U", format_ethernet_address, eid);
2519     }
2520   return 0;
2521 }
2522
2523 static u8 *
2524 format_lisp_eid_vat (u8 * s, va_list * args)
2525 {
2526   u32 type = va_arg (*args, u32);
2527   u8 *eid = va_arg (*args, u8 *);
2528   u32 eid_len = va_arg (*args, u32);
2529   u8 *seid = va_arg (*args, u8 *);
2530   u32 seid_len = va_arg (*args, u32);
2531   u32 is_src_dst = va_arg (*args, u32);
2532
2533   if (is_src_dst)
2534     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
2535
2536   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
2537
2538   return s;
2539 }
2540
2541 static void
2542 vl_api_one_eid_table_details_t_handler (vl_api_one_eid_table_details_t * mp)
2543 {
2544   vat_main_t *vam = &vat_main;
2545   u8 *s = 0, *eid = 0;
2546
2547   if (~0 == mp->locator_set_index)
2548     s = format (0, "action: %d", mp->action);
2549   else
2550     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
2551
2552   eid = format (0, "%U", format_lisp_eid_vat,
2553                 mp->eid_type,
2554                 mp->eid,
2555                 mp->eid_prefix_len,
2556                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2557   vec_add1 (eid, 0);
2558
2559   print (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s",
2560          clib_net_to_host_u32 (mp->vni),
2561          eid,
2562          mp->is_local ? "local" : "remote",
2563          s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
2564          clib_net_to_host_u16 (mp->key_id), mp->key);
2565
2566   vec_free (s);
2567   vec_free (eid);
2568 }
2569
2570 static void
2571 vl_api_one_eid_table_details_t_handler_json (vl_api_one_eid_table_details_t
2572                                              * mp)
2573 {
2574   vat_main_t *vam = &vat_main;
2575   vat_json_node_t *node = 0;
2576   u8 *eid = 0;
2577
2578   if (VAT_JSON_ARRAY != vam->json_tree.type)
2579     {
2580       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2581       vat_json_init_array (&vam->json_tree);
2582     }
2583   node = vat_json_array_add (&vam->json_tree);
2584
2585   vat_json_init_object (node);
2586   if (~0 == mp->locator_set_index)
2587     vat_json_object_add_uint (node, "action", mp->action);
2588   else
2589     vat_json_object_add_uint (node, "locator_set_index",
2590                               clib_net_to_host_u32 (mp->locator_set_index));
2591
2592   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
2593   eid = format (0, "%U", format_lisp_eid_vat,
2594                 mp->eid_type,
2595                 mp->eid,
2596                 mp->eid_prefix_len,
2597                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2598   vec_add1 (eid, 0);
2599   vat_json_object_add_string_copy (node, "eid", eid);
2600   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2601   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
2602   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
2603
2604   if (mp->key_id)
2605     {
2606       vat_json_object_add_uint (node, "key_id",
2607                                 clib_net_to_host_u16 (mp->key_id));
2608       vat_json_object_add_string_copy (node, "key", mp->key);
2609     }
2610   vec_free (eid);
2611 }
2612
2613 static void
2614   vl_api_one_eid_table_map_details_t_handler
2615   (vl_api_one_eid_table_map_details_t * mp)
2616 {
2617   vat_main_t *vam = &vat_main;
2618
2619   u8 *line = format (0, "%=10d%=10d",
2620                      clib_net_to_host_u32 (mp->vni),
2621                      clib_net_to_host_u32 (mp->dp_table));
2622   print (vam->ofp, "%v", line);
2623   vec_free (line);
2624 }
2625
2626 static void
2627   vl_api_one_eid_table_map_details_t_handler_json
2628   (vl_api_one_eid_table_map_details_t * mp)
2629 {
2630   vat_main_t *vam = &vat_main;
2631   vat_json_node_t *node = NULL;
2632
2633   if (VAT_JSON_ARRAY != vam->json_tree.type)
2634     {
2635       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2636       vat_json_init_array (&vam->json_tree);
2637     }
2638   node = vat_json_array_add (&vam->json_tree);
2639   vat_json_init_object (node);
2640   vat_json_object_add_uint (node, "dp_table",
2641                             clib_net_to_host_u32 (mp->dp_table));
2642   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2643 }
2644
2645 static void
2646   vl_api_one_eid_table_vni_details_t_handler
2647   (vl_api_one_eid_table_vni_details_t * mp)
2648 {
2649   vat_main_t *vam = &vat_main;
2650
2651   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
2652   print (vam->ofp, "%v", line);
2653   vec_free (line);
2654 }
2655
2656 static void
2657   vl_api_one_eid_table_vni_details_t_handler_json
2658   (vl_api_one_eid_table_vni_details_t * mp)
2659 {
2660   vat_main_t *vam = &vat_main;
2661   vat_json_node_t *node = NULL;
2662
2663   if (VAT_JSON_ARRAY != vam->json_tree.type)
2664     {
2665       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2666       vat_json_init_array (&vam->json_tree);
2667     }
2668   node = vat_json_array_add (&vam->json_tree);
2669   vat_json_init_object (node);
2670   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2671 }
2672
2673 static void
2674   vl_api_show_one_map_register_state_reply_t_handler
2675   (vl_api_show_one_map_register_state_reply_t * mp)
2676 {
2677   vat_main_t *vam = &vat_main;
2678   int retval = clib_net_to_host_u32 (mp->retval);
2679
2680   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
2681
2682   vam->retval = retval;
2683   vam->result_ready = 1;
2684 }
2685
2686 static void
2687   vl_api_show_one_map_register_state_reply_t_handler_json
2688   (vl_api_show_one_map_register_state_reply_t * mp)
2689 {
2690   vat_main_t *vam = &vat_main;
2691   vat_json_node_t _node, *node = &_node;
2692   int retval = clib_net_to_host_u32 (mp->retval);
2693
2694   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
2695
2696   vat_json_init_object (node);
2697   vat_json_object_add_string_copy (node, "state", s);
2698
2699   vat_json_print (vam->ofp, node);
2700   vat_json_free (node);
2701
2702   vam->retval = retval;
2703   vam->result_ready = 1;
2704   vec_free (s);
2705 }
2706
2707 static void
2708   vl_api_show_one_rloc_probe_state_reply_t_handler
2709   (vl_api_show_one_rloc_probe_state_reply_t * mp)
2710 {
2711   vat_main_t *vam = &vat_main;
2712   int retval = clib_net_to_host_u32 (mp->retval);
2713
2714   if (retval)
2715     goto end;
2716
2717   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
2718 end:
2719   vam->retval = retval;
2720   vam->result_ready = 1;
2721 }
2722
2723 static void
2724   vl_api_show_one_rloc_probe_state_reply_t_handler_json
2725   (vl_api_show_one_rloc_probe_state_reply_t * mp)
2726 {
2727   vat_main_t *vam = &vat_main;
2728   vat_json_node_t _node, *node = &_node;
2729   int retval = clib_net_to_host_u32 (mp->retval);
2730
2731   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
2732   vat_json_init_object (node);
2733   vat_json_object_add_string_copy (node, "state", s);
2734
2735   vat_json_print (vam->ofp, node);
2736   vat_json_free (node);
2737
2738   vam->retval = retval;
2739   vam->result_ready = 1;
2740   vec_free (s);
2741 }
2742
2743 static void
2744 api_gpe_fwd_entry_net_to_host (vl_api_gpe_fwd_entry_t * e)
2745 {
2746   e->dp_table = clib_net_to_host_u32 (e->dp_table);
2747   e->fwd_entry_index = clib_net_to_host_u32 (e->fwd_entry_index);
2748 }
2749
2750 static void
2751   gpe_fwd_entries_get_reply_t_net_to_host
2752   (vl_api_gpe_fwd_entries_get_reply_t * mp)
2753 {
2754   u32 i;
2755
2756   mp->count = clib_net_to_host_u32 (mp->count);
2757   for (i = 0; i < mp->count; i++)
2758     {
2759       api_gpe_fwd_entry_net_to_host (&mp->entries[i]);
2760     }
2761 }
2762
2763 static u8 *
2764 format_gpe_encap_mode (u8 * s, va_list * args)
2765 {
2766   u32 mode = va_arg (*args, u32);
2767
2768   switch (mode)
2769     {
2770     case 0:
2771       return format (s, "lisp");
2772     case 1:
2773       return format (s, "vxlan");
2774     }
2775   return 0;
2776 }
2777
2778 static void
2779   vl_api_gpe_get_encap_mode_reply_t_handler
2780   (vl_api_gpe_get_encap_mode_reply_t * mp)
2781 {
2782   vat_main_t *vam = &vat_main;
2783
2784   print (vam->ofp, "gpe mode: %U", format_gpe_encap_mode, mp->encap_mode);
2785   vam->retval = ntohl (mp->retval);
2786   vam->result_ready = 1;
2787 }
2788
2789 static void
2790   vl_api_gpe_get_encap_mode_reply_t_handler_json
2791   (vl_api_gpe_get_encap_mode_reply_t * mp)
2792 {
2793   vat_main_t *vam = &vat_main;
2794   vat_json_node_t node;
2795
2796   u8 *encap_mode = format (0, "%U", format_gpe_encap_mode, mp->encap_mode);
2797   vec_add1 (encap_mode, 0);
2798
2799   vat_json_init_object (&node);
2800   vat_json_object_add_string_copy (&node, "gpe_mode", encap_mode);
2801
2802   vec_free (encap_mode);
2803   vat_json_print (vam->ofp, &node);
2804   vat_json_free (&node);
2805
2806   vam->retval = ntohl (mp->retval);
2807   vam->result_ready = 1;
2808 }
2809
2810 static void
2811   vl_api_gpe_fwd_entry_path_details_t_handler
2812   (vl_api_gpe_fwd_entry_path_details_t * mp)
2813 {
2814   vat_main_t *vam = &vat_main;
2815   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
2816
2817   if (mp->lcl_loc.is_ip4)
2818     format_ip_address_fcn = format_ip4_address;
2819   else
2820     format_ip_address_fcn = format_ip6_address;
2821
2822   print (vam->ofp, "w:%d %30U %30U", mp->rmt_loc.weight,
2823          format_ip_address_fcn, &mp->lcl_loc,
2824          format_ip_address_fcn, &mp->rmt_loc);
2825 }
2826
2827 static void
2828 lisp_fill_locator_node (vat_json_node_t * n, vl_api_gpe_locator_t * loc)
2829 {
2830   struct in6_addr ip6;
2831   struct in_addr ip4;
2832
2833   if (loc->is_ip4)
2834     {
2835       clib_memcpy (&ip4, loc->addr, sizeof (ip4));
2836       vat_json_object_add_ip4 (n, "address", ip4);
2837     }
2838   else
2839     {
2840       clib_memcpy (&ip6, loc->addr, sizeof (ip6));
2841       vat_json_object_add_ip6 (n, "address", ip6);
2842     }
2843   vat_json_object_add_uint (n, "weight", loc->weight);
2844 }
2845
2846 static void
2847   vl_api_gpe_fwd_entry_path_details_t_handler_json
2848   (vl_api_gpe_fwd_entry_path_details_t * mp)
2849 {
2850   vat_main_t *vam = &vat_main;
2851   vat_json_node_t *node = NULL;
2852   vat_json_node_t *loc_node;
2853
2854   if (VAT_JSON_ARRAY != vam->json_tree.type)
2855     {
2856       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2857       vat_json_init_array (&vam->json_tree);
2858     }
2859   node = vat_json_array_add (&vam->json_tree);
2860   vat_json_init_object (node);
2861
2862   loc_node = vat_json_object_add (node, "local_locator");
2863   vat_json_init_object (loc_node);
2864   lisp_fill_locator_node (loc_node, &mp->lcl_loc);
2865
2866   loc_node = vat_json_object_add (node, "remote_locator");
2867   vat_json_init_object (loc_node);
2868   lisp_fill_locator_node (loc_node, &mp->rmt_loc);
2869 }
2870
2871 static void
2872   vl_api_gpe_fwd_entries_get_reply_t_handler
2873   (vl_api_gpe_fwd_entries_get_reply_t * mp)
2874 {
2875   vat_main_t *vam = &vat_main;
2876   u32 i;
2877   int retval = clib_net_to_host_u32 (mp->retval);
2878   vl_api_gpe_fwd_entry_t *e;
2879
2880   if (retval)
2881     goto end;
2882
2883   gpe_fwd_entries_get_reply_t_net_to_host (mp);
2884
2885   for (i = 0; i < mp->count; i++)
2886     {
2887       e = &mp->entries[i];
2888       print (vam->ofp, "%10d %10d %U %40U", e->fwd_entry_index, e->dp_table,
2889              format_lisp_flat_eid, e->eid_type, e->leid, e->leid_prefix_len,
2890              format_lisp_flat_eid, e->eid_type, e->reid, e->reid_prefix_len);
2891     }
2892
2893 end:
2894   vam->retval = retval;
2895   vam->result_ready = 1;
2896 }
2897
2898 static void
2899   vl_api_gpe_fwd_entries_get_reply_t_handler_json
2900   (vl_api_gpe_fwd_entries_get_reply_t * mp)
2901 {
2902   u8 *s = 0;
2903   vat_main_t *vam = &vat_main;
2904   vat_json_node_t *e = 0, root;
2905   u32 i;
2906   int retval = clib_net_to_host_u32 (mp->retval);
2907   vl_api_gpe_fwd_entry_t *fwd;
2908
2909   if (retval)
2910     goto end;
2911
2912   gpe_fwd_entries_get_reply_t_net_to_host (mp);
2913   vat_json_init_array (&root);
2914
2915   for (i = 0; i < mp->count; i++)
2916     {
2917       e = vat_json_array_add (&root);
2918       fwd = &mp->entries[i];
2919
2920       vat_json_init_object (e);
2921       vat_json_object_add_int (e, "fwd_entry_index", fwd->fwd_entry_index);
2922       vat_json_object_add_int (e, "dp_table", fwd->dp_table);
2923
2924       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->leid,
2925                   fwd->leid_prefix_len);
2926       vec_add1 (s, 0);
2927       vat_json_object_add_string_copy (e, "leid", s);
2928       vec_free (s);
2929
2930       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->reid,
2931                   fwd->reid_prefix_len);
2932       vec_add1 (s, 0);
2933       vat_json_object_add_string_copy (e, "reid", s);
2934       vec_free (s);
2935     }
2936
2937   vat_json_print (vam->ofp, &root);
2938   vat_json_free (&root);
2939
2940 end:
2941   vam->retval = retval;
2942   vam->result_ready = 1;
2943 }
2944
2945 static void
2946   vl_api_one_adjacencies_get_reply_t_handler
2947   (vl_api_one_adjacencies_get_reply_t * mp)
2948 {
2949   vat_main_t *vam = &vat_main;
2950   u32 i, n;
2951   int retval = clib_net_to_host_u32 (mp->retval);
2952   vl_api_one_adjacency_t *a;
2953
2954   if (retval)
2955     goto end;
2956
2957   n = clib_net_to_host_u32 (mp->count);
2958
2959   for (i = 0; i < n; i++)
2960     {
2961       a = &mp->adjacencies[i];
2962       print (vam->ofp, "%U %40U",
2963              format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
2964              format_lisp_flat_eid, a->eid_type, a->reid, a->reid_prefix_len);
2965     }
2966
2967 end:
2968   vam->retval = retval;
2969   vam->result_ready = 1;
2970 }
2971
2972 static void
2973   vl_api_one_adjacencies_get_reply_t_handler_json
2974   (vl_api_one_adjacencies_get_reply_t * mp)
2975 {
2976   u8 *s = 0;
2977   vat_main_t *vam = &vat_main;
2978   vat_json_node_t *e = 0, root;
2979   u32 i, n;
2980   int retval = clib_net_to_host_u32 (mp->retval);
2981   vl_api_one_adjacency_t *a;
2982
2983   if (retval)
2984     goto end;
2985
2986   n = clib_net_to_host_u32 (mp->count);
2987   vat_json_init_array (&root);
2988
2989   for (i = 0; i < n; i++)
2990     {
2991       e = vat_json_array_add (&root);
2992       a = &mp->adjacencies[i];
2993
2994       vat_json_init_object (e);
2995       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
2996                   a->leid_prefix_len);
2997       vec_add1 (s, 0);
2998       vat_json_object_add_string_copy (e, "leid", s);
2999       vec_free (s);
3000
3001       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
3002                   a->reid_prefix_len);
3003       vec_add1 (s, 0);
3004       vat_json_object_add_string_copy (e, "reid", s);
3005       vec_free (s);
3006     }
3007
3008   vat_json_print (vam->ofp, &root);
3009   vat_json_free (&root);
3010
3011 end:
3012   vam->retval = retval;
3013   vam->result_ready = 1;
3014 }
3015
3016 static void
3017 vl_api_one_map_server_details_t_handler (vl_api_one_map_server_details_t * mp)
3018 {
3019   vat_main_t *vam = &vat_main;
3020
3021   print (vam->ofp, "%=20U",
3022          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
3023          mp->ip_address);
3024 }
3025
3026 static void
3027   vl_api_one_map_server_details_t_handler_json
3028   (vl_api_one_map_server_details_t * mp)
3029 {
3030   vat_main_t *vam = &vat_main;
3031   vat_json_node_t *node = NULL;
3032   struct in6_addr ip6;
3033   struct in_addr ip4;
3034
3035   if (VAT_JSON_ARRAY != vam->json_tree.type)
3036     {
3037       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3038       vat_json_init_array (&vam->json_tree);
3039     }
3040   node = vat_json_array_add (&vam->json_tree);
3041
3042   vat_json_init_object (node);
3043   if (mp->is_ipv6)
3044     {
3045       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
3046       vat_json_object_add_ip6 (node, "map-server", ip6);
3047     }
3048   else
3049     {
3050       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
3051       vat_json_object_add_ip4 (node, "map-server", ip4);
3052     }
3053 }
3054
3055 static void
3056 vl_api_one_map_resolver_details_t_handler (vl_api_one_map_resolver_details_t
3057                                            * mp)
3058 {
3059   vat_main_t *vam = &vat_main;
3060
3061   print (vam->ofp, "%=20U",
3062          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
3063          mp->ip_address);
3064 }
3065
3066 static void
3067   vl_api_one_map_resolver_details_t_handler_json
3068   (vl_api_one_map_resolver_details_t * mp)
3069 {
3070   vat_main_t *vam = &vat_main;
3071   vat_json_node_t *node = NULL;
3072   struct in6_addr ip6;
3073   struct in_addr ip4;
3074
3075   if (VAT_JSON_ARRAY != vam->json_tree.type)
3076     {
3077       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3078       vat_json_init_array (&vam->json_tree);
3079     }
3080   node = vat_json_array_add (&vam->json_tree);
3081
3082   vat_json_init_object (node);
3083   if (mp->is_ipv6)
3084     {
3085       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
3086       vat_json_object_add_ip6 (node, "map resolver", ip6);
3087     }
3088   else
3089     {
3090       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
3091       vat_json_object_add_ip4 (node, "map resolver", ip4);
3092     }
3093 }
3094
3095 static void
3096 vl_api_show_one_status_reply_t_handler (vl_api_show_one_status_reply_t * mp)
3097 {
3098   vat_main_t *vam = &vat_main;
3099   i32 retval = ntohl (mp->retval);
3100
3101   if (0 <= retval)
3102     {
3103       print (vam->ofp, "feature: %s\ngpe: %s",
3104              mp->feature_status ? "enabled" : "disabled",
3105              mp->gpe_status ? "enabled" : "disabled");
3106     }
3107
3108   vam->retval = retval;
3109   vam->result_ready = 1;
3110 }
3111
3112 static void
3113   vl_api_show_one_status_reply_t_handler_json
3114   (vl_api_show_one_status_reply_t * mp)
3115 {
3116   vat_main_t *vam = &vat_main;
3117   vat_json_node_t node;
3118   u8 *gpe_status = NULL;
3119   u8 *feature_status = NULL;
3120
3121   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
3122   feature_status = format (0, "%s",
3123                            mp->feature_status ? "enabled" : "disabled");
3124   vec_add1 (gpe_status, 0);
3125   vec_add1 (feature_status, 0);
3126
3127   vat_json_init_object (&node);
3128   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
3129   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
3130
3131   vec_free (gpe_status);
3132   vec_free (feature_status);
3133
3134   vat_json_print (vam->ofp, &node);
3135   vat_json_free (&node);
3136
3137   vam->retval = ntohl (mp->retval);
3138   vam->result_ready = 1;
3139 }
3140
3141 static void
3142   vl_api_one_get_map_request_itr_rlocs_reply_t_handler
3143   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
3144 {
3145   vat_main_t *vam = &vat_main;
3146   i32 retval = ntohl (mp->retval);
3147
3148   if (retval >= 0)
3149     {
3150       print (vam->ofp, "%=20s", mp->locator_set_name);
3151     }
3152
3153   vam->retval = retval;
3154   vam->result_ready = 1;
3155 }
3156
3157 static void
3158   vl_api_one_get_map_request_itr_rlocs_reply_t_handler_json
3159   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
3160 {
3161   vat_main_t *vam = &vat_main;
3162   vat_json_node_t *node = NULL;
3163
3164   if (VAT_JSON_ARRAY != vam->json_tree.type)
3165     {
3166       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3167       vat_json_init_array (&vam->json_tree);
3168     }
3169   node = vat_json_array_add (&vam->json_tree);
3170
3171   vat_json_init_object (node);
3172   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
3173
3174   vat_json_print (vam->ofp, node);
3175   vat_json_free (node);
3176
3177   vam->retval = ntohl (mp->retval);
3178   vam->result_ready = 1;
3179 }
3180
3181 static u8 *
3182 format_lisp_map_request_mode (u8 * s, va_list * args)
3183 {
3184   u32 mode = va_arg (*args, u32);
3185
3186   switch (mode)
3187     {
3188     case 0:
3189       return format (0, "dst-only");
3190     case 1:
3191       return format (0, "src-dst");
3192     }
3193   return 0;
3194 }
3195
3196 static void
3197   vl_api_show_one_map_request_mode_reply_t_handler
3198   (vl_api_show_one_map_request_mode_reply_t * mp)
3199 {
3200   vat_main_t *vam = &vat_main;
3201   i32 retval = ntohl (mp->retval);
3202
3203   if (0 <= retval)
3204     {
3205       u32 mode = mp->mode;
3206       print (vam->ofp, "map_request_mode: %U",
3207              format_lisp_map_request_mode, mode);
3208     }
3209
3210   vam->retval = retval;
3211   vam->result_ready = 1;
3212 }
3213
3214 static void
3215   vl_api_show_one_map_request_mode_reply_t_handler_json
3216   (vl_api_show_one_map_request_mode_reply_t * mp)
3217 {
3218   vat_main_t *vam = &vat_main;
3219   vat_json_node_t node;
3220   u8 *s = 0;
3221   u32 mode;
3222
3223   mode = mp->mode;
3224   s = format (0, "%U", format_lisp_map_request_mode, mode);
3225   vec_add1 (s, 0);
3226
3227   vat_json_init_object (&node);
3228   vat_json_object_add_string_copy (&node, "map_request_mode", s);
3229   vat_json_print (vam->ofp, &node);
3230   vat_json_free (&node);
3231
3232   vec_free (s);
3233   vam->retval = ntohl (mp->retval);
3234   vam->result_ready = 1;
3235 }
3236
3237 static void
3238   vl_api_show_one_use_petr_reply_t_handler
3239   (vl_api_show_one_use_petr_reply_t * mp)
3240 {
3241   vat_main_t *vam = &vat_main;
3242   i32 retval = ntohl (mp->retval);
3243
3244   if (0 <= retval)
3245     {
3246       print (vam->ofp, "%s\n", mp->status ? "enabled" : "disabled");
3247       if (mp->status)
3248         {
3249           print (vam->ofp, "Proxy-ETR address; %U",
3250                  mp->is_ip4 ? format_ip4_address : format_ip6_address,
3251                  mp->address);
3252         }
3253     }
3254
3255   vam->retval = retval;
3256   vam->result_ready = 1;
3257 }
3258
3259 static void
3260   vl_api_show_one_use_petr_reply_t_handler_json
3261   (vl_api_show_one_use_petr_reply_t * mp)
3262 {
3263   vat_main_t *vam = &vat_main;
3264   vat_json_node_t node;
3265   u8 *status = 0;
3266   struct in_addr ip4;
3267   struct in6_addr ip6;
3268
3269   status = format (0, "%s", mp->status ? "enabled" : "disabled");
3270   vec_add1 (status, 0);
3271
3272   vat_json_init_object (&node);
3273   vat_json_object_add_string_copy (&node, "status", status);
3274   if (mp->status)
3275     {
3276       if (mp->is_ip4)
3277         {
3278           clib_memcpy (&ip6, mp->address, sizeof (ip6));
3279           vat_json_object_add_ip6 (&node, "address", ip6);
3280         }
3281       else
3282         {
3283           clib_memcpy (&ip4, mp->address, sizeof (ip4));
3284           vat_json_object_add_ip4 (&node, "address", ip4);
3285         }
3286     }
3287
3288   vec_free (status);
3289
3290   vat_json_print (vam->ofp, &node);
3291   vat_json_free (&node);
3292
3293   vam->retval = ntohl (mp->retval);
3294   vam->result_ready = 1;
3295 }
3296
3297 static void
3298 vl_api_show_one_pitr_reply_t_handler (vl_api_show_one_pitr_reply_t * mp)
3299 {
3300   vat_main_t *vam = &vat_main;
3301   i32 retval = ntohl (mp->retval);
3302
3303   if (0 <= retval)
3304     {
3305       print (vam->ofp, "%-20s%-16s",
3306              mp->status ? "enabled" : "disabled",
3307              mp->status ? (char *) mp->locator_set_name : "");
3308     }
3309
3310   vam->retval = retval;
3311   vam->result_ready = 1;
3312 }
3313
3314 static void
3315 vl_api_show_one_pitr_reply_t_handler_json (vl_api_show_one_pitr_reply_t * mp)
3316 {
3317   vat_main_t *vam = &vat_main;
3318   vat_json_node_t node;
3319   u8 *status = 0;
3320
3321   status = format (0, "%s", mp->status ? "enabled" : "disabled");
3322   vec_add1 (status, 0);
3323
3324   vat_json_init_object (&node);
3325   vat_json_object_add_string_copy (&node, "status", status);
3326   if (mp->status)
3327     {
3328       vat_json_object_add_string_copy (&node, "locator_set",
3329                                        mp->locator_set_name);
3330     }
3331
3332   vec_free (status);
3333
3334   vat_json_print (vam->ofp, &node);
3335   vat_json_free (&node);
3336
3337   vam->retval = ntohl (mp->retval);
3338   vam->result_ready = 1;
3339 }
3340
3341 static u8 *
3342 format_policer_type (u8 * s, va_list * va)
3343 {
3344   u32 i = va_arg (*va, u32);
3345
3346   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
3347     s = format (s, "1r2c");
3348   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
3349     s = format (s, "1r3c");
3350   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
3351     s = format (s, "2r3c-2698");
3352   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
3353     s = format (s, "2r3c-4115");
3354   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
3355     s = format (s, "2r3c-mef5cf1");
3356   else
3357     s = format (s, "ILLEGAL");
3358   return s;
3359 }
3360
3361 static u8 *
3362 format_policer_rate_type (u8 * s, va_list * va)
3363 {
3364   u32 i = va_arg (*va, u32);
3365
3366   if (i == SSE2_QOS_RATE_KBPS)
3367     s = format (s, "kbps");
3368   else if (i == SSE2_QOS_RATE_PPS)
3369     s = format (s, "pps");
3370   else
3371     s = format (s, "ILLEGAL");
3372   return s;
3373 }
3374
3375 static u8 *
3376 format_policer_round_type (u8 * s, va_list * va)
3377 {
3378   u32 i = va_arg (*va, u32);
3379
3380   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
3381     s = format (s, "closest");
3382   else if (i == SSE2_QOS_ROUND_TO_UP)
3383     s = format (s, "up");
3384   else if (i == SSE2_QOS_ROUND_TO_DOWN)
3385     s = format (s, "down");
3386   else
3387     s = format (s, "ILLEGAL");
3388   return s;
3389 }
3390
3391 static u8 *
3392 format_policer_action_type (u8 * s, va_list * va)
3393 {
3394   u32 i = va_arg (*va, u32);
3395
3396   if (i == SSE2_QOS_ACTION_DROP)
3397     s = format (s, "drop");
3398   else if (i == SSE2_QOS_ACTION_TRANSMIT)
3399     s = format (s, "transmit");
3400   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3401     s = format (s, "mark-and-transmit");
3402   else
3403     s = format (s, "ILLEGAL");
3404   return s;
3405 }
3406
3407 static u8 *
3408 format_dscp (u8 * s, va_list * va)
3409 {
3410   u32 i = va_arg (*va, u32);
3411   char *t = 0;
3412
3413   switch (i)
3414     {
3415 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
3416       foreach_vnet_dscp
3417 #undef _
3418     default:
3419       return format (s, "ILLEGAL");
3420     }
3421   s = format (s, "%s", t);
3422   return s;
3423 }
3424
3425 static void
3426 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
3427 {
3428   vat_main_t *vam = &vat_main;
3429   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
3430
3431   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3432     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
3433   else
3434     conform_dscp_str = format (0, "");
3435
3436   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3437     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
3438   else
3439     exceed_dscp_str = format (0, "");
3440
3441   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3442     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
3443   else
3444     violate_dscp_str = format (0, "");
3445
3446   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
3447          "rate type %U, round type %U, %s rate, %s color-aware, "
3448          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
3449          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
3450          "conform action %U%s, exceed action %U%s, violate action %U%s",
3451          mp->name,
3452          format_policer_type, mp->type,
3453          ntohl (mp->cir),
3454          ntohl (mp->eir),
3455          clib_net_to_host_u64 (mp->cb),
3456          clib_net_to_host_u64 (mp->eb),
3457          format_policer_rate_type, mp->rate_type,
3458          format_policer_round_type, mp->round_type,
3459          mp->single_rate ? "single" : "dual",
3460          mp->color_aware ? "is" : "not",
3461          ntohl (mp->cir_tokens_per_period),
3462          ntohl (mp->pir_tokens_per_period),
3463          ntohl (mp->scale),
3464          ntohl (mp->current_limit),
3465          ntohl (mp->current_bucket),
3466          ntohl (mp->extended_limit),
3467          ntohl (mp->extended_bucket),
3468          clib_net_to_host_u64 (mp->last_update_time),
3469          format_policer_action_type, mp->conform_action_type,
3470          conform_dscp_str,
3471          format_policer_action_type, mp->exceed_action_type,
3472          exceed_dscp_str,
3473          format_policer_action_type, mp->violate_action_type,
3474          violate_dscp_str);
3475
3476   vec_free (conform_dscp_str);
3477   vec_free (exceed_dscp_str);
3478   vec_free (violate_dscp_str);
3479 }
3480
3481 static void vl_api_policer_details_t_handler_json
3482   (vl_api_policer_details_t * mp)
3483 {
3484   vat_main_t *vam = &vat_main;
3485   vat_json_node_t *node;
3486   u8 *rate_type_str, *round_type_str, *type_str;
3487   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
3488
3489   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
3490   round_type_str =
3491     format (0, "%U", format_policer_round_type, mp->round_type);
3492   type_str = format (0, "%U", format_policer_type, mp->type);
3493   conform_action_str = format (0, "%U", format_policer_action_type,
3494                                mp->conform_action_type);
3495   exceed_action_str = format (0, "%U", format_policer_action_type,
3496                               mp->exceed_action_type);
3497   violate_action_str = format (0, "%U", format_policer_action_type,
3498                                mp->violate_action_type);
3499
3500   if (VAT_JSON_ARRAY != vam->json_tree.type)
3501     {
3502       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3503       vat_json_init_array (&vam->json_tree);
3504     }
3505   node = vat_json_array_add (&vam->json_tree);
3506
3507   vat_json_init_object (node);
3508   vat_json_object_add_string_copy (node, "name", mp->name);
3509   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
3510   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
3511   vat_json_object_add_uint (node, "cb", ntohl (mp->cb));
3512   vat_json_object_add_uint (node, "eb", ntohl (mp->eb));
3513   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
3514   vat_json_object_add_string_copy (node, "round_type", round_type_str);
3515   vat_json_object_add_string_copy (node, "type", type_str);
3516   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
3517   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
3518   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
3519   vat_json_object_add_uint (node, "cir_tokens_per_period",
3520                             ntohl (mp->cir_tokens_per_period));
3521   vat_json_object_add_uint (node, "eir_tokens_per_period",
3522                             ntohl (mp->pir_tokens_per_period));
3523   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
3524   vat_json_object_add_uint (node, "current_bucket",
3525                             ntohl (mp->current_bucket));
3526   vat_json_object_add_uint (node, "extended_limit",
3527                             ntohl (mp->extended_limit));
3528   vat_json_object_add_uint (node, "extended_bucket",
3529                             ntohl (mp->extended_bucket));
3530   vat_json_object_add_uint (node, "last_update_time",
3531                             ntohl (mp->last_update_time));
3532   vat_json_object_add_string_copy (node, "conform_action",
3533                                    conform_action_str);
3534   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3535     {
3536       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
3537       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
3538       vec_free (dscp_str);
3539     }
3540   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
3541   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3542     {
3543       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
3544       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
3545       vec_free (dscp_str);
3546     }
3547   vat_json_object_add_string_copy (node, "violate_action",
3548                                    violate_action_str);
3549   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3550     {
3551       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
3552       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
3553       vec_free (dscp_str);
3554     }
3555
3556   vec_free (rate_type_str);
3557   vec_free (round_type_str);
3558   vec_free (type_str);
3559   vec_free (conform_action_str);
3560   vec_free (exceed_action_str);
3561   vec_free (violate_action_str);
3562 }
3563
3564 static void
3565 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
3566                                            mp)
3567 {
3568   vat_main_t *vam = &vat_main;
3569   int i, count = ntohl (mp->count);
3570
3571   if (count > 0)
3572     print (vam->ofp, "classify table ids (%d) : ", count);
3573   for (i = 0; i < count; i++)
3574     {
3575       print (vam->ofp, "%d", ntohl (mp->ids[i]));
3576       print (vam->ofp, (i < count - 1) ? "," : "");
3577     }
3578   vam->retval = ntohl (mp->retval);
3579   vam->result_ready = 1;
3580 }
3581
3582 static void
3583   vl_api_classify_table_ids_reply_t_handler_json
3584   (vl_api_classify_table_ids_reply_t * mp)
3585 {
3586   vat_main_t *vam = &vat_main;
3587   int i, count = ntohl (mp->count);
3588
3589   if (count > 0)
3590     {
3591       vat_json_node_t node;
3592
3593       vat_json_init_object (&node);
3594       for (i = 0; i < count; i++)
3595         {
3596           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
3597         }
3598       vat_json_print (vam->ofp, &node);
3599       vat_json_free (&node);
3600     }
3601   vam->retval = ntohl (mp->retval);
3602   vam->result_ready = 1;
3603 }
3604
3605 static void
3606   vl_api_classify_table_by_interface_reply_t_handler
3607   (vl_api_classify_table_by_interface_reply_t * mp)
3608 {
3609   vat_main_t *vam = &vat_main;
3610   u32 table_id;
3611
3612   table_id = ntohl (mp->l2_table_id);
3613   if (table_id != ~0)
3614     print (vam->ofp, "l2 table id : %d", table_id);
3615   else
3616     print (vam->ofp, "l2 table id : No input ACL tables configured");
3617   table_id = ntohl (mp->ip4_table_id);
3618   if (table_id != ~0)
3619     print (vam->ofp, "ip4 table id : %d", table_id);
3620   else
3621     print (vam->ofp, "ip4 table id : No input ACL tables configured");
3622   table_id = ntohl (mp->ip6_table_id);
3623   if (table_id != ~0)
3624     print (vam->ofp, "ip6 table id : %d", table_id);
3625   else
3626     print (vam->ofp, "ip6 table id : No input ACL tables configured");
3627   vam->retval = ntohl (mp->retval);
3628   vam->result_ready = 1;
3629 }
3630
3631 static void
3632   vl_api_classify_table_by_interface_reply_t_handler_json
3633   (vl_api_classify_table_by_interface_reply_t * mp)
3634 {
3635   vat_main_t *vam = &vat_main;
3636   vat_json_node_t node;
3637
3638   vat_json_init_object (&node);
3639
3640   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
3641   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
3642   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
3643
3644   vat_json_print (vam->ofp, &node);
3645   vat_json_free (&node);
3646
3647   vam->retval = ntohl (mp->retval);
3648   vam->result_ready = 1;
3649 }
3650
3651 static void vl_api_policer_add_del_reply_t_handler
3652   (vl_api_policer_add_del_reply_t * mp)
3653 {
3654   vat_main_t *vam = &vat_main;
3655   i32 retval = ntohl (mp->retval);
3656   if (vam->async_mode)
3657     {
3658       vam->async_errors += (retval < 0);
3659     }
3660   else
3661     {
3662       vam->retval = retval;
3663       vam->result_ready = 1;
3664       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
3665         /*
3666          * Note: this is just barely thread-safe, depends on
3667          * the main thread spinning waiting for an answer...
3668          */
3669         errmsg ("policer index %d", ntohl (mp->policer_index));
3670     }
3671 }
3672
3673 static void vl_api_policer_add_del_reply_t_handler_json
3674   (vl_api_policer_add_del_reply_t * mp)
3675 {
3676   vat_main_t *vam = &vat_main;
3677   vat_json_node_t node;
3678
3679   vat_json_init_object (&node);
3680   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3681   vat_json_object_add_uint (&node, "policer_index",
3682                             ntohl (mp->policer_index));
3683
3684   vat_json_print (vam->ofp, &node);
3685   vat_json_free (&node);
3686
3687   vam->retval = ntohl (mp->retval);
3688   vam->result_ready = 1;
3689 }
3690
3691 /* Format hex dump. */
3692 u8 *
3693 format_hex_bytes (u8 * s, va_list * va)
3694 {
3695   u8 *bytes = va_arg (*va, u8 *);
3696   int n_bytes = va_arg (*va, int);
3697   uword i;
3698
3699   /* Print short or long form depending on byte count. */
3700   uword short_form = n_bytes <= 32;
3701   uword indent = format_get_indent (s);
3702
3703   if (n_bytes == 0)
3704     return s;
3705
3706   for (i = 0; i < n_bytes; i++)
3707     {
3708       if (!short_form && (i % 32) == 0)
3709         s = format (s, "%08x: ", i);
3710       s = format (s, "%02x", bytes[i]);
3711       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
3712         s = format (s, "\n%U", format_white_space, indent);
3713     }
3714
3715   return s;
3716 }
3717
3718 static void
3719 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
3720                                             * mp)
3721 {
3722   vat_main_t *vam = &vat_main;
3723   i32 retval = ntohl (mp->retval);
3724   if (retval == 0)
3725     {
3726       print (vam->ofp, "classify table info :");
3727       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
3728              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
3729              ntohl (mp->miss_next_index));
3730       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
3731              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
3732              ntohl (mp->match_n_vectors));
3733       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
3734              ntohl (mp->mask_length));
3735     }
3736   vam->retval = retval;
3737   vam->result_ready = 1;
3738 }
3739
3740 static void
3741   vl_api_classify_table_info_reply_t_handler_json
3742   (vl_api_classify_table_info_reply_t * mp)
3743 {
3744   vat_main_t *vam = &vat_main;
3745   vat_json_node_t node;
3746
3747   i32 retval = ntohl (mp->retval);
3748   if (retval == 0)
3749     {
3750       vat_json_init_object (&node);
3751
3752       vat_json_object_add_int (&node, "sessions",
3753                                ntohl (mp->active_sessions));
3754       vat_json_object_add_int (&node, "nexttbl",
3755                                ntohl (mp->next_table_index));
3756       vat_json_object_add_int (&node, "nextnode",
3757                                ntohl (mp->miss_next_index));
3758       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
3759       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
3760       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
3761       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
3762                       ntohl (mp->mask_length), 0);
3763       vat_json_object_add_string_copy (&node, "mask", s);
3764
3765       vat_json_print (vam->ofp, &node);
3766       vat_json_free (&node);
3767     }
3768   vam->retval = ntohl (mp->retval);
3769   vam->result_ready = 1;
3770 }
3771
3772 static void
3773 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
3774                                            mp)
3775 {
3776   vat_main_t *vam = &vat_main;
3777
3778   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
3779          ntohl (mp->hit_next_index), ntohl (mp->advance),
3780          ntohl (mp->opaque_index));
3781   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
3782          ntohl (mp->match_length));
3783 }
3784
3785 static void
3786   vl_api_classify_session_details_t_handler_json
3787   (vl_api_classify_session_details_t * mp)
3788 {
3789   vat_main_t *vam = &vat_main;
3790   vat_json_node_t *node = NULL;
3791
3792   if (VAT_JSON_ARRAY != vam->json_tree.type)
3793     {
3794       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3795       vat_json_init_array (&vam->json_tree);
3796     }
3797   node = vat_json_array_add (&vam->json_tree);
3798
3799   vat_json_init_object (node);
3800   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
3801   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
3802   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
3803   u8 *s =
3804     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
3805             0);
3806   vat_json_object_add_string_copy (node, "match", s);
3807 }
3808
3809 static void vl_api_pg_create_interface_reply_t_handler
3810   (vl_api_pg_create_interface_reply_t * mp)
3811 {
3812   vat_main_t *vam = &vat_main;
3813
3814   vam->retval = ntohl (mp->retval);
3815   vam->result_ready = 1;
3816 }
3817
3818 static void vl_api_pg_create_interface_reply_t_handler_json
3819   (vl_api_pg_create_interface_reply_t * mp)
3820 {
3821   vat_main_t *vam = &vat_main;
3822   vat_json_node_t node;
3823
3824   i32 retval = ntohl (mp->retval);
3825   if (retval == 0)
3826     {
3827       vat_json_init_object (&node);
3828
3829       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
3830
3831       vat_json_print (vam->ofp, &node);
3832       vat_json_free (&node);
3833     }
3834   vam->retval = ntohl (mp->retval);
3835   vam->result_ready = 1;
3836 }
3837
3838 static void vl_api_policer_classify_details_t_handler
3839   (vl_api_policer_classify_details_t * mp)
3840 {
3841   vat_main_t *vam = &vat_main;
3842
3843   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
3844          ntohl (mp->table_index));
3845 }
3846
3847 static void vl_api_policer_classify_details_t_handler_json
3848   (vl_api_policer_classify_details_t * mp)
3849 {
3850   vat_main_t *vam = &vat_main;
3851   vat_json_node_t *node;
3852
3853   if (VAT_JSON_ARRAY != vam->json_tree.type)
3854     {
3855       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3856       vat_json_init_array (&vam->json_tree);
3857     }
3858   node = vat_json_array_add (&vam->json_tree);
3859
3860   vat_json_init_object (node);
3861   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
3862   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
3863 }
3864
3865 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler
3866   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
3867 {
3868   vat_main_t *vam = &vat_main;
3869   i32 retval = ntohl (mp->retval);
3870   if (vam->async_mode)
3871     {
3872       vam->async_errors += (retval < 0);
3873     }
3874   else
3875     {
3876       vam->retval = retval;
3877       vam->sw_if_index = ntohl (mp->sw_if_index);
3878       vam->result_ready = 1;
3879     }
3880 }
3881
3882 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler_json
3883   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
3884 {
3885   vat_main_t *vam = &vat_main;
3886   vat_json_node_t node;
3887
3888   vat_json_init_object (&node);
3889   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3890   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
3891
3892   vat_json_print (vam->ofp, &node);
3893   vat_json_free (&node);
3894
3895   vam->retval = ntohl (mp->retval);
3896   vam->result_ready = 1;
3897 }
3898
3899 static void vl_api_flow_classify_details_t_handler
3900   (vl_api_flow_classify_details_t * mp)
3901 {
3902   vat_main_t *vam = &vat_main;
3903
3904   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
3905          ntohl (mp->table_index));
3906 }
3907
3908 static void vl_api_flow_classify_details_t_handler_json
3909   (vl_api_flow_classify_details_t * mp)
3910 {
3911   vat_main_t *vam = &vat_main;
3912   vat_json_node_t *node;
3913
3914   if (VAT_JSON_ARRAY != vam->json_tree.type)
3915     {
3916       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3917       vat_json_init_array (&vam->json_tree);
3918     }
3919   node = vat_json_array_add (&vam->json_tree);
3920
3921   vat_json_init_object (node);
3922   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
3923   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
3924 }
3925
3926
3927
3928 #define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
3929 #define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler
3930 #define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler
3931 #define vl_api_vnet_ip6_fib_counters_t_print vl_noop_handler
3932 #define vl_api_vnet_ip4_nbr_counters_t_endian vl_noop_handler
3933 #define vl_api_vnet_ip4_nbr_counters_t_print vl_noop_handler
3934 #define vl_api_vnet_ip6_nbr_counters_t_endian vl_noop_handler
3935 #define vl_api_vnet_ip6_nbr_counters_t_print vl_noop_handler
3936 #define vl_api_one_adjacencies_get_reply_t_endian vl_noop_handler
3937 #define vl_api_one_adjacencies_get_reply_t_print vl_noop_handler
3938
3939 /*
3940  * Generate boilerplate reply handlers, which
3941  * dig the return value out of the xxx_reply_t API message,
3942  * stick it into vam->retval, and set vam->result_ready
3943  *
3944  * Could also do this by pointing N message decode slots at
3945  * a single function, but that could break in subtle ways.
3946  */
3947
3948 #define foreach_standard_reply_retval_handler           \
3949 _(sw_interface_set_flags_reply)                         \
3950 _(sw_interface_add_del_address_reply)                   \
3951 _(sw_interface_set_table_reply)                         \
3952 _(sw_interface_set_mpls_enable_reply)                   \
3953 _(sw_interface_set_vpath_reply)                         \
3954 _(sw_interface_set_vxlan_bypass_reply)                  \
3955 _(sw_interface_set_l2_bridge_reply)                     \
3956 _(bridge_domain_add_del_reply)                          \
3957 _(sw_interface_set_l2_xconnect_reply)                   \
3958 _(l2fib_add_del_reply)                                  \
3959 _(ip_add_del_route_reply)                               \
3960 _(ip_mroute_add_del_reply)                              \
3961 _(mpls_route_add_del_reply)                             \
3962 _(mpls_ip_bind_unbind_reply)                            \
3963 _(proxy_arp_add_del_reply)                              \
3964 _(proxy_arp_intfc_enable_disable_reply)                 \
3965 _(sw_interface_set_unnumbered_reply)                    \
3966 _(ip_neighbor_add_del_reply)                            \
3967 _(reset_vrf_reply)                                      \
3968 _(oam_add_del_reply)                                    \
3969 _(reset_fib_reply)                                      \
3970 _(dhcp_proxy_config_reply)                              \
3971 _(dhcp_proxy_set_vss_reply)                             \
3972 _(dhcp_client_config_reply)                             \
3973 _(set_ip_flow_hash_reply)                               \
3974 _(sw_interface_ip6_enable_disable_reply)                \
3975 _(sw_interface_ip6_set_link_local_address_reply)        \
3976 _(ip6nd_proxy_add_del_reply)                            \
3977 _(sw_interface_ip6nd_ra_prefix_reply)                   \
3978 _(sw_interface_ip6nd_ra_config_reply)                   \
3979 _(set_arp_neighbor_limit_reply)                         \
3980 _(l2_patch_add_del_reply)                               \
3981 _(sr_policy_add_reply)                                  \
3982 _(sr_policy_mod_reply)                                  \
3983 _(sr_policy_del_reply)                                  \
3984 _(sr_localsid_add_del_reply)                            \
3985 _(sr_steering_add_del_reply)                            \
3986 _(classify_add_del_session_reply)                       \
3987 _(classify_set_interface_ip_table_reply)                \
3988 _(classify_set_interface_l2_tables_reply)               \
3989 _(l2tpv3_set_tunnel_cookies_reply)                      \
3990 _(l2tpv3_interface_enable_disable_reply)                \
3991 _(l2tpv3_set_lookup_key_reply)                          \
3992 _(l2_fib_clear_table_reply)                             \
3993 _(l2_interface_efp_filter_reply)                        \
3994 _(l2_interface_vlan_tag_rewrite_reply)                  \
3995 _(modify_vhost_user_if_reply)                           \
3996 _(delete_vhost_user_if_reply)                           \
3997 _(want_ip4_arp_events_reply)                            \
3998 _(want_ip6_nd_events_reply)                             \
3999 _(input_acl_set_interface_reply)                        \
4000 _(ipsec_spd_add_del_reply)                              \
4001 _(ipsec_interface_add_del_spd_reply)                    \
4002 _(ipsec_spd_add_del_entry_reply)                        \
4003 _(ipsec_sad_add_del_entry_reply)                        \
4004 _(ipsec_sa_set_key_reply)                               \
4005 _(ikev2_profile_add_del_reply)                          \
4006 _(ikev2_profile_set_auth_reply)                         \
4007 _(ikev2_profile_set_id_reply)                           \
4008 _(ikev2_profile_set_ts_reply)                           \
4009 _(ikev2_set_local_key_reply)                            \
4010 _(ikev2_set_responder_reply)                            \
4011 _(ikev2_set_ike_transforms_reply)                       \
4012 _(ikev2_set_esp_transforms_reply)                       \
4013 _(ikev2_set_sa_lifetime_reply)                          \
4014 _(ikev2_initiate_sa_init_reply)                         \
4015 _(ikev2_initiate_del_ike_sa_reply)                      \
4016 _(ikev2_initiate_del_child_sa_reply)                    \
4017 _(ikev2_initiate_rekey_child_sa_reply)                  \
4018 _(delete_loopback_reply)                                \
4019 _(bd_ip_mac_add_del_reply)                              \
4020 _(map_del_domain_reply)                                 \
4021 _(map_add_del_rule_reply)                               \
4022 _(want_interface_events_reply)                          \
4023 _(want_stats_reply)                                     \
4024 _(cop_interface_enable_disable_reply)                   \
4025 _(cop_whitelist_enable_disable_reply)                   \
4026 _(sw_interface_clear_stats_reply)                       \
4027 _(ioam_enable_reply)                              \
4028 _(ioam_disable_reply)                              \
4029 _(one_add_del_locator_reply)                            \
4030 _(one_add_del_local_eid_reply)                          \
4031 _(one_add_del_remote_mapping_reply)                     \
4032 _(one_add_del_adjacency_reply)                          \
4033 _(one_add_del_map_resolver_reply)                       \
4034 _(one_add_del_map_server_reply)                         \
4035 _(one_enable_disable_reply)                             \
4036 _(one_rloc_probe_enable_disable_reply)                  \
4037 _(one_map_register_enable_disable_reply)                \
4038 _(one_pitr_set_locator_set_reply)                       \
4039 _(one_map_request_mode_reply)                           \
4040 _(one_add_del_map_request_itr_rlocs_reply)              \
4041 _(one_eid_table_add_del_map_reply)                      \
4042 _(one_use_petr_reply)                                   \
4043 _(gpe_add_del_fwd_entry_reply)                          \
4044 _(gpe_enable_disable_reply)                             \
4045 _(gpe_set_encap_mode_reply)                             \
4046 _(gpe_add_del_iface_reply)                              \
4047 _(vxlan_gpe_add_del_tunnel_reply)                       \
4048 _(af_packet_delete_reply)                               \
4049 _(policer_classify_set_interface_reply)                 \
4050 _(netmap_create_reply)                                  \
4051 _(netmap_delete_reply)                                  \
4052 _(set_ipfix_exporter_reply)                             \
4053 _(set_ipfix_classify_stream_reply)                      \
4054 _(ipfix_classify_table_add_del_reply)                   \
4055 _(flow_classify_set_interface_reply)                    \
4056 _(sw_interface_span_enable_disable_reply)               \
4057 _(pg_capture_reply)                                     \
4058 _(pg_enable_disable_reply)                              \
4059 _(ip_source_and_port_range_check_add_del_reply)         \
4060 _(ip_source_and_port_range_check_interface_add_del_reply)\
4061 _(delete_subif_reply)                                   \
4062 _(l2_interface_pbb_tag_rewrite_reply)                   \
4063 _(punt_reply)                                           \
4064 _(feature_enable_disable_reply)                         \
4065 _(sw_interface_tag_add_del_reply)                       \
4066 _(sw_interface_set_mtu_reply)
4067
4068 #define _(n)                                    \
4069     static void vl_api_##n##_t_handler          \
4070     (vl_api_##n##_t * mp)                       \
4071     {                                           \
4072         vat_main_t * vam = &vat_main;           \
4073         i32 retval = ntohl(mp->retval);         \
4074         if (vam->async_mode) {                  \
4075             vam->async_errors += (retval < 0);  \
4076         } else {                                \
4077             vam->retval = retval;               \
4078             vam->result_ready = 1;              \
4079         }                                       \
4080     }
4081 foreach_standard_reply_retval_handler;
4082 #undef _
4083
4084 #define _(n)                                    \
4085     static void vl_api_##n##_t_handler_json     \
4086     (vl_api_##n##_t * mp)                       \
4087     {                                           \
4088         vat_main_t * vam = &vat_main;           \
4089         vat_json_node_t node;                   \
4090         vat_json_init_object(&node);            \
4091         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
4092         vat_json_print(vam->ofp, &node);        \
4093         vam->retval = ntohl(mp->retval);        \
4094         vam->result_ready = 1;                  \
4095     }
4096 foreach_standard_reply_retval_handler;
4097 #undef _
4098
4099 /*
4100  * Table of message reply handlers, must include boilerplate handlers
4101  * we just generated
4102  */
4103
4104 #define foreach_vpe_api_reply_msg                                       \
4105 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
4106 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
4107 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
4108 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
4109 _(CONTROL_PING_REPLY, control_ping_reply)                               \
4110 _(CLI_REPLY, cli_reply)                                                 \
4111 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
4112 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
4113   sw_interface_add_del_address_reply)                                   \
4114 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
4115 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
4116 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
4117 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
4118 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
4119   sw_interface_set_l2_xconnect_reply)                                   \
4120 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
4121   sw_interface_set_l2_bridge_reply)                                     \
4122 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
4123 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
4124 _(BRIDGE_DOMAIN_SW_IF_DETAILS, bridge_domain_sw_if_details)             \
4125 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
4126 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
4127 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
4128 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
4129 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
4130 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
4131 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
4132 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
4133 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
4134 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
4135 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
4136 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
4137 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
4138   proxy_arp_intfc_enable_disable_reply)                                 \
4139 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
4140 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
4141   sw_interface_set_unnumbered_reply)                                    \
4142 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
4143 _(RESET_VRF_REPLY, reset_vrf_reply)                                     \
4144 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
4145 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
4146 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
4147 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
4148 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
4149 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
4150 _(DHCP_PROXY_DETAILS, dhcp_proxy_details)                               \
4151 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
4152 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
4153 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
4154   sw_interface_ip6_enable_disable_reply)                                \
4155 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY,                        \
4156   sw_interface_ip6_set_link_local_address_reply)                        \
4157 _(IP6ND_PROXY_ADD_DEL_REPLY, ip6nd_proxy_add_del_reply)                 \
4158 _(IP6ND_PROXY_DETAILS, ip6nd_proxy_details)                             \
4159 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
4160   sw_interface_ip6nd_ra_prefix_reply)                                   \
4161 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
4162   sw_interface_ip6nd_ra_config_reply)                                   \
4163 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
4164 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
4165 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
4166 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
4167 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
4168 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
4169 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
4170 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
4171 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
4172 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
4173 classify_set_interface_ip_table_reply)                                  \
4174 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
4175   classify_set_interface_l2_tables_reply)                               \
4176 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
4177 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
4178 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
4179 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
4180 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
4181   l2tpv3_interface_enable_disable_reply)                                \
4182 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
4183 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
4184 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
4185 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
4186 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
4187 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
4188 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
4189 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
4190 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
4191 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
4192 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
4193 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
4194 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
4195 _(SHOW_VERSION_REPLY, show_version_reply)                               \
4196 _(L2_FIB_TABLE_ENTRY, l2_fib_table_entry)                               \
4197 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)           \
4198 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
4199 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
4200 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
4201 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
4202 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
4203 _(IP6_ND_EVENT, ip6_nd_event)                                           \
4204 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
4205 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
4206 _(IP_DETAILS, ip_details)                                               \
4207 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
4208 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
4209 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
4210 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
4211 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
4212 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
4213 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
4214 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
4215 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
4216 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
4217 _(IKEV2_SET_RESPONDER_REPLY, ikev2_set_responder_reply)                 \
4218 _(IKEV2_SET_IKE_TRANSFORMS_REPLY, ikev2_set_ike_transforms_reply)       \
4219 _(IKEV2_SET_ESP_TRANSFORMS_REPLY, ikev2_set_esp_transforms_reply)       \
4220 _(IKEV2_SET_SA_LIFETIME_REPLY, ikev2_set_sa_lifetime_reply)             \
4221 _(IKEV2_INITIATE_SA_INIT_REPLY, ikev2_initiate_sa_init_reply)           \
4222 _(IKEV2_INITIATE_DEL_IKE_SA_REPLY, ikev2_initiate_del_ike_sa_reply)     \
4223 _(IKEV2_INITIATE_DEL_CHILD_SA_REPLY, ikev2_initiate_del_child_sa_reply) \
4224 _(IKEV2_INITIATE_REKEY_CHILD_SA_REPLY, ikev2_initiate_rekey_child_sa_reply) \
4225 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
4226 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
4227 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
4228 _(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply)                           \
4229 _(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply)                           \
4230 _(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply)                       \
4231 _(MAP_DOMAIN_DETAILS, map_domain_details)                               \
4232 _(MAP_RULE_DETAILS, map_rule_details)                                   \
4233 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
4234 _(WANT_STATS_REPLY, want_stats_reply)                                   \
4235 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
4236 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
4237 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
4238 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
4239 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
4240 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
4241 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
4242 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
4243 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
4244 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
4245 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
4246 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
4247 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
4248 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
4249 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
4250 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
4251   one_map_register_enable_disable_reply)                                \
4252 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
4253   one_rloc_probe_enable_disable_reply)                                  \
4254 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
4255 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
4256 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
4257 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
4258 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
4259 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
4260 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
4261 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
4262 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
4263 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
4264 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
4265 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
4266 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
4267 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
4268 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
4269 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
4270 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
4271 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
4272 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
4273   gpe_fwd_entry_path_details)                                           \
4274 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
4275 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
4276   one_add_del_map_request_itr_rlocs_reply)                              \
4277 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
4278   one_get_map_request_itr_rlocs_reply)                                  \
4279 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
4280 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
4281 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
4282 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
4283 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
4284   show_one_map_register_state_reply)                                    \
4285 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
4286 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
4287 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
4288 _(POLICER_DETAILS, policer_details)                                     \
4289 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
4290 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
4291 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
4292 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
4293 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
4294 _(MPLS_FIB_DETAILS, mpls_fib_details)                                   \
4295 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
4296 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
4297 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
4298 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
4299 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
4300 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
4301 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
4302 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
4303 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
4304 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
4305 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
4306 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
4307 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
4308 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
4309 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
4310 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
4311 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
4312 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
4313 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
4314  ip_source_and_port_range_check_add_del_reply)                          \
4315 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
4316  ip_source_and_port_range_check_interface_add_del_reply)                \
4317 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
4318 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
4319 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
4320 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
4321 _(PUNT_REPLY, punt_reply)                                               \
4322 _(IP_FIB_DETAILS, ip_fib_details)                                       \
4323 _(IP6_FIB_DETAILS, ip6_fib_details)                                     \
4324 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
4325 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
4326 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
4327 _(SW_INTERFACE_SET_MTU_REPLY, sw_interface_set_mtu_reply)               \
4328 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
4329 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)
4330
4331 #define foreach_standalone_reply_msg                                    \
4332 _(SW_INTERFACE_SET_FLAGS, sw_interface_set_flags)                       \
4333 _(VNET_INTERFACE_COUNTERS, vnet_interface_counters)                     \
4334 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
4335 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
4336 _(VNET_IP4_NBR_COUNTERS, vnet_ip4_nbr_counters)                         \
4337 _(VNET_IP6_NBR_COUNTERS, vnet_ip6_nbr_counters)
4338
4339 typedef struct
4340 {
4341   u8 *name;
4342   u32 value;
4343 } name_sort_t;
4344
4345
4346 #define STR_VTR_OP_CASE(op)     \
4347     case L2_VTR_ ## op:         \
4348         return "" # op;
4349
4350 static const char *
4351 str_vtr_op (u32 vtr_op)
4352 {
4353   switch (vtr_op)
4354     {
4355       STR_VTR_OP_CASE (DISABLED);
4356       STR_VTR_OP_CASE (PUSH_1);
4357       STR_VTR_OP_CASE (PUSH_2);
4358       STR_VTR_OP_CASE (POP_1);
4359       STR_VTR_OP_CASE (POP_2);
4360       STR_VTR_OP_CASE (TRANSLATE_1_1);
4361       STR_VTR_OP_CASE (TRANSLATE_1_2);
4362       STR_VTR_OP_CASE (TRANSLATE_2_1);
4363       STR_VTR_OP_CASE (TRANSLATE_2_2);
4364     }
4365
4366   return "UNKNOWN";
4367 }
4368
4369 static int
4370 dump_sub_interface_table (vat_main_t * vam)
4371 {
4372   const sw_interface_subif_t *sub = NULL;
4373
4374   if (vam->json_output)
4375     {
4376       clib_warning
4377         ("JSON output supported only for VPE API calls and dump_stats_table");
4378       return -99;
4379     }
4380
4381   print (vam->ofp,
4382          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
4383          "Interface", "sw_if_index",
4384          "sub id", "dot1ad", "tags", "outer id",
4385          "inner id", "exact", "default", "outer any", "inner any");
4386
4387   vec_foreach (sub, vam->sw_if_subif_table)
4388   {
4389     print (vam->ofp,
4390            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
4391            sub->interface_name,
4392            sub->sw_if_index,
4393            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
4394            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
4395            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
4396            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
4397     if (sub->vtr_op != L2_VTR_DISABLED)
4398       {
4399         print (vam->ofp,
4400                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
4401                "tag1: %d tag2: %d ]",
4402                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
4403                sub->vtr_tag1, sub->vtr_tag2);
4404       }
4405   }
4406
4407   return 0;
4408 }
4409
4410 static int
4411 name_sort_cmp (void *a1, void *a2)
4412 {
4413   name_sort_t *n1 = a1;
4414   name_sort_t *n2 = a2;
4415
4416   return strcmp ((char *) n1->name, (char *) n2->name);
4417 }
4418
4419 static int
4420 dump_interface_table (vat_main_t * vam)
4421 {
4422   hash_pair_t *p;
4423   name_sort_t *nses = 0, *ns;
4424
4425   if (vam->json_output)
4426     {
4427       clib_warning
4428         ("JSON output supported only for VPE API calls and dump_stats_table");
4429       return -99;
4430     }
4431
4432   /* *INDENT-OFF* */
4433   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
4434   ({
4435     vec_add2 (nses, ns, 1);
4436     ns->name = (u8 *)(p->key);
4437     ns->value = (u32) p->value[0];
4438   }));
4439   /* *INDENT-ON* */
4440
4441   vec_sort_with_function (nses, name_sort_cmp);
4442
4443   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
4444   vec_foreach (ns, nses)
4445   {
4446     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
4447   }
4448   vec_free (nses);
4449   return 0;
4450 }
4451
4452 static int
4453 dump_ip_table (vat_main_t * vam, int is_ipv6)
4454 {
4455   const ip_details_t *det = NULL;
4456   const ip_address_details_t *address = NULL;
4457   u32 i = ~0;
4458
4459   print (vam->ofp, "%-12s", "sw_if_index");
4460
4461   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
4462   {
4463     i++;
4464     if (!det->present)
4465       {
4466         continue;
4467       }
4468     print (vam->ofp, "%-12d", i);
4469     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
4470     if (!det->addr)
4471       {
4472         continue;
4473       }
4474     vec_foreach (address, det->addr)
4475     {
4476       print (vam->ofp,
4477              "            %-30U%-13d",
4478              is_ipv6 ? format_ip6_address : format_ip4_address,
4479              address->ip, address->prefix_length);
4480     }
4481   }
4482
4483   return 0;
4484 }
4485
4486 static int
4487 dump_ipv4_table (vat_main_t * vam)
4488 {
4489   if (vam->json_output)
4490     {
4491       clib_warning
4492         ("JSON output supported only for VPE API calls and dump_stats_table");
4493       return -99;
4494     }
4495
4496   return dump_ip_table (vam, 0);
4497 }
4498
4499 static int
4500 dump_ipv6_table (vat_main_t * vam)
4501 {
4502   if (vam->json_output)
4503     {
4504       clib_warning
4505         ("JSON output supported only for VPE API calls and dump_stats_table");
4506       return -99;
4507     }
4508
4509   return dump_ip_table (vam, 1);
4510 }
4511
4512 static char *
4513 counter_type_to_str (u8 counter_type, u8 is_combined)
4514 {
4515   if (!is_combined)
4516     {
4517       switch (counter_type)
4518         {
4519         case VNET_INTERFACE_COUNTER_DROP:
4520           return "drop";
4521         case VNET_INTERFACE_COUNTER_PUNT:
4522           return "punt";
4523         case VNET_INTERFACE_COUNTER_IP4:
4524           return "ip4";
4525         case VNET_INTERFACE_COUNTER_IP6:
4526           return "ip6";
4527         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
4528           return "rx-no-buf";
4529         case VNET_INTERFACE_COUNTER_RX_MISS:
4530           return "rx-miss";
4531         case VNET_INTERFACE_COUNTER_RX_ERROR:
4532           return "rx-error";
4533         case VNET_INTERFACE_COUNTER_TX_ERROR:
4534           return "tx-error";
4535         default:
4536           return "INVALID-COUNTER-TYPE";
4537         }
4538     }
4539   else
4540     {
4541       switch (counter_type)
4542         {
4543         case VNET_INTERFACE_COUNTER_RX:
4544           return "rx";
4545         case VNET_INTERFACE_COUNTER_TX:
4546           return "tx";
4547         default:
4548           return "INVALID-COUNTER-TYPE";
4549         }
4550     }
4551 }
4552
4553 static int
4554 dump_stats_table (vat_main_t * vam)
4555 {
4556   vat_json_node_t node;
4557   vat_json_node_t *msg_array;
4558   vat_json_node_t *msg;
4559   vat_json_node_t *counter_array;
4560   vat_json_node_t *counter;
4561   interface_counter_t c;
4562   u64 packets;
4563   ip4_fib_counter_t *c4;
4564   ip6_fib_counter_t *c6;
4565   ip4_nbr_counter_t *n4;
4566   ip6_nbr_counter_t *n6;
4567   int i, j;
4568
4569   if (!vam->json_output)
4570     {
4571       clib_warning ("dump_stats_table supported only in JSON format");
4572       return -99;
4573     }
4574
4575   vat_json_init_object (&node);
4576
4577   /* interface counters */
4578   msg_array = vat_json_object_add (&node, "interface_counters");
4579   vat_json_init_array (msg_array);
4580   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
4581     {
4582       msg = vat_json_array_add (msg_array);
4583       vat_json_init_object (msg);
4584       vat_json_object_add_string_copy (msg, "vnet_counter_type",
4585                                        (u8 *) counter_type_to_str (i, 0));
4586       vat_json_object_add_int (msg, "is_combined", 0);
4587       counter_array = vat_json_object_add (msg, "data");
4588       vat_json_init_array (counter_array);
4589       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
4590         {
4591           packets = vam->simple_interface_counters[i][j];
4592           vat_json_array_add_uint (counter_array, packets);
4593         }
4594     }
4595   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
4596     {
4597       msg = vat_json_array_add (msg_array);
4598       vat_json_init_object (msg);
4599       vat_json_object_add_string_copy (msg, "vnet_counter_type",
4600                                        (u8 *) counter_type_to_str (i, 1));
4601       vat_json_object_add_int (msg, "is_combined", 1);
4602       counter_array = vat_json_object_add (msg, "data");
4603       vat_json_init_array (counter_array);
4604       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
4605         {
4606           c = vam->combined_interface_counters[i][j];
4607           counter = vat_json_array_add (counter_array);
4608           vat_json_init_object (counter);
4609           vat_json_object_add_uint (counter, "packets", c.packets);
4610           vat_json_object_add_uint (counter, "bytes", c.bytes);
4611         }
4612     }
4613
4614   /* ip4 fib counters */
4615   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
4616   vat_json_init_array (msg_array);
4617   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
4618     {
4619       msg = vat_json_array_add (msg_array);
4620       vat_json_init_object (msg);
4621       vat_json_object_add_uint (msg, "vrf_id",
4622                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
4623       counter_array = vat_json_object_add (msg, "c");
4624       vat_json_init_array (counter_array);
4625       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
4626         {
4627           counter = vat_json_array_add (counter_array);
4628           vat_json_init_object (counter);
4629           c4 = &vam->ip4_fib_counters[i][j];
4630           vat_json_object_add_ip4 (counter, "address", c4->address);
4631           vat_json_object_add_uint (counter, "address_length",
4632                                     c4->address_length);
4633           vat_json_object_add_uint (counter, "packets", c4->packets);
4634           vat_json_object_add_uint (counter, "bytes", c4->bytes);
4635         }
4636     }
4637
4638   /* ip6 fib counters */
4639   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
4640   vat_json_init_array (msg_array);
4641   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
4642     {
4643       msg = vat_json_array_add (msg_array);
4644       vat_json_init_object (msg);
4645       vat_json_object_add_uint (msg, "vrf_id",
4646                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
4647       counter_array = vat_json_object_add (msg, "c");
4648       vat_json_init_array (counter_array);
4649       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
4650         {
4651           counter = vat_json_array_add (counter_array);
4652           vat_json_init_object (counter);
4653           c6 = &vam->ip6_fib_counters[i][j];
4654           vat_json_object_add_ip6 (counter, "address", c6->address);
4655           vat_json_object_add_uint (counter, "address_length",
4656                                     c6->address_length);
4657           vat_json_object_add_uint (counter, "packets", c6->packets);
4658           vat_json_object_add_uint (counter, "bytes", c6->bytes);
4659         }
4660     }
4661
4662   /* ip4 nbr counters */
4663   msg_array = vat_json_object_add (&node, "ip4_nbr_counters");
4664   vat_json_init_array (msg_array);
4665   for (i = 0; i < vec_len (vam->ip4_nbr_counters); i++)
4666     {
4667       msg = vat_json_array_add (msg_array);
4668       vat_json_init_object (msg);
4669       vat_json_object_add_uint (msg, "sw_if_index", i);
4670       counter_array = vat_json_object_add (msg, "c");
4671       vat_json_init_array (counter_array);
4672       for (j = 0; j < vec_len (vam->ip4_nbr_counters[i]); j++)
4673         {
4674           counter = vat_json_array_add (counter_array);
4675           vat_json_init_object (counter);
4676           n4 = &vam->ip4_nbr_counters[i][j];
4677           vat_json_object_add_ip4 (counter, "address", n4->address);
4678           vat_json_object_add_uint (counter, "link-type", n4->linkt);
4679           vat_json_object_add_uint (counter, "packets", n4->packets);
4680           vat_json_object_add_uint (counter, "bytes", n4->bytes);
4681         }
4682     }
4683
4684   /* ip6 nbr counters */
4685   msg_array = vat_json_object_add (&node, "ip6_nbr_counters");
4686   vat_json_init_array (msg_array);
4687   for (i = 0; i < vec_len (vam->ip6_nbr_counters); i++)
4688     {
4689       msg = vat_json_array_add (msg_array);
4690       vat_json_init_object (msg);
4691       vat_json_object_add_uint (msg, "sw_if_index", i);
4692       counter_array = vat_json_object_add (msg, "c");
4693       vat_json_init_array (counter_array);
4694       for (j = 0; j < vec_len (vam->ip6_nbr_counters[i]); j++)
4695         {
4696           counter = vat_json_array_add (counter_array);
4697           vat_json_init_object (counter);
4698           n6 = &vam->ip6_nbr_counters[i][j];
4699           vat_json_object_add_ip6 (counter, "address", n6->address);
4700           vat_json_object_add_uint (counter, "packets", n6->packets);
4701           vat_json_object_add_uint (counter, "bytes", n6->bytes);
4702         }
4703     }
4704
4705   vat_json_print (vam->ofp, &node);
4706   vat_json_free (&node);
4707
4708   return 0;
4709 }
4710
4711 int
4712 exec (vat_main_t * vam)
4713 {
4714   api_main_t *am = &api_main;
4715   vl_api_cli_request_t *mp;
4716   f64 timeout;
4717   void *oldheap;
4718   u8 *cmd = 0;
4719   unformat_input_t *i = vam->input;
4720
4721   if (vec_len (i->buffer) == 0)
4722     return -1;
4723
4724   if (vam->exec_mode == 0 && unformat (i, "mode"))
4725     {
4726       vam->exec_mode = 1;
4727       return 0;
4728     }
4729   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4730     {
4731       vam->exec_mode = 0;
4732       return 0;
4733     }
4734
4735
4736   M (CLI_REQUEST, mp);
4737
4738   /*
4739    * Copy cmd into shared memory.
4740    * In order for the CLI command to work, it
4741    * must be a vector ending in \n, not a C-string ending
4742    * in \n\0.
4743    */
4744   pthread_mutex_lock (&am->vlib_rp->mutex);
4745   oldheap = svm_push_data_heap (am->vlib_rp);
4746
4747   vec_validate (cmd, vec_len (vam->input->buffer) - 1);
4748   clib_memcpy (cmd, vam->input->buffer, vec_len (vam->input->buffer));
4749
4750   svm_pop_heap (oldheap);
4751   pthread_mutex_unlock (&am->vlib_rp->mutex);
4752
4753   mp->cmd_in_shmem = (u64) cmd;
4754   S (mp);
4755   timeout = vat_time_now (vam) + 10.0;
4756
4757   while (vat_time_now (vam) < timeout)
4758     {
4759       if (vam->result_ready == 1)
4760         {
4761           u8 *free_me;
4762           if (vam->shmem_result != NULL)
4763             print (vam->ofp, "%s", vam->shmem_result);
4764           pthread_mutex_lock (&am->vlib_rp->mutex);
4765           oldheap = svm_push_data_heap (am->vlib_rp);
4766
4767           free_me = (u8 *) vam->shmem_result;
4768           vec_free (free_me);
4769
4770           svm_pop_heap (oldheap);
4771           pthread_mutex_unlock (&am->vlib_rp->mutex);
4772           return 0;
4773         }
4774     }
4775   return -99;
4776 }
4777
4778 /*
4779  * Future replacement of exec() that passes CLI buffers directly in
4780  * the API messages instead of an additional shared memory area.
4781  */
4782 static int
4783 exec_inband (vat_main_t * vam)
4784 {
4785   vl_api_cli_inband_t *mp;
4786   unformat_input_t *i = vam->input;
4787   int ret;
4788
4789   if (vec_len (i->buffer) == 0)
4790     return -1;
4791
4792   if (vam->exec_mode == 0 && unformat (i, "mode"))
4793     {
4794       vam->exec_mode = 1;
4795       return 0;
4796     }
4797   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4798     {
4799       vam->exec_mode = 0;
4800       return 0;
4801     }
4802
4803   /*
4804    * In order for the CLI command to work, it
4805    * must be a vector ending in \n, not a C-string ending
4806    * in \n\0.
4807    */
4808   u32 len = vec_len (vam->input->buffer);
4809   M2 (CLI_INBAND, mp, len);
4810   clib_memcpy (mp->cmd, vam->input->buffer, len);
4811   mp->length = htonl (len);
4812
4813   S (mp);
4814   W2 (ret, print (vam->ofp, "%s", vam->cmd_reply));
4815   return ret;
4816 }
4817
4818 static int
4819 api_create_loopback (vat_main_t * vam)
4820 {
4821   unformat_input_t *i = vam->input;
4822   vl_api_create_loopback_t *mp;
4823   vl_api_create_loopback_instance_t *mp_lbi;
4824   u8 mac_address[6];
4825   u8 mac_set = 0;
4826   u8 is_specified = 0;
4827   u32 user_instance = 0;
4828   int ret;
4829
4830   memset (mac_address, 0, sizeof (mac_address));
4831
4832   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4833     {
4834       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
4835         mac_set = 1;
4836       if (unformat (i, "instance %d", &user_instance))
4837         is_specified = 1;
4838       else
4839         break;
4840     }
4841
4842   if (is_specified)
4843     {
4844       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
4845       mp_lbi->is_specified = is_specified;
4846       if (is_specified)
4847         mp_lbi->user_instance = htonl (user_instance);
4848       if (mac_set)
4849         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
4850       S (mp_lbi);
4851     }
4852   else
4853     {
4854       /* Construct the API message */
4855       M (CREATE_LOOPBACK, mp);
4856       if (mac_set)
4857         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
4858       S (mp);
4859     }
4860
4861   W (ret);
4862   return ret;
4863 }
4864
4865 static int
4866 api_delete_loopback (vat_main_t * vam)
4867 {
4868   unformat_input_t *i = vam->input;
4869   vl_api_delete_loopback_t *mp;
4870   u32 sw_if_index = ~0;
4871   int ret;
4872
4873   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4874     {
4875       if (unformat (i, "sw_if_index %d", &sw_if_index))
4876         ;
4877       else
4878         break;
4879     }
4880
4881   if (sw_if_index == ~0)
4882     {
4883       errmsg ("missing sw_if_index");
4884       return -99;
4885     }
4886
4887   /* Construct the API message */
4888   M (DELETE_LOOPBACK, mp);
4889   mp->sw_if_index = ntohl (sw_if_index);
4890
4891   S (mp);
4892   W (ret);
4893   return ret;
4894 }
4895
4896 static int
4897 api_want_stats (vat_main_t * vam)
4898 {
4899   unformat_input_t *i = vam->input;
4900   vl_api_want_stats_t *mp;
4901   int enable = -1;
4902   int ret;
4903
4904   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4905     {
4906       if (unformat (i, "enable"))
4907         enable = 1;
4908       else if (unformat (i, "disable"))
4909         enable = 0;
4910       else
4911         break;
4912     }
4913
4914   if (enable == -1)
4915     {
4916       errmsg ("missing enable|disable");
4917       return -99;
4918     }
4919
4920   M (WANT_STATS, mp);
4921   mp->enable_disable = enable;
4922
4923   S (mp);
4924   W (ret);
4925   return ret;
4926 }
4927
4928 static int
4929 api_want_interface_events (vat_main_t * vam)
4930 {
4931   unformat_input_t *i = vam->input;
4932   vl_api_want_interface_events_t *mp;
4933   int enable = -1;
4934   int ret;
4935
4936   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4937     {
4938       if (unformat (i, "enable"))
4939         enable = 1;
4940       else if (unformat (i, "disable"))
4941         enable = 0;
4942       else
4943         break;
4944     }
4945
4946   if (enable == -1)
4947     {
4948       errmsg ("missing enable|disable");
4949       return -99;
4950     }
4951
4952   M (WANT_INTERFACE_EVENTS, mp);
4953   mp->enable_disable = enable;
4954
4955   vam->interface_event_display = enable;
4956
4957   S (mp);
4958   W (ret);
4959   return ret;
4960 }
4961
4962
4963 /* Note: non-static, called once to set up the initial intfc table */
4964 int
4965 api_sw_interface_dump (vat_main_t * vam)
4966 {
4967   vl_api_sw_interface_dump_t *mp;
4968   vl_api_control_ping_t *mp_ping;
4969   hash_pair_t *p;
4970   name_sort_t *nses = 0, *ns;
4971   sw_interface_subif_t *sub = NULL;
4972   int ret;
4973
4974   /* Toss the old name table */
4975   /* *INDENT-OFF* */
4976   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
4977   ({
4978     vec_add2 (nses, ns, 1);
4979     ns->name = (u8 *)(p->key);
4980     ns->value = (u32) p->value[0];
4981   }));
4982   /* *INDENT-ON* */
4983
4984   hash_free (vam->sw_if_index_by_interface_name);
4985
4986   vec_foreach (ns, nses) vec_free (ns->name);
4987
4988   vec_free (nses);
4989
4990   vec_foreach (sub, vam->sw_if_subif_table)
4991   {
4992     vec_free (sub->interface_name);
4993   }
4994   vec_free (vam->sw_if_subif_table);
4995
4996   /* recreate the interface name hash table */
4997   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
4998
4999   /* Get list of ethernets */
5000   M (SW_INTERFACE_DUMP, mp);
5001   mp->name_filter_valid = 1;
5002   strncpy ((char *) mp->name_filter, "Ether", sizeof (mp->name_filter) - 1);
5003   S (mp);
5004
5005   /* and local / loopback interfaces */
5006   M (SW_INTERFACE_DUMP, mp);
5007   mp->name_filter_valid = 1;
5008   strncpy ((char *) mp->name_filter, "lo", sizeof (mp->name_filter) - 1);
5009   S (mp);
5010
5011   /* and packet-generator interfaces */
5012   M (SW_INTERFACE_DUMP, mp);
5013   mp->name_filter_valid = 1;
5014   strncpy ((char *) mp->name_filter, "pg", sizeof (mp->name_filter) - 1);
5015   S (mp);
5016
5017   /* and vxlan-gpe tunnel interfaces */
5018   M (SW_INTERFACE_DUMP, mp);
5019   mp->name_filter_valid = 1;
5020   strncpy ((char *) mp->name_filter, "vxlan_gpe",
5021            sizeof (mp->name_filter) - 1);
5022   S (mp);
5023
5024   /* and vxlan tunnel interfaces */
5025   M (SW_INTERFACE_DUMP, mp);
5026   mp->name_filter_valid = 1;
5027   strncpy ((char *) mp->name_filter, "vxlan", sizeof (mp->name_filter) - 1);
5028   S (mp);
5029
5030   /* and host (af_packet) interfaces */
5031   M (SW_INTERFACE_DUMP, mp);
5032   mp->name_filter_valid = 1;
5033   strncpy ((char *) mp->name_filter, "host", sizeof (mp->name_filter) - 1);
5034   S (mp);
5035
5036   /* and l2tpv3 tunnel interfaces */
5037   M (SW_INTERFACE_DUMP, mp);
5038   mp->name_filter_valid = 1;
5039   strncpy ((char *) mp->name_filter, "l2tpv3_tunnel",
5040            sizeof (mp->name_filter) - 1);
5041   S (mp);
5042
5043   /* and GRE tunnel interfaces */
5044   M (SW_INTERFACE_DUMP, mp);
5045   mp->name_filter_valid = 1;
5046   strncpy ((char *) mp->name_filter, "gre", sizeof (mp->name_filter) - 1);
5047   S (mp);
5048
5049   /* and LISP-GPE interfaces */
5050   M (SW_INTERFACE_DUMP, mp);
5051   mp->name_filter_valid = 1;
5052   strncpy ((char *) mp->name_filter, "lisp_gpe",
5053            sizeof (mp->name_filter) - 1);
5054   S (mp);
5055
5056   /* and IPSEC tunnel interfaces */
5057   M (SW_INTERFACE_DUMP, mp);
5058   mp->name_filter_valid = 1;
5059   strncpy ((char *) mp->name_filter, "ipsec", sizeof (mp->name_filter) - 1);
5060   S (mp);
5061
5062   /* Use a control ping for synchronization */
5063   M (CONTROL_PING, mp_ping);
5064   S (mp_ping);
5065
5066   W (ret);
5067   return ret;
5068 }
5069
5070 static int
5071 api_sw_interface_set_flags (vat_main_t * vam)
5072 {
5073   unformat_input_t *i = vam->input;
5074   vl_api_sw_interface_set_flags_t *mp;
5075   u32 sw_if_index;
5076   u8 sw_if_index_set = 0;
5077   u8 admin_up = 0, link_up = 0;
5078   int ret;
5079
5080   /* Parse args required to build the message */
5081   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5082     {
5083       if (unformat (i, "admin-up"))
5084         admin_up = 1;
5085       else if (unformat (i, "admin-down"))
5086         admin_up = 0;
5087       else if (unformat (i, "link-up"))
5088         link_up = 1;
5089       else if (unformat (i, "link-down"))
5090         link_up = 0;
5091       else
5092         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5093         sw_if_index_set = 1;
5094       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5095         sw_if_index_set = 1;
5096       else
5097         break;
5098     }
5099
5100   if (sw_if_index_set == 0)
5101     {
5102       errmsg ("missing interface name or sw_if_index");
5103       return -99;
5104     }
5105
5106   /* Construct the API message */
5107   M (SW_INTERFACE_SET_FLAGS, mp);
5108   mp->sw_if_index = ntohl (sw_if_index);
5109   mp->admin_up_down = admin_up;
5110   mp->link_up_down = link_up;
5111
5112   /* send it... */
5113   S (mp);
5114
5115   /* Wait for a reply, return the good/bad news... */
5116   W (ret);
5117   return ret;
5118 }
5119
5120 static int
5121 api_sw_interface_clear_stats (vat_main_t * vam)
5122 {
5123   unformat_input_t *i = vam->input;
5124   vl_api_sw_interface_clear_stats_t *mp;
5125   u32 sw_if_index;
5126   u8 sw_if_index_set = 0;
5127   int ret;
5128
5129   /* Parse args required to build the message */
5130   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5131     {
5132       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5133         sw_if_index_set = 1;
5134       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5135         sw_if_index_set = 1;
5136       else
5137         break;
5138     }
5139
5140   /* Construct the API message */
5141   M (SW_INTERFACE_CLEAR_STATS, mp);
5142
5143   if (sw_if_index_set == 1)
5144     mp->sw_if_index = ntohl (sw_if_index);
5145   else
5146     mp->sw_if_index = ~0;
5147
5148   /* send it... */
5149   S (mp);
5150
5151   /* Wait for a reply, return the good/bad news... */
5152   W (ret);
5153   return ret;
5154 }
5155
5156 static int
5157 api_sw_interface_add_del_address (vat_main_t * vam)
5158 {
5159   unformat_input_t *i = vam->input;
5160   vl_api_sw_interface_add_del_address_t *mp;
5161   u32 sw_if_index;
5162   u8 sw_if_index_set = 0;
5163   u8 is_add = 1, del_all = 0;
5164   u32 address_length = 0;
5165   u8 v4_address_set = 0;
5166   u8 v6_address_set = 0;
5167   ip4_address_t v4address;
5168   ip6_address_t v6address;
5169   int ret;
5170
5171   /* Parse args required to build the message */
5172   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5173     {
5174       if (unformat (i, "del-all"))
5175         del_all = 1;
5176       else if (unformat (i, "del"))
5177         is_add = 0;
5178       else
5179         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5180         sw_if_index_set = 1;
5181       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5182         sw_if_index_set = 1;
5183       else if (unformat (i, "%U/%d",
5184                          unformat_ip4_address, &v4address, &address_length))
5185         v4_address_set = 1;
5186       else if (unformat (i, "%U/%d",
5187                          unformat_ip6_address, &v6address, &address_length))
5188         v6_address_set = 1;
5189       else
5190         break;
5191     }
5192
5193   if (sw_if_index_set == 0)
5194     {
5195       errmsg ("missing interface name or sw_if_index");
5196       return -99;
5197     }
5198   if (v4_address_set && v6_address_set)
5199     {
5200       errmsg ("both v4 and v6 addresses set");
5201       return -99;
5202     }
5203   if (!v4_address_set && !v6_address_set && !del_all)
5204     {
5205       errmsg ("no addresses set");
5206       return -99;
5207     }
5208
5209   /* Construct the API message */
5210   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
5211
5212   mp->sw_if_index = ntohl (sw_if_index);
5213   mp->is_add = is_add;
5214   mp->del_all = del_all;
5215   if (v6_address_set)
5216     {
5217       mp->is_ipv6 = 1;
5218       clib_memcpy (mp->address, &v6address, sizeof (v6address));
5219     }
5220   else
5221     {
5222       clib_memcpy (mp->address, &v4address, sizeof (v4address));
5223     }
5224   mp->address_length = address_length;
5225
5226   /* send it... */
5227   S (mp);
5228
5229   /* Wait for a reply, return good/bad news  */
5230   W (ret);
5231   return ret;
5232 }
5233
5234 static int
5235 api_sw_interface_set_mpls_enable (vat_main_t * vam)
5236 {
5237   unformat_input_t *i = vam->input;
5238   vl_api_sw_interface_set_mpls_enable_t *mp;
5239   u32 sw_if_index;
5240   u8 sw_if_index_set = 0;
5241   u8 enable = 1;
5242   int ret;
5243
5244   /* Parse args required to build the message */
5245   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5246     {
5247       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5248         sw_if_index_set = 1;
5249       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5250         sw_if_index_set = 1;
5251       else if (unformat (i, "disable"))
5252         enable = 0;
5253       else if (unformat (i, "dis"))
5254         enable = 0;
5255       else
5256         break;
5257     }
5258
5259   if (sw_if_index_set == 0)
5260     {
5261       errmsg ("missing interface name or sw_if_index");
5262       return -99;
5263     }
5264
5265   /* Construct the API message */
5266   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
5267
5268   mp->sw_if_index = ntohl (sw_if_index);
5269   mp->enable = enable;
5270
5271   /* send it... */
5272   S (mp);
5273
5274   /* Wait for a reply... */
5275   W (ret);
5276   return ret;
5277 }
5278
5279 static int
5280 api_sw_interface_set_table (vat_main_t * vam)
5281 {
5282   unformat_input_t *i = vam->input;
5283   vl_api_sw_interface_set_table_t *mp;
5284   u32 sw_if_index, vrf_id = 0;
5285   u8 sw_if_index_set = 0;
5286   u8 is_ipv6 = 0;
5287   int ret;
5288
5289   /* Parse args required to build the message */
5290   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5291     {
5292       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5293         sw_if_index_set = 1;
5294       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5295         sw_if_index_set = 1;
5296       else if (unformat (i, "vrf %d", &vrf_id))
5297         ;
5298       else if (unformat (i, "ipv6"))
5299         is_ipv6 = 1;
5300       else
5301         break;
5302     }
5303
5304   if (sw_if_index_set == 0)
5305     {
5306       errmsg ("missing interface name or sw_if_index");
5307       return -99;
5308     }
5309
5310   /* Construct the API message */
5311   M (SW_INTERFACE_SET_TABLE, mp);
5312
5313   mp->sw_if_index = ntohl (sw_if_index);
5314   mp->is_ipv6 = is_ipv6;
5315   mp->vrf_id = ntohl (vrf_id);
5316
5317   /* send it... */
5318   S (mp);
5319
5320   /* Wait for a reply... */
5321   W (ret);
5322   return ret;
5323 }
5324
5325 static void vl_api_sw_interface_get_table_reply_t_handler
5326   (vl_api_sw_interface_get_table_reply_t * mp)
5327 {
5328   vat_main_t *vam = &vat_main;
5329
5330   print (vam->ofp, "%d", ntohl (mp->vrf_id));
5331
5332   vam->retval = ntohl (mp->retval);
5333   vam->result_ready = 1;
5334
5335 }
5336
5337 static void vl_api_sw_interface_get_table_reply_t_handler_json
5338   (vl_api_sw_interface_get_table_reply_t * mp)
5339 {
5340   vat_main_t *vam = &vat_main;
5341   vat_json_node_t node;
5342
5343   vat_json_init_object (&node);
5344   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
5345   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
5346
5347   vat_json_print (vam->ofp, &node);
5348   vat_json_free (&node);
5349
5350   vam->retval = ntohl (mp->retval);
5351   vam->result_ready = 1;
5352 }
5353
5354 static int
5355 api_sw_interface_get_table (vat_main_t * vam)
5356 {
5357   unformat_input_t *i = vam->input;
5358   vl_api_sw_interface_get_table_t *mp;
5359   u32 sw_if_index;
5360   u8 sw_if_index_set = 0;
5361   u8 is_ipv6 = 0;
5362   int ret;
5363
5364   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5365     {
5366       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5367         sw_if_index_set = 1;
5368       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5369         sw_if_index_set = 1;
5370       else if (unformat (i, "ipv6"))
5371         is_ipv6 = 1;
5372       else
5373         break;
5374     }
5375
5376   if (sw_if_index_set == 0)
5377     {
5378       errmsg ("missing interface name or sw_if_index");
5379       return -99;
5380     }
5381
5382   M (SW_INTERFACE_GET_TABLE, mp);
5383   mp->sw_if_index = htonl (sw_if_index);
5384   mp->is_ipv6 = is_ipv6;
5385
5386   S (mp);
5387   W (ret);
5388   return ret;
5389 }
5390
5391 static int
5392 api_sw_interface_set_vpath (vat_main_t * vam)
5393 {
5394   unformat_input_t *i = vam->input;
5395   vl_api_sw_interface_set_vpath_t *mp;
5396   u32 sw_if_index = 0;
5397   u8 sw_if_index_set = 0;
5398   u8 is_enable = 0;
5399   int ret;
5400
5401   /* Parse args required to build the message */
5402   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5403     {
5404       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5405         sw_if_index_set = 1;
5406       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5407         sw_if_index_set = 1;
5408       else if (unformat (i, "enable"))
5409         is_enable = 1;
5410       else if (unformat (i, "disable"))
5411         is_enable = 0;
5412       else
5413         break;
5414     }
5415
5416   if (sw_if_index_set == 0)
5417     {
5418       errmsg ("missing interface name or sw_if_index");
5419       return -99;
5420     }
5421
5422   /* Construct the API message */
5423   M (SW_INTERFACE_SET_VPATH, mp);
5424
5425   mp->sw_if_index = ntohl (sw_if_index);
5426   mp->enable = is_enable;
5427
5428   /* send it... */
5429   S (mp);
5430
5431   /* Wait for a reply... */
5432   W (ret);
5433   return ret;
5434 }
5435
5436 static int
5437 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
5438 {
5439   unformat_input_t *i = vam->input;
5440   vl_api_sw_interface_set_vxlan_bypass_t *mp;
5441   u32 sw_if_index = 0;
5442   u8 sw_if_index_set = 0;
5443   u8 is_enable = 1;
5444   u8 is_ipv6 = 0;
5445   int ret;
5446
5447   /* Parse args required to build the message */
5448   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5449     {
5450       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5451         sw_if_index_set = 1;
5452       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5453         sw_if_index_set = 1;
5454       else if (unformat (i, "enable"))
5455         is_enable = 1;
5456       else if (unformat (i, "disable"))
5457         is_enable = 0;
5458       else if (unformat (i, "ip4"))
5459         is_ipv6 = 0;
5460       else if (unformat (i, "ip6"))
5461         is_ipv6 = 1;
5462       else
5463         break;
5464     }
5465
5466   if (sw_if_index_set == 0)
5467     {
5468       errmsg ("missing interface name or sw_if_index");
5469       return -99;
5470     }
5471
5472   /* Construct the API message */
5473   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
5474
5475   mp->sw_if_index = ntohl (sw_if_index);
5476   mp->enable = is_enable;
5477   mp->is_ipv6 = is_ipv6;
5478
5479   /* send it... */
5480   S (mp);
5481
5482   /* Wait for a reply... */
5483   W (ret);
5484   return ret;
5485 }
5486
5487 static int
5488 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
5489 {
5490   unformat_input_t *i = vam->input;
5491   vl_api_sw_interface_set_l2_xconnect_t *mp;
5492   u32 rx_sw_if_index;
5493   u8 rx_sw_if_index_set = 0;
5494   u32 tx_sw_if_index;
5495   u8 tx_sw_if_index_set = 0;
5496   u8 enable = 1;
5497   int ret;
5498
5499   /* Parse args required to build the message */
5500   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5501     {
5502       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
5503         rx_sw_if_index_set = 1;
5504       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
5505         tx_sw_if_index_set = 1;
5506       else if (unformat (i, "rx"))
5507         {
5508           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5509             {
5510               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
5511                             &rx_sw_if_index))
5512                 rx_sw_if_index_set = 1;
5513             }
5514           else
5515             break;
5516         }
5517       else if (unformat (i, "tx"))
5518         {
5519           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5520             {
5521               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
5522                             &tx_sw_if_index))
5523                 tx_sw_if_index_set = 1;
5524             }
5525           else
5526             break;
5527         }
5528       else if (unformat (i, "enable"))
5529         enable = 1;
5530       else if (unformat (i, "disable"))
5531         enable = 0;
5532       else
5533         break;
5534     }
5535
5536   if (rx_sw_if_index_set == 0)
5537     {
5538       errmsg ("missing rx interface name or rx_sw_if_index");
5539       return -99;
5540     }
5541
5542   if (enable && (tx_sw_if_index_set == 0))
5543     {
5544       errmsg ("missing tx interface name or tx_sw_if_index");
5545       return -99;
5546     }
5547
5548   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
5549
5550   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
5551   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
5552   mp->enable = enable;
5553
5554   S (mp);
5555   W (ret);
5556   return ret;
5557 }
5558
5559 static int
5560 api_sw_interface_set_l2_bridge (vat_main_t * vam)
5561 {
5562   unformat_input_t *i = vam->input;
5563   vl_api_sw_interface_set_l2_bridge_t *mp;
5564   u32 rx_sw_if_index;
5565   u8 rx_sw_if_index_set = 0;
5566   u32 bd_id;
5567   u8 bd_id_set = 0;
5568   u8 bvi = 0;
5569   u32 shg = 0;
5570   u8 enable = 1;
5571   int ret;
5572
5573   /* Parse args required to build the message */
5574   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5575     {
5576       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
5577         rx_sw_if_index_set = 1;
5578       else if (unformat (i, "bd_id %d", &bd_id))
5579         bd_id_set = 1;
5580       else
5581         if (unformat
5582             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
5583         rx_sw_if_index_set = 1;
5584       else if (unformat (i, "shg %d", &shg))
5585         ;
5586       else if (unformat (i, "bvi"))
5587         bvi = 1;
5588       else if (unformat (i, "enable"))
5589         enable = 1;
5590       else if (unformat (i, "disable"))
5591         enable = 0;
5592       else
5593         break;
5594     }
5595
5596   if (rx_sw_if_index_set == 0)
5597     {
5598       errmsg ("missing rx interface name or sw_if_index");
5599       return -99;
5600     }
5601
5602   if (enable && (bd_id_set == 0))
5603     {
5604       errmsg ("missing bridge domain");
5605       return -99;
5606     }
5607
5608   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
5609
5610   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
5611   mp->bd_id = ntohl (bd_id);
5612   mp->shg = (u8) shg;
5613   mp->bvi = bvi;
5614   mp->enable = enable;
5615
5616   S (mp);
5617   W (ret);
5618   return ret;
5619 }
5620
5621 static int
5622 api_bridge_domain_dump (vat_main_t * vam)
5623 {
5624   unformat_input_t *i = vam->input;
5625   vl_api_bridge_domain_dump_t *mp;
5626   vl_api_control_ping_t *mp_ping;
5627   u32 bd_id = ~0;
5628   int ret;
5629
5630   /* Parse args required to build the message */
5631   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5632     {
5633       if (unformat (i, "bd_id %d", &bd_id))
5634         ;
5635       else
5636         break;
5637     }
5638
5639   M (BRIDGE_DOMAIN_DUMP, mp);
5640   mp->bd_id = ntohl (bd_id);
5641   S (mp);
5642
5643   /* Use a control ping for synchronization */
5644   M (CONTROL_PING, mp_ping);
5645   S (mp_ping);
5646
5647   W (ret);
5648   return ret;
5649 }
5650
5651 static int
5652 api_bridge_domain_add_del (vat_main_t * vam)
5653 {
5654   unformat_input_t *i = vam->input;
5655   vl_api_bridge_domain_add_del_t *mp;
5656   u32 bd_id = ~0;
5657   u8 is_add = 1;
5658   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
5659   u32 mac_age = 0;
5660   int ret;
5661
5662   /* Parse args required to build the message */
5663   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5664     {
5665       if (unformat (i, "bd_id %d", &bd_id))
5666         ;
5667       else if (unformat (i, "flood %d", &flood))
5668         ;
5669       else if (unformat (i, "uu-flood %d", &uu_flood))
5670         ;
5671       else if (unformat (i, "forward %d", &forward))
5672         ;
5673       else if (unformat (i, "learn %d", &learn))
5674         ;
5675       else if (unformat (i, "arp-term %d", &arp_term))
5676         ;
5677       else if (unformat (i, "mac-age %d", &mac_age))
5678         ;
5679       else if (unformat (i, "del"))
5680         {
5681           is_add = 0;
5682           flood = uu_flood = forward = learn = 0;
5683         }
5684       else
5685         break;
5686     }
5687
5688   if (bd_id == ~0)
5689     {
5690       errmsg ("missing bridge domain");
5691       return -99;
5692     }
5693
5694   if (mac_age > 255)
5695     {
5696       errmsg ("mac age must be less than 256 ");
5697       return -99;
5698     }
5699
5700   M (BRIDGE_DOMAIN_ADD_DEL, mp);
5701
5702   mp->bd_id = ntohl (bd_id);
5703   mp->flood = flood;
5704   mp->uu_flood = uu_flood;
5705   mp->forward = forward;
5706   mp->learn = learn;
5707   mp->arp_term = arp_term;
5708   mp->is_add = is_add;
5709   mp->mac_age = (u8) mac_age;
5710
5711   S (mp);
5712   W (ret);
5713   return ret;
5714 }
5715
5716 static int
5717 api_l2fib_add_del (vat_main_t * vam)
5718 {
5719   unformat_input_t *i = vam->input;
5720   vl_api_l2fib_add_del_t *mp;
5721   f64 timeout;
5722   u64 mac = 0;
5723   u8 mac_set = 0;
5724   u32 bd_id;
5725   u8 bd_id_set = 0;
5726   u32 sw_if_index = ~0;
5727   u8 sw_if_index_set = 0;
5728   u8 is_add = 1;
5729   u8 static_mac = 0;
5730   u8 filter_mac = 0;
5731   u8 bvi_mac = 0;
5732   int count = 1;
5733   f64 before = 0;
5734   int j;
5735
5736   /* Parse args required to build the message */
5737   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5738     {
5739       if (unformat (i, "mac %U", unformat_ethernet_address, &mac))
5740         mac_set = 1;
5741       else if (unformat (i, "bd_id %d", &bd_id))
5742         bd_id_set = 1;
5743       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5744         sw_if_index_set = 1;
5745       else if (unformat (i, "sw_if"))
5746         {
5747           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5748             {
5749               if (unformat
5750                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5751                 sw_if_index_set = 1;
5752             }
5753           else
5754             break;
5755         }
5756       else if (unformat (i, "static"))
5757         static_mac = 1;
5758       else if (unformat (i, "filter"))
5759         {
5760           filter_mac = 1;
5761           static_mac = 1;
5762         }
5763       else if (unformat (i, "bvi"))
5764         {
5765           bvi_mac = 1;
5766           static_mac = 1;
5767         }
5768       else if (unformat (i, "del"))
5769         is_add = 0;
5770       else if (unformat (i, "count %d", &count))
5771         ;
5772       else
5773         break;
5774     }
5775
5776   if (mac_set == 0)
5777     {
5778       errmsg ("missing mac address");
5779       return -99;
5780     }
5781
5782   if (bd_id_set == 0)
5783     {
5784       errmsg ("missing bridge domain");
5785       return -99;
5786     }
5787
5788   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
5789     {
5790       errmsg ("missing interface name or sw_if_index");
5791       return -99;
5792     }
5793
5794   if (count > 1)
5795     {
5796       /* Turn on async mode */
5797       vam->async_mode = 1;
5798       vam->async_errors = 0;
5799       before = vat_time_now (vam);
5800     }
5801
5802   for (j = 0; j < count; j++)
5803     {
5804       M (L2FIB_ADD_DEL, mp);
5805
5806       mp->mac = mac;
5807       mp->bd_id = ntohl (bd_id);
5808       mp->is_add = is_add;
5809
5810       if (is_add)
5811         {
5812           mp->sw_if_index = ntohl (sw_if_index);
5813           mp->static_mac = static_mac;
5814           mp->filter_mac = filter_mac;
5815           mp->bvi_mac = bvi_mac;
5816         }
5817       increment_mac_address (&mac);
5818       /* send it... */
5819       S (mp);
5820     }
5821
5822   if (count > 1)
5823     {
5824       vl_api_control_ping_t *mp_ping;
5825       f64 after;
5826
5827       /* Shut off async mode */
5828       vam->async_mode = 0;
5829
5830       M (CONTROL_PING, mp_ping);
5831       S (mp_ping);
5832
5833       timeout = vat_time_now (vam) + 1.0;
5834       while (vat_time_now (vam) < timeout)
5835         if (vam->result_ready == 1)
5836           goto out;
5837       vam->retval = -99;
5838
5839     out:
5840       if (vam->retval == -99)
5841         errmsg ("timeout");
5842
5843       if (vam->async_errors > 0)
5844         {
5845           errmsg ("%d asynchronous errors", vam->async_errors);
5846           vam->retval = -98;
5847         }
5848       vam->async_errors = 0;
5849       after = vat_time_now (vam);
5850
5851       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
5852              count, after - before, count / (after - before));
5853     }
5854   else
5855     {
5856       int ret;
5857
5858       /* Wait for a reply... */
5859       W (ret);
5860       return ret;
5861     }
5862   /* Return the good/bad news */
5863   return (vam->retval);
5864 }
5865
5866 static int
5867 api_l2_flags (vat_main_t * vam)
5868 {
5869   unformat_input_t *i = vam->input;
5870   vl_api_l2_flags_t *mp;
5871   u32 sw_if_index;
5872   u32 feature_bitmap = 0;
5873   u8 sw_if_index_set = 0;
5874   int ret;
5875
5876   /* Parse args required to build the message */
5877   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5878     {
5879       if (unformat (i, "sw_if_index %d", &sw_if_index))
5880         sw_if_index_set = 1;
5881       else if (unformat (i, "sw_if"))
5882         {
5883           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5884             {
5885               if (unformat
5886                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5887                 sw_if_index_set = 1;
5888             }
5889           else
5890             break;
5891         }
5892       else if (unformat (i, "learn"))
5893         feature_bitmap |= L2INPUT_FEAT_LEARN;
5894       else if (unformat (i, "forward"))
5895         feature_bitmap |= L2INPUT_FEAT_FWD;
5896       else if (unformat (i, "flood"))
5897         feature_bitmap |= L2INPUT_FEAT_FLOOD;
5898       else if (unformat (i, "uu-flood"))
5899         feature_bitmap |= L2INPUT_FEAT_UU_FLOOD;
5900       else
5901         break;
5902     }
5903
5904   if (sw_if_index_set == 0)
5905     {
5906       errmsg ("missing interface name or sw_if_index");
5907       return -99;
5908     }
5909
5910   M (L2_FLAGS, mp);
5911
5912   mp->sw_if_index = ntohl (sw_if_index);
5913   mp->feature_bitmap = ntohl (feature_bitmap);
5914
5915   S (mp);
5916   W (ret);
5917   return ret;
5918 }
5919
5920 static int
5921 api_bridge_flags (vat_main_t * vam)
5922 {
5923   unformat_input_t *i = vam->input;
5924   vl_api_bridge_flags_t *mp;
5925   u32 bd_id;
5926   u8 bd_id_set = 0;
5927   u8 is_set = 1;
5928   u32 flags = 0;
5929   int ret;
5930
5931   /* Parse args required to build the message */
5932   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5933     {
5934       if (unformat (i, "bd_id %d", &bd_id))
5935         bd_id_set = 1;
5936       else if (unformat (i, "learn"))
5937         flags |= L2_LEARN;
5938       else if (unformat (i, "forward"))
5939         flags |= L2_FWD;
5940       else if (unformat (i, "flood"))
5941         flags |= L2_FLOOD;
5942       else if (unformat (i, "uu-flood"))
5943         flags |= L2_UU_FLOOD;
5944       else if (unformat (i, "arp-term"))
5945         flags |= L2_ARP_TERM;
5946       else if (unformat (i, "off"))
5947         is_set = 0;
5948       else if (unformat (i, "disable"))
5949         is_set = 0;
5950       else
5951         break;
5952     }
5953
5954   if (bd_id_set == 0)
5955     {
5956       errmsg ("missing bridge domain");
5957       return -99;
5958     }
5959
5960   M (BRIDGE_FLAGS, mp);
5961
5962   mp->bd_id = ntohl (bd_id);
5963   mp->feature_bitmap = ntohl (flags);
5964   mp->is_set = is_set;
5965
5966   S (mp);
5967   W (ret);
5968   return ret;
5969 }
5970
5971 static int
5972 api_bd_ip_mac_add_del (vat_main_t * vam)
5973 {
5974   unformat_input_t *i = vam->input;
5975   vl_api_bd_ip_mac_add_del_t *mp;
5976   u32 bd_id;
5977   u8 is_ipv6 = 0;
5978   u8 is_add = 1;
5979   u8 bd_id_set = 0;
5980   u8 ip_set = 0;
5981   u8 mac_set = 0;
5982   ip4_address_t v4addr;
5983   ip6_address_t v6addr;
5984   u8 macaddr[6];
5985   int ret;
5986
5987
5988   /* Parse args required to build the message */
5989   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5990     {
5991       if (unformat (i, "bd_id %d", &bd_id))
5992         {
5993           bd_id_set++;
5994         }
5995       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
5996         {
5997           ip_set++;
5998         }
5999       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
6000         {
6001           ip_set++;
6002           is_ipv6++;
6003         }
6004       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
6005         {
6006           mac_set++;
6007         }
6008       else if (unformat (i, "del"))
6009         is_add = 0;
6010       else
6011         break;
6012     }
6013
6014   if (bd_id_set == 0)
6015     {
6016       errmsg ("missing bridge domain");
6017       return -99;
6018     }
6019   else if (ip_set == 0)
6020     {
6021       errmsg ("missing IP address");
6022       return -99;
6023     }
6024   else if (mac_set == 0)
6025     {
6026       errmsg ("missing MAC address");
6027       return -99;
6028     }
6029
6030   M (BD_IP_MAC_ADD_DEL, mp);
6031
6032   mp->bd_id = ntohl (bd_id);
6033   mp->is_ipv6 = is_ipv6;
6034   mp->is_add = is_add;
6035   if (is_ipv6)
6036     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
6037   else
6038     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
6039   clib_memcpy (mp->mac_address, macaddr, 6);
6040   S (mp);
6041   W (ret);
6042   return ret;
6043 }
6044
6045 static int
6046 api_tap_connect (vat_main_t * vam)
6047 {
6048   unformat_input_t *i = vam->input;
6049   vl_api_tap_connect_t *mp;
6050   u8 mac_address[6];
6051   u8 random_mac = 1;
6052   u8 name_set = 0;
6053   u8 *tap_name;
6054   u8 *tag = 0;
6055   ip4_address_t ip4_address;
6056   u32 ip4_mask_width;
6057   int ip4_address_set = 0;
6058   ip6_address_t ip6_address;
6059   u32 ip6_mask_width;
6060   int ip6_address_set = 0;
6061   int ret;
6062
6063   memset (mac_address, 0, sizeof (mac_address));
6064
6065   /* Parse args required to build the message */
6066   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6067     {
6068       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6069         {
6070           random_mac = 0;
6071         }
6072       else if (unformat (i, "random-mac"))
6073         random_mac = 1;
6074       else if (unformat (i, "tapname %s", &tap_name))
6075         name_set = 1;
6076       else if (unformat (i, "tag %s", &tag))
6077         ;
6078       else if (unformat (i, "address %U/%d",
6079                          unformat_ip4_address, &ip4_address, &ip4_mask_width))
6080         ip4_address_set = 1;
6081       else if (unformat (i, "address %U/%d",
6082                          unformat_ip6_address, &ip6_address, &ip6_mask_width))
6083         ip6_address_set = 1;
6084       else
6085         break;
6086     }
6087
6088   if (name_set == 0)
6089     {
6090       errmsg ("missing tap name");
6091       return -99;
6092     }
6093   if (vec_len (tap_name) > 63)
6094     {
6095       errmsg ("tap name too long");
6096       return -99;
6097     }
6098   vec_add1 (tap_name, 0);
6099
6100   if (vec_len (tag) > 63)
6101     {
6102       errmsg ("tag too long");
6103       return -99;
6104     }
6105
6106   /* Construct the API message */
6107   M (TAP_CONNECT, mp);
6108
6109   mp->use_random_mac = random_mac;
6110   clib_memcpy (mp->mac_address, mac_address, 6);
6111   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
6112   if (tag)
6113     clib_memcpy (mp->tag, tag, vec_len (tag));
6114
6115   if (ip4_address_set)
6116     {
6117       mp->ip4_address_set = 1;
6118       clib_memcpy (mp->ip4_address, &ip4_address, sizeof (mp->ip4_address));
6119       mp->ip4_mask_width = ip4_mask_width;
6120     }
6121   if (ip6_address_set)
6122     {
6123       mp->ip6_address_set = 1;
6124       clib_memcpy (mp->ip6_address, &ip6_address, sizeof (mp->ip6_address));
6125       mp->ip6_mask_width = ip6_mask_width;
6126     }
6127
6128   vec_free (tap_name);
6129   vec_free (tag);
6130
6131   /* send it... */
6132   S (mp);
6133
6134   /* Wait for a reply... */
6135   W (ret);
6136   return ret;
6137 }
6138
6139 static int
6140 api_tap_modify (vat_main_t * vam)
6141 {
6142   unformat_input_t *i = vam->input;
6143   vl_api_tap_modify_t *mp;
6144   u8 mac_address[6];
6145   u8 random_mac = 1;
6146   u8 name_set = 0;
6147   u8 *tap_name;
6148   u32 sw_if_index = ~0;
6149   u8 sw_if_index_set = 0;
6150   int ret;
6151
6152   memset (mac_address, 0, sizeof (mac_address));
6153
6154   /* Parse args required to build the message */
6155   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6156     {
6157       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6158         sw_if_index_set = 1;
6159       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6160         sw_if_index_set = 1;
6161       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6162         {
6163           random_mac = 0;
6164         }
6165       else if (unformat (i, "random-mac"))
6166         random_mac = 1;
6167       else if (unformat (i, "tapname %s", &tap_name))
6168         name_set = 1;
6169       else
6170         break;
6171     }
6172
6173   if (sw_if_index_set == 0)
6174     {
6175       errmsg ("missing vpp interface name");
6176       return -99;
6177     }
6178   if (name_set == 0)
6179     {
6180       errmsg ("missing tap name");
6181       return -99;
6182     }
6183   if (vec_len (tap_name) > 63)
6184     {
6185       errmsg ("tap name too long");
6186     }
6187   vec_add1 (tap_name, 0);
6188
6189   /* Construct the API message */
6190   M (TAP_MODIFY, mp);
6191
6192   mp->use_random_mac = random_mac;
6193   mp->sw_if_index = ntohl (sw_if_index);
6194   clib_memcpy (mp->mac_address, mac_address, 6);
6195   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
6196   vec_free (tap_name);
6197
6198   /* send it... */
6199   S (mp);
6200
6201   /* Wait for a reply... */
6202   W (ret);
6203   return ret;
6204 }
6205
6206 static int
6207 api_tap_delete (vat_main_t * vam)
6208 {
6209   unformat_input_t *i = vam->input;
6210   vl_api_tap_delete_t *mp;
6211   u32 sw_if_index = ~0;
6212   u8 sw_if_index_set = 0;
6213   int ret;
6214
6215   /* Parse args required to build the message */
6216   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6217     {
6218       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6219         sw_if_index_set = 1;
6220       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6221         sw_if_index_set = 1;
6222       else
6223         break;
6224     }
6225
6226   if (sw_if_index_set == 0)
6227     {
6228       errmsg ("missing vpp interface name");
6229       return -99;
6230     }
6231
6232   /* Construct the API message */
6233   M (TAP_DELETE, mp);
6234
6235   mp->sw_if_index = ntohl (sw_if_index);
6236
6237   /* send it... */
6238   S (mp);
6239
6240   /* Wait for a reply... */
6241   W (ret);
6242   return ret;
6243 }
6244
6245 static int
6246 api_ip_add_del_route (vat_main_t * vam)
6247 {
6248   unformat_input_t *i = vam->input;
6249   vl_api_ip_add_del_route_t *mp;
6250   u32 sw_if_index = ~0, vrf_id = 0;
6251   u8 is_ipv6 = 0;
6252   u8 is_local = 0, is_drop = 0;
6253   u8 is_unreach = 0, is_prohibit = 0;
6254   u8 create_vrf_if_needed = 0;
6255   u8 is_add = 1;
6256   u32 next_hop_weight = 1;
6257   u8 not_last = 0;
6258   u8 is_multipath = 0;
6259   u8 address_set = 0;
6260   u8 address_length_set = 0;
6261   u32 next_hop_table_id = 0;
6262   u32 resolve_attempts = 0;
6263   u32 dst_address_length = 0;
6264   u8 next_hop_set = 0;
6265   ip4_address_t v4_dst_address, v4_next_hop_address;
6266   ip6_address_t v6_dst_address, v6_next_hop_address;
6267   int count = 1;
6268   int j;
6269   f64 before = 0;
6270   u32 random_add_del = 0;
6271   u32 *random_vector = 0;
6272   uword *random_hash;
6273   u32 random_seed = 0xdeaddabe;
6274   u32 classify_table_index = ~0;
6275   u8 is_classify = 0;
6276   u8 resolve_host = 0, resolve_attached = 0;
6277   mpls_label_t *next_hop_out_label_stack = NULL;
6278   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
6279   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
6280
6281   /* Parse args required to build the message */
6282   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6283     {
6284       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6285         ;
6286       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6287         ;
6288       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
6289         {
6290           address_set = 1;
6291           is_ipv6 = 0;
6292         }
6293       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
6294         {
6295           address_set = 1;
6296           is_ipv6 = 1;
6297         }
6298       else if (unformat (i, "/%d", &dst_address_length))
6299         {
6300           address_length_set = 1;
6301         }
6302
6303       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
6304                                          &v4_next_hop_address))
6305         {
6306           next_hop_set = 1;
6307         }
6308       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
6309                                          &v6_next_hop_address))
6310         {
6311           next_hop_set = 1;
6312         }
6313       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
6314         ;
6315       else if (unformat (i, "weight %d", &next_hop_weight))
6316         ;
6317       else if (unformat (i, "drop"))
6318         {
6319           is_drop = 1;
6320         }
6321       else if (unformat (i, "null-send-unreach"))
6322         {
6323           is_unreach = 1;
6324         }
6325       else if (unformat (i, "null-send-prohibit"))
6326         {
6327           is_prohibit = 1;
6328         }
6329       else if (unformat (i, "local"))
6330         {
6331           is_local = 1;
6332         }
6333       else if (unformat (i, "classify %d", &classify_table_index))
6334         {
6335           is_classify = 1;
6336         }
6337       else if (unformat (i, "del"))
6338         is_add = 0;
6339       else if (unformat (i, "add"))
6340         is_add = 1;
6341       else if (unformat (i, "not-last"))
6342         not_last = 1;
6343       else if (unformat (i, "resolve-via-host"))
6344         resolve_host = 1;
6345       else if (unformat (i, "resolve-via-attached"))
6346         resolve_attached = 1;
6347       else if (unformat (i, "multipath"))
6348         is_multipath = 1;
6349       else if (unformat (i, "vrf %d", &vrf_id))
6350         ;
6351       else if (unformat (i, "create-vrf"))
6352         create_vrf_if_needed = 1;
6353       else if (unformat (i, "count %d", &count))
6354         ;
6355       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
6356         ;
6357       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
6358         ;
6359       else if (unformat (i, "out-label %d", &next_hop_out_label))
6360         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
6361       else if (unformat (i, "via-label %d", &next_hop_via_label))
6362         ;
6363       else if (unformat (i, "random"))
6364         random_add_del = 1;
6365       else if (unformat (i, "seed %d", &random_seed))
6366         ;
6367       else
6368         {
6369           clib_warning ("parse error '%U'", format_unformat_error, i);
6370           return -99;
6371         }
6372     }
6373
6374   if (!next_hop_set && !is_drop && !is_local &&
6375       !is_classify && !is_unreach && !is_prohibit &&
6376       MPLS_LABEL_INVALID == next_hop_via_label)
6377     {
6378       errmsg
6379         ("next hop / local / drop / unreach / prohibit / classify not set");
6380       return -99;
6381     }
6382
6383   if (next_hop_set && MPLS_LABEL_INVALID != next_hop_via_label)
6384     {
6385       errmsg ("next hop and next-hop via label set");
6386       return -99;
6387     }
6388   if (address_set == 0)
6389     {
6390       errmsg ("missing addresses");
6391       return -99;
6392     }
6393
6394   if (address_length_set == 0)
6395     {
6396       errmsg ("missing address length");
6397       return -99;
6398     }
6399
6400   /* Generate a pile of unique, random routes */
6401   if (random_add_del)
6402     {
6403       u32 this_random_address;
6404       random_hash = hash_create (count, sizeof (uword));
6405
6406       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
6407       for (j = 0; j <= count; j++)
6408         {
6409           do
6410             {
6411               this_random_address = random_u32 (&random_seed);
6412               this_random_address =
6413                 clib_host_to_net_u32 (this_random_address);
6414             }
6415           while (hash_get (random_hash, this_random_address));
6416           vec_add1 (random_vector, this_random_address);
6417           hash_set (random_hash, this_random_address, 1);
6418         }
6419       hash_free (random_hash);
6420       v4_dst_address.as_u32 = random_vector[0];
6421     }
6422
6423   if (count > 1)
6424     {
6425       /* Turn on async mode */
6426       vam->async_mode = 1;
6427       vam->async_errors = 0;
6428       before = vat_time_now (vam);
6429     }
6430
6431   for (j = 0; j < count; j++)
6432     {
6433       /* Construct the API message */
6434       M2 (IP_ADD_DEL_ROUTE, mp,
6435           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
6436
6437       mp->next_hop_sw_if_index = ntohl (sw_if_index);
6438       mp->table_id = ntohl (vrf_id);
6439       mp->create_vrf_if_needed = create_vrf_if_needed;
6440
6441       mp->is_add = is_add;
6442       mp->is_drop = is_drop;
6443       mp->is_unreach = is_unreach;
6444       mp->is_prohibit = is_prohibit;
6445       mp->is_ipv6 = is_ipv6;
6446       mp->is_local = is_local;
6447       mp->is_classify = is_classify;
6448       mp->is_multipath = is_multipath;
6449       mp->is_resolve_host = resolve_host;
6450       mp->is_resolve_attached = resolve_attached;
6451       mp->not_last = not_last;
6452       mp->next_hop_weight = next_hop_weight;
6453       mp->dst_address_length = dst_address_length;
6454       mp->next_hop_table_id = ntohl (next_hop_table_id);
6455       mp->classify_table_index = ntohl (classify_table_index);
6456       mp->next_hop_via_label = ntohl (next_hop_via_label);
6457       mp->next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
6458       if (0 != mp->next_hop_n_out_labels)
6459         {
6460           memcpy (mp->next_hop_out_label_stack,
6461                   next_hop_out_label_stack,
6462                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
6463           vec_free (next_hop_out_label_stack);
6464         }
6465
6466       if (is_ipv6)
6467         {
6468           clib_memcpy (mp->dst_address, &v6_dst_address,
6469                        sizeof (v6_dst_address));
6470           if (next_hop_set)
6471             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
6472                          sizeof (v6_next_hop_address));
6473           increment_v6_address (&v6_dst_address);
6474         }
6475       else
6476         {
6477           clib_memcpy (mp->dst_address, &v4_dst_address,
6478                        sizeof (v4_dst_address));
6479           if (next_hop_set)
6480             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
6481                          sizeof (v4_next_hop_address));
6482           if (random_add_del)
6483             v4_dst_address.as_u32 = random_vector[j + 1];
6484           else
6485             increment_v4_address (&v4_dst_address);
6486         }
6487       /* send it... */
6488       S (mp);
6489       /* If we receive SIGTERM, stop now... */
6490       if (vam->do_exit)
6491         break;
6492     }
6493
6494   /* When testing multiple add/del ops, use a control-ping to sync */
6495   if (count > 1)
6496     {
6497       vl_api_control_ping_t *mp_ping;
6498       f64 after;
6499       f64 timeout;
6500
6501       /* Shut off async mode */
6502       vam->async_mode = 0;
6503
6504       M (CONTROL_PING, mp_ping);
6505       S (mp_ping);
6506
6507       timeout = vat_time_now (vam) + 1.0;
6508       while (vat_time_now (vam) < timeout)
6509         if (vam->result_ready == 1)
6510           goto out;
6511       vam->retval = -99;
6512
6513     out:
6514       if (vam->retval == -99)
6515         errmsg ("timeout");
6516
6517       if (vam->async_errors > 0)
6518         {
6519           errmsg ("%d asynchronous errors", vam->async_errors);
6520           vam->retval = -98;
6521         }
6522       vam->async_errors = 0;
6523       after = vat_time_now (vam);
6524
6525       /* slim chance, but we might have eaten SIGTERM on the first iteration */
6526       if (j > 0)
6527         count = j;
6528
6529       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6530              count, after - before, count / (after - before));
6531     }
6532   else
6533     {
6534       int ret;
6535
6536       /* Wait for a reply... */
6537       W (ret);
6538       return ret;
6539     }
6540
6541   /* Return the good/bad news */
6542   return (vam->retval);
6543 }
6544
6545 static int
6546 api_ip_mroute_add_del (vat_main_t * vam)
6547 {
6548   unformat_input_t *i = vam->input;
6549   vl_api_ip_mroute_add_del_t *mp;
6550   u32 sw_if_index = ~0, vrf_id = 0;
6551   u8 is_ipv6 = 0;
6552   u8 is_local = 0;
6553   u8 create_vrf_if_needed = 0;
6554   u8 is_add = 1;
6555   u8 address_set = 0;
6556   u32 grp_address_length = 0;
6557   ip4_address_t v4_grp_address, v4_src_address;
6558   ip6_address_t v6_grp_address, v6_src_address;
6559   mfib_itf_flags_t iflags = 0;
6560   mfib_entry_flags_t eflags = 0;
6561   int ret;
6562
6563   /* Parse args required to build the message */
6564   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6565     {
6566       if (unformat (i, "sw_if_index %d", &sw_if_index))
6567         ;
6568       else if (unformat (i, "%U %U",
6569                          unformat_ip4_address, &v4_src_address,
6570                          unformat_ip4_address, &v4_grp_address))
6571         {
6572           grp_address_length = 64;
6573           address_set = 1;
6574           is_ipv6 = 0;
6575         }
6576       else if (unformat (i, "%U %U",
6577                          unformat_ip6_address, &v6_src_address,
6578                          unformat_ip6_address, &v6_grp_address))
6579         {
6580           grp_address_length = 256;
6581           address_set = 1;
6582           is_ipv6 = 1;
6583         }
6584       else if (unformat (i, "%U", unformat_ip4_address, &v4_grp_address))
6585         {
6586           memset (&v4_src_address, 0, sizeof (v4_src_address));
6587           grp_address_length = 32;
6588           address_set = 1;
6589           is_ipv6 = 0;
6590         }
6591       else if (unformat (i, "%U", unformat_ip6_address, &v6_grp_address))
6592         {
6593           memset (&v6_src_address, 0, sizeof (v6_src_address));
6594           grp_address_length = 128;
6595           address_set = 1;
6596           is_ipv6 = 1;
6597         }
6598       else if (unformat (i, "/%d", &grp_address_length))
6599         ;
6600       else if (unformat (i, "local"))
6601         {
6602           is_local = 1;
6603         }
6604       else if (unformat (i, "del"))
6605         is_add = 0;
6606       else if (unformat (i, "add"))
6607         is_add = 1;
6608       else if (unformat (i, "vrf %d", &vrf_id))
6609         ;
6610       else if (unformat (i, "create-vrf"))
6611         create_vrf_if_needed = 1;
6612       else if (unformat (i, "%U", unformat_mfib_itf_flags, &iflags))
6613         ;
6614       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
6615         ;
6616       else
6617         {
6618           clib_warning ("parse error '%U'", format_unformat_error, i);
6619           return -99;
6620         }
6621     }
6622
6623   if (address_set == 0)
6624     {
6625       errmsg ("missing addresses\n");
6626       return -99;
6627     }
6628
6629   /* Construct the API message */
6630   M (IP_MROUTE_ADD_DEL, mp);
6631
6632   mp->next_hop_sw_if_index = ntohl (sw_if_index);
6633   mp->table_id = ntohl (vrf_id);
6634   mp->create_vrf_if_needed = create_vrf_if_needed;
6635
6636   mp->is_add = is_add;
6637   mp->is_ipv6 = is_ipv6;
6638   mp->is_local = is_local;
6639   mp->itf_flags = ntohl (iflags);
6640   mp->entry_flags = ntohl (eflags);
6641   mp->grp_address_length = grp_address_length;
6642   mp->grp_address_length = ntohs (mp->grp_address_length);
6643
6644   if (is_ipv6)
6645     {
6646       clib_memcpy (mp->grp_address, &v6_grp_address, sizeof (v6_grp_address));
6647       clib_memcpy (mp->src_address, &v6_src_address, sizeof (v6_src_address));
6648     }
6649   else
6650     {
6651       clib_memcpy (mp->grp_address, &v4_grp_address, sizeof (v4_grp_address));
6652       clib_memcpy (mp->src_address, &v4_src_address, sizeof (v4_src_address));
6653
6654     }
6655
6656   /* send it... */
6657   S (mp);
6658   /* Wait for a reply... */
6659   W (ret);
6660   return ret;
6661 }
6662
6663 static int
6664 api_mpls_route_add_del (vat_main_t * vam)
6665 {
6666   unformat_input_t *i = vam->input;
6667   vl_api_mpls_route_add_del_t *mp;
6668   u32 sw_if_index = ~0, table_id = 0;
6669   u8 create_table_if_needed = 0;
6670   u8 is_add = 1;
6671   u32 next_hop_weight = 1;
6672   u8 is_multipath = 0;
6673   u32 next_hop_table_id = 0;
6674   u8 next_hop_set = 0;
6675   ip4_address_t v4_next_hop_address = {
6676     .as_u32 = 0,
6677   };
6678   ip6_address_t v6_next_hop_address = { {0} };
6679   int count = 1;
6680   int j;
6681   f64 before = 0;
6682   u32 classify_table_index = ~0;
6683   u8 is_classify = 0;
6684   u8 resolve_host = 0, resolve_attached = 0;
6685   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
6686   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
6687   mpls_label_t *next_hop_out_label_stack = NULL;
6688   mpls_label_t local_label = MPLS_LABEL_INVALID;
6689   u8 is_eos = 0;
6690   u8 next_hop_proto_is_ip4 = 1;
6691
6692   /* Parse args required to build the message */
6693   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6694     {
6695       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6696         ;
6697       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6698         ;
6699       else if (unformat (i, "%d", &local_label))
6700         ;
6701       else if (unformat (i, "eos"))
6702         is_eos = 1;
6703       else if (unformat (i, "non-eos"))
6704         is_eos = 0;
6705       else if (unformat (i, "via %U", unformat_ip4_address,
6706                          &v4_next_hop_address))
6707         {
6708           next_hop_set = 1;
6709           next_hop_proto_is_ip4 = 1;
6710         }
6711       else if (unformat (i, "via %U", unformat_ip6_address,
6712                          &v6_next_hop_address))
6713         {
6714           next_hop_set = 1;
6715           next_hop_proto_is_ip4 = 0;
6716         }
6717       else if (unformat (i, "weight %d", &next_hop_weight))
6718         ;
6719       else if (unformat (i, "create-table"))
6720         create_table_if_needed = 1;
6721       else if (unformat (i, "classify %d", &classify_table_index))
6722         {
6723           is_classify = 1;
6724         }
6725       else if (unformat (i, "del"))
6726         is_add = 0;
6727       else if (unformat (i, "add"))
6728         is_add = 1;
6729       else if (unformat (i, "resolve-via-host"))
6730         resolve_host = 1;
6731       else if (unformat (i, "resolve-via-attached"))
6732         resolve_attached = 1;
6733       else if (unformat (i, "multipath"))
6734         is_multipath = 1;
6735       else if (unformat (i, "count %d", &count))
6736         ;
6737       else if (unformat (i, "lookup-in-ip4-table %d", &next_hop_table_id))
6738         {
6739           next_hop_set = 1;
6740           next_hop_proto_is_ip4 = 1;
6741         }
6742       else if (unformat (i, "lookup-in-ip6-table %d", &next_hop_table_id))
6743         {
6744           next_hop_set = 1;
6745           next_hop_proto_is_ip4 = 0;
6746         }
6747       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
6748         ;
6749       else if (unformat (i, "via-label %d", &next_hop_via_label))
6750         ;
6751       else if (unformat (i, "out-label %d", &next_hop_out_label))
6752         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
6753       else
6754         {
6755           clib_warning ("parse error '%U'", format_unformat_error, i);
6756           return -99;
6757         }
6758     }
6759
6760   if (!next_hop_set && !is_classify)
6761     {
6762       errmsg ("next hop / classify not set");
6763       return -99;
6764     }
6765
6766   if (MPLS_LABEL_INVALID == local_label)
6767     {
6768       errmsg ("missing label");
6769       return -99;
6770     }
6771
6772   if (count > 1)
6773     {
6774       /* Turn on async mode */
6775       vam->async_mode = 1;
6776       vam->async_errors = 0;
6777       before = vat_time_now (vam);
6778     }
6779
6780   for (j = 0; j < count; j++)
6781     {
6782       /* Construct the API message */
6783       M2 (MPLS_ROUTE_ADD_DEL, mp,
6784           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
6785
6786       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
6787       mp->mr_table_id = ntohl (table_id);
6788       mp->mr_create_table_if_needed = create_table_if_needed;
6789
6790       mp->mr_is_add = is_add;
6791       mp->mr_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
6792       mp->mr_is_classify = is_classify;
6793       mp->mr_is_multipath = is_multipath;
6794       mp->mr_is_resolve_host = resolve_host;
6795       mp->mr_is_resolve_attached = resolve_attached;
6796       mp->mr_next_hop_weight = next_hop_weight;
6797       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
6798       mp->mr_classify_table_index = ntohl (classify_table_index);
6799       mp->mr_next_hop_via_label = ntohl (next_hop_via_label);
6800       mp->mr_label = ntohl (local_label);
6801       mp->mr_eos = is_eos;
6802
6803       mp->mr_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
6804       if (0 != mp->mr_next_hop_n_out_labels)
6805         {
6806           memcpy (mp->mr_next_hop_out_label_stack,
6807                   next_hop_out_label_stack,
6808                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
6809           vec_free (next_hop_out_label_stack);
6810         }
6811
6812       if (next_hop_set)
6813         {
6814           if (next_hop_proto_is_ip4)
6815             {
6816               clib_memcpy (mp->mr_next_hop,
6817                            &v4_next_hop_address,
6818                            sizeof (v4_next_hop_address));
6819             }
6820           else
6821             {
6822               clib_memcpy (mp->mr_next_hop,
6823                            &v6_next_hop_address,
6824                            sizeof (v6_next_hop_address));
6825             }
6826         }
6827       local_label++;
6828
6829       /* send it... */
6830       S (mp);
6831       /* If we receive SIGTERM, stop now... */
6832       if (vam->do_exit)
6833         break;
6834     }
6835
6836   /* When testing multiple add/del ops, use a control-ping to sync */
6837   if (count > 1)
6838     {
6839       vl_api_control_ping_t *mp_ping;
6840       f64 after;
6841       f64 timeout;
6842
6843       /* Shut off async mode */
6844       vam->async_mode = 0;
6845
6846       M (CONTROL_PING, mp_ping);
6847       S (mp_ping);
6848
6849       timeout = vat_time_now (vam) + 1.0;
6850       while (vat_time_now (vam) < timeout)
6851         if (vam->result_ready == 1)
6852           goto out;
6853       vam->retval = -99;
6854
6855     out:
6856       if (vam->retval == -99)
6857         errmsg ("timeout");
6858
6859       if (vam->async_errors > 0)
6860         {
6861           errmsg ("%d asynchronous errors", vam->async_errors);
6862           vam->retval = -98;
6863         }
6864       vam->async_errors = 0;
6865       after = vat_time_now (vam);
6866
6867       /* slim chance, but we might have eaten SIGTERM on the first iteration */
6868       if (j > 0)
6869         count = j;
6870
6871       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6872              count, after - before, count / (after - before));
6873     }
6874   else
6875     {
6876       int ret;
6877
6878       /* Wait for a reply... */
6879       W (ret);
6880       return ret;
6881     }
6882
6883   /* Return the good/bad news */
6884   return (vam->retval);
6885 }
6886
6887 static int
6888 api_mpls_ip_bind_unbind (vat_main_t * vam)
6889 {
6890   unformat_input_t *i = vam->input;
6891   vl_api_mpls_ip_bind_unbind_t *mp;
6892   u32 ip_table_id = 0;
6893   u8 create_table_if_needed = 0;
6894   u8 is_bind = 1;
6895   u8 is_ip4 = 1;
6896   ip4_address_t v4_address;
6897   ip6_address_t v6_address;
6898   u32 address_length;
6899   u8 address_set = 0;
6900   mpls_label_t local_label = MPLS_LABEL_INVALID;
6901   int ret;
6902
6903   /* Parse args required to build the message */
6904   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6905     {
6906       if (unformat (i, "%U/%d", unformat_ip4_address,
6907                     &v4_address, &address_length))
6908         {
6909           is_ip4 = 1;
6910           address_set = 1;
6911         }
6912       else if (unformat (i, "%U/%d", unformat_ip6_address,
6913                          &v6_address, &address_length))
6914         {
6915           is_ip4 = 0;
6916           address_set = 1;
6917         }
6918       else if (unformat (i, "%d", &local_label))
6919         ;
6920       else if (unformat (i, "create-table"))
6921         create_table_if_needed = 1;
6922       else if (unformat (i, "table-id %d", &ip_table_id))
6923         ;
6924       else if (unformat (i, "unbind"))
6925         is_bind = 0;
6926       else if (unformat (i, "bind"))
6927         is_bind = 1;
6928       else
6929         {
6930           clib_warning ("parse error '%U'", format_unformat_error, i);
6931           return -99;
6932         }
6933     }
6934
6935   if (!address_set)
6936     {
6937       errmsg ("IP addres not set");
6938       return -99;
6939     }
6940
6941   if (MPLS_LABEL_INVALID == local_label)
6942     {
6943       errmsg ("missing label");
6944       return -99;
6945     }
6946
6947   /* Construct the API message */
6948   M (MPLS_IP_BIND_UNBIND, mp);
6949
6950   mp->mb_create_table_if_needed = create_table_if_needed;
6951   mp->mb_is_bind = is_bind;
6952   mp->mb_is_ip4 = is_ip4;
6953   mp->mb_ip_table_id = ntohl (ip_table_id);
6954   mp->mb_mpls_table_id = 0;
6955   mp->mb_label = ntohl (local_label);
6956   mp->mb_address_length = address_length;
6957
6958   if (is_ip4)
6959     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
6960   else
6961     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
6962
6963   /* send it... */
6964   S (mp);
6965
6966   /* Wait for a reply... */
6967   W (ret);
6968   return ret;
6969 }
6970
6971 static int
6972 api_proxy_arp_add_del (vat_main_t * vam)
6973 {
6974   unformat_input_t *i = vam->input;
6975   vl_api_proxy_arp_add_del_t *mp;
6976   u32 vrf_id = 0;
6977   u8 is_add = 1;
6978   ip4_address_t lo, hi;
6979   u8 range_set = 0;
6980   int ret;
6981
6982   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6983     {
6984       if (unformat (i, "vrf %d", &vrf_id))
6985         ;
6986       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
6987                          unformat_ip4_address, &hi))
6988         range_set = 1;
6989       else if (unformat (i, "del"))
6990         is_add = 0;
6991       else
6992         {
6993           clib_warning ("parse error '%U'", format_unformat_error, i);
6994           return -99;
6995         }
6996     }
6997
6998   if (range_set == 0)
6999     {
7000       errmsg ("address range not set");
7001       return -99;
7002     }
7003
7004   M (PROXY_ARP_ADD_DEL, mp);
7005
7006   mp->vrf_id = ntohl (vrf_id);
7007   mp->is_add = is_add;
7008   clib_memcpy (mp->low_address, &lo, sizeof (mp->low_address));
7009   clib_memcpy (mp->hi_address, &hi, sizeof (mp->hi_address));
7010
7011   S (mp);
7012   W (ret);
7013   return ret;
7014 }
7015
7016 static int
7017 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
7018 {
7019   unformat_input_t *i = vam->input;
7020   vl_api_proxy_arp_intfc_enable_disable_t *mp;
7021   u32 sw_if_index;
7022   u8 enable = 1;
7023   u8 sw_if_index_set = 0;
7024   int ret;
7025
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 if (unformat (i, "enable"))
7033         enable = 1;
7034       else if (unformat (i, "disable"))
7035         enable = 0;
7036       else
7037         {
7038           clib_warning ("parse error '%U'", format_unformat_error, i);
7039           return -99;
7040         }
7041     }
7042
7043   if (sw_if_index_set == 0)
7044     {
7045       errmsg ("missing interface name or sw_if_index");
7046       return -99;
7047     }
7048
7049   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
7050
7051   mp->sw_if_index = ntohl (sw_if_index);
7052   mp->enable_disable = enable;
7053
7054   S (mp);
7055   W (ret);
7056   return ret;
7057 }
7058
7059 static int
7060 api_mpls_tunnel_add_del (vat_main_t * vam)
7061 {
7062   unformat_input_t *i = vam->input;
7063   vl_api_mpls_tunnel_add_del_t *mp;
7064
7065   u8 is_add = 1;
7066   u8 l2_only = 0;
7067   u32 sw_if_index = ~0;
7068   u32 next_hop_sw_if_index = ~0;
7069   u32 next_hop_proto_is_ip4 = 1;
7070
7071   u32 next_hop_table_id = 0;
7072   ip4_address_t v4_next_hop_address = {
7073     .as_u32 = 0,
7074   };
7075   ip6_address_t v6_next_hop_address = { {0} };
7076   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID, *labels = NULL;
7077   int ret;
7078
7079   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7080     {
7081       if (unformat (i, "add"))
7082         is_add = 1;
7083       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
7084         is_add = 0;
7085       else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
7086         ;
7087       else if (unformat (i, "via %U",
7088                          unformat_ip4_address, &v4_next_hop_address))
7089         {
7090           next_hop_proto_is_ip4 = 1;
7091         }
7092       else if (unformat (i, "via %U",
7093                          unformat_ip6_address, &v6_next_hop_address))
7094         {
7095           next_hop_proto_is_ip4 = 0;
7096         }
7097       else if (unformat (i, "l2-only"))
7098         l2_only = 1;
7099       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
7100         ;
7101       else if (unformat (i, "out-label %d", &next_hop_out_label))
7102         vec_add1 (labels, ntohl (next_hop_out_label));
7103       else
7104         {
7105           clib_warning ("parse error '%U'", format_unformat_error, i);
7106           return -99;
7107         }
7108     }
7109
7110   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (mpls_label_t) * vec_len (labels));
7111
7112   mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
7113   mp->mt_sw_if_index = ntohl (sw_if_index);
7114   mp->mt_is_add = is_add;
7115   mp->mt_l2_only = l2_only;
7116   mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
7117   mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
7118
7119   mp->mt_next_hop_n_out_labels = vec_len (labels);
7120
7121   if (0 != mp->mt_next_hop_n_out_labels)
7122     {
7123       clib_memcpy (mp->mt_next_hop_out_label_stack, labels,
7124                    sizeof (mpls_label_t) * mp->mt_next_hop_n_out_labels);
7125       vec_free (labels);
7126     }
7127
7128   if (next_hop_proto_is_ip4)
7129     {
7130       clib_memcpy (mp->mt_next_hop,
7131                    &v4_next_hop_address, sizeof (v4_next_hop_address));
7132     }
7133   else
7134     {
7135       clib_memcpy (mp->mt_next_hop,
7136                    &v6_next_hop_address, sizeof (v6_next_hop_address));
7137     }
7138
7139   S (mp);
7140   W (ret);
7141   return ret;
7142 }
7143
7144 static int
7145 api_sw_interface_set_unnumbered (vat_main_t * vam)
7146 {
7147   unformat_input_t *i = vam->input;
7148   vl_api_sw_interface_set_unnumbered_t *mp;
7149   u32 sw_if_index;
7150   u32 unnum_sw_index = ~0;
7151   u8 is_add = 1;
7152   u8 sw_if_index_set = 0;
7153   int ret;
7154
7155   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7156     {
7157       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7158         sw_if_index_set = 1;
7159       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7160         sw_if_index_set = 1;
7161       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
7162         ;
7163       else if (unformat (i, "del"))
7164         is_add = 0;
7165       else
7166         {
7167           clib_warning ("parse error '%U'", format_unformat_error, i);
7168           return -99;
7169         }
7170     }
7171
7172   if (sw_if_index_set == 0)
7173     {
7174       errmsg ("missing interface name or sw_if_index");
7175       return -99;
7176     }
7177
7178   M (SW_INTERFACE_SET_UNNUMBERED, mp);
7179
7180   mp->sw_if_index = ntohl (sw_if_index);
7181   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
7182   mp->is_add = is_add;
7183
7184   S (mp);
7185   W (ret);
7186   return ret;
7187 }
7188
7189 static int
7190 api_ip_neighbor_add_del (vat_main_t * vam)
7191 {
7192   unformat_input_t *i = vam->input;
7193   vl_api_ip_neighbor_add_del_t *mp;
7194   u32 sw_if_index;
7195   u8 sw_if_index_set = 0;
7196   u8 is_add = 1;
7197   u8 is_static = 0;
7198   u8 is_no_fib_entry = 0;
7199   u8 mac_address[6];
7200   u8 mac_set = 0;
7201   u8 v4_address_set = 0;
7202   u8 v6_address_set = 0;
7203   ip4_address_t v4address;
7204   ip6_address_t v6address;
7205   int ret;
7206
7207   memset (mac_address, 0, sizeof (mac_address));
7208
7209   /* Parse args required to build the message */
7210   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7211     {
7212       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7213         {
7214           mac_set = 1;
7215         }
7216       else if (unformat (i, "del"))
7217         is_add = 0;
7218       else
7219         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7220         sw_if_index_set = 1;
7221       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7222         sw_if_index_set = 1;
7223       else if (unformat (i, "is_static"))
7224         is_static = 1;
7225       else if (unformat (i, "no-fib-entry"))
7226         is_no_fib_entry = 1;
7227       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
7228         v4_address_set = 1;
7229       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
7230         v6_address_set = 1;
7231       else
7232         {
7233           clib_warning ("parse error '%U'", format_unformat_error, i);
7234           return -99;
7235         }
7236     }
7237
7238   if (sw_if_index_set == 0)
7239     {
7240       errmsg ("missing interface name or sw_if_index");
7241       return -99;
7242     }
7243   if (v4_address_set && v6_address_set)
7244     {
7245       errmsg ("both v4 and v6 addresses set");
7246       return -99;
7247     }
7248   if (!v4_address_set && !v6_address_set)
7249     {
7250       errmsg ("no address set");
7251       return -99;
7252     }
7253
7254   /* Construct the API message */
7255   M (IP_NEIGHBOR_ADD_DEL, mp);
7256
7257   mp->sw_if_index = ntohl (sw_if_index);
7258   mp->is_add = is_add;
7259   mp->is_static = is_static;
7260   mp->is_no_adj_fib = is_no_fib_entry;
7261   if (mac_set)
7262     clib_memcpy (mp->mac_address, mac_address, 6);
7263   if (v6_address_set)
7264     {
7265       mp->is_ipv6 = 1;
7266       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
7267     }
7268   else
7269     {
7270       /* mp->is_ipv6 = 0; via memset in M macro above */
7271       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
7272     }
7273
7274   /* send it... */
7275   S (mp);
7276
7277   /* Wait for a reply, return good/bad news  */
7278   W (ret);
7279   return ret;
7280 }
7281
7282 static int
7283 api_reset_vrf (vat_main_t * vam)
7284 {
7285   unformat_input_t *i = vam->input;
7286   vl_api_reset_vrf_t *mp;
7287   u32 vrf_id = 0;
7288   u8 is_ipv6 = 0;
7289   u8 vrf_id_set = 0;
7290   int ret;
7291
7292   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7293     {
7294       if (unformat (i, "vrf %d", &vrf_id))
7295         vrf_id_set = 1;
7296       else if (unformat (i, "ipv6"))
7297         is_ipv6 = 1;
7298       else
7299         {
7300           clib_warning ("parse error '%U'", format_unformat_error, i);
7301           return -99;
7302         }
7303     }
7304
7305   if (vrf_id_set == 0)
7306     {
7307       errmsg ("missing vrf id");
7308       return -99;
7309     }
7310
7311   M (RESET_VRF, mp);
7312
7313   mp->vrf_id = ntohl (vrf_id);
7314   mp->is_ipv6 = is_ipv6;
7315
7316   S (mp);
7317   W (ret);
7318   return ret;
7319 }
7320
7321 static int
7322 api_create_vlan_subif (vat_main_t * vam)
7323 {
7324   unformat_input_t *i = vam->input;
7325   vl_api_create_vlan_subif_t *mp;
7326   u32 sw_if_index;
7327   u8 sw_if_index_set = 0;
7328   u32 vlan_id;
7329   u8 vlan_id_set = 0;
7330   int ret;
7331
7332   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7333     {
7334       if (unformat (i, "sw_if_index %d", &sw_if_index))
7335         sw_if_index_set = 1;
7336       else
7337         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7338         sw_if_index_set = 1;
7339       else if (unformat (i, "vlan %d", &vlan_id))
7340         vlan_id_set = 1;
7341       else
7342         {
7343           clib_warning ("parse error '%U'", format_unformat_error, i);
7344           return -99;
7345         }
7346     }
7347
7348   if (sw_if_index_set == 0)
7349     {
7350       errmsg ("missing interface name or sw_if_index");
7351       return -99;
7352     }
7353
7354   if (vlan_id_set == 0)
7355     {
7356       errmsg ("missing vlan_id");
7357       return -99;
7358     }
7359   M (CREATE_VLAN_SUBIF, mp);
7360
7361   mp->sw_if_index = ntohl (sw_if_index);
7362   mp->vlan_id = ntohl (vlan_id);
7363
7364   S (mp);
7365   W (ret);
7366   return ret;
7367 }
7368
7369 #define foreach_create_subif_bit                \
7370 _(no_tags)                                      \
7371 _(one_tag)                                      \
7372 _(two_tags)                                     \
7373 _(dot1ad)                                       \
7374 _(exact_match)                                  \
7375 _(default_sub)                                  \
7376 _(outer_vlan_id_any)                            \
7377 _(inner_vlan_id_any)
7378
7379 static int
7380 api_create_subif (vat_main_t * vam)
7381 {
7382   unformat_input_t *i = vam->input;
7383   vl_api_create_subif_t *mp;
7384   u32 sw_if_index;
7385   u8 sw_if_index_set = 0;
7386   u32 sub_id;
7387   u8 sub_id_set = 0;
7388   u32 no_tags = 0;
7389   u32 one_tag = 0;
7390   u32 two_tags = 0;
7391   u32 dot1ad = 0;
7392   u32 exact_match = 0;
7393   u32 default_sub = 0;
7394   u32 outer_vlan_id_any = 0;
7395   u32 inner_vlan_id_any = 0;
7396   u32 tmp;
7397   u16 outer_vlan_id = 0;
7398   u16 inner_vlan_id = 0;
7399   int ret;
7400
7401   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7402     {
7403       if (unformat (i, "sw_if_index %d", &sw_if_index))
7404         sw_if_index_set = 1;
7405       else
7406         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7407         sw_if_index_set = 1;
7408       else if (unformat (i, "sub_id %d", &sub_id))
7409         sub_id_set = 1;
7410       else if (unformat (i, "outer_vlan_id %d", &tmp))
7411         outer_vlan_id = tmp;
7412       else if (unformat (i, "inner_vlan_id %d", &tmp))
7413         inner_vlan_id = tmp;
7414
7415 #define _(a) else if (unformat (i, #a)) a = 1 ;
7416       foreach_create_subif_bit
7417 #undef _
7418         else
7419         {
7420           clib_warning ("parse error '%U'", format_unformat_error, i);
7421           return -99;
7422         }
7423     }
7424
7425   if (sw_if_index_set == 0)
7426     {
7427       errmsg ("missing interface name or sw_if_index");
7428       return -99;
7429     }
7430
7431   if (sub_id_set == 0)
7432     {
7433       errmsg ("missing sub_id");
7434       return -99;
7435     }
7436   M (CREATE_SUBIF, mp);
7437
7438   mp->sw_if_index = ntohl (sw_if_index);
7439   mp->sub_id = ntohl (sub_id);
7440
7441 #define _(a) mp->a = a;
7442   foreach_create_subif_bit;
7443 #undef _
7444
7445   mp->outer_vlan_id = ntohs (outer_vlan_id);
7446   mp->inner_vlan_id = ntohs (inner_vlan_id);
7447
7448   S (mp);
7449   W (ret);
7450   return ret;
7451 }
7452
7453 static int
7454 api_oam_add_del (vat_main_t * vam)
7455 {
7456   unformat_input_t *i = vam->input;
7457   vl_api_oam_add_del_t *mp;
7458   u32 vrf_id = 0;
7459   u8 is_add = 1;
7460   ip4_address_t src, dst;
7461   u8 src_set = 0;
7462   u8 dst_set = 0;
7463   int ret;
7464
7465   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7466     {
7467       if (unformat (i, "vrf %d", &vrf_id))
7468         ;
7469       else if (unformat (i, "src %U", unformat_ip4_address, &src))
7470         src_set = 1;
7471       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
7472         dst_set = 1;
7473       else if (unformat (i, "del"))
7474         is_add = 0;
7475       else
7476         {
7477           clib_warning ("parse error '%U'", format_unformat_error, i);
7478           return -99;
7479         }
7480     }
7481
7482   if (src_set == 0)
7483     {
7484       errmsg ("missing src addr");
7485       return -99;
7486     }
7487
7488   if (dst_set == 0)
7489     {
7490       errmsg ("missing dst addr");
7491       return -99;
7492     }
7493
7494   M (OAM_ADD_DEL, mp);
7495
7496   mp->vrf_id = ntohl (vrf_id);
7497   mp->is_add = is_add;
7498   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
7499   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
7500
7501   S (mp);
7502   W (ret);
7503   return ret;
7504 }
7505
7506 static int
7507 api_reset_fib (vat_main_t * vam)
7508 {
7509   unformat_input_t *i = vam->input;
7510   vl_api_reset_fib_t *mp;
7511   u32 vrf_id = 0;
7512   u8 is_ipv6 = 0;
7513   u8 vrf_id_set = 0;
7514
7515   int ret;
7516   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7517     {
7518       if (unformat (i, "vrf %d", &vrf_id))
7519         vrf_id_set = 1;
7520       else if (unformat (i, "ipv6"))
7521         is_ipv6 = 1;
7522       else
7523         {
7524           clib_warning ("parse error '%U'", format_unformat_error, i);
7525           return -99;
7526         }
7527     }
7528
7529   if (vrf_id_set == 0)
7530     {
7531       errmsg ("missing vrf id");
7532       return -99;
7533     }
7534
7535   M (RESET_FIB, mp);
7536
7537   mp->vrf_id = ntohl (vrf_id);
7538   mp->is_ipv6 = is_ipv6;
7539
7540   S (mp);
7541   W (ret);
7542   return ret;
7543 }
7544
7545 static int
7546 api_dhcp_proxy_config (vat_main_t * vam)
7547 {
7548   unformat_input_t *i = vam->input;
7549   vl_api_dhcp_proxy_config_t *mp;
7550   u32 rx_vrf_id = 0;
7551   u32 server_vrf_id = 0;
7552   u8 is_add = 1;
7553   u8 v4_address_set = 0;
7554   u8 v6_address_set = 0;
7555   ip4_address_t v4address;
7556   ip6_address_t v6address;
7557   u8 v4_src_address_set = 0;
7558   u8 v6_src_address_set = 0;
7559   ip4_address_t v4srcaddress;
7560   ip6_address_t v6srcaddress;
7561   int ret;
7562
7563   /* Parse args required to build the message */
7564   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7565     {
7566       if (unformat (i, "del"))
7567         is_add = 0;
7568       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
7569         ;
7570       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
7571         ;
7572       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
7573         v4_address_set = 1;
7574       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
7575         v6_address_set = 1;
7576       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
7577         v4_src_address_set = 1;
7578       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
7579         v6_src_address_set = 1;
7580       else
7581         break;
7582     }
7583
7584   if (v4_address_set && v6_address_set)
7585     {
7586       errmsg ("both v4 and v6 server addresses set");
7587       return -99;
7588     }
7589   if (!v4_address_set && !v6_address_set)
7590     {
7591       errmsg ("no server addresses set");
7592       return -99;
7593     }
7594
7595   if (v4_src_address_set && v6_src_address_set)
7596     {
7597       errmsg ("both v4 and v6  src addresses set");
7598       return -99;
7599     }
7600   if (!v4_src_address_set && !v6_src_address_set)
7601     {
7602       errmsg ("no src addresses set");
7603       return -99;
7604     }
7605
7606   if (!(v4_src_address_set && v4_address_set) &&
7607       !(v6_src_address_set && v6_address_set))
7608     {
7609       errmsg ("no matching server and src addresses set");
7610       return -99;
7611     }
7612
7613   /* Construct the API message */
7614   M (DHCP_PROXY_CONFIG, mp);
7615
7616   mp->is_add = is_add;
7617   mp->rx_vrf_id = ntohl (rx_vrf_id);
7618   mp->server_vrf_id = ntohl (server_vrf_id);
7619   if (v6_address_set)
7620     {
7621       mp->is_ipv6 = 1;
7622       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
7623       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
7624     }
7625   else
7626     {
7627       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
7628       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
7629     }
7630
7631   /* send it... */
7632   S (mp);
7633
7634   /* Wait for a reply, return good/bad news  */
7635   W (ret);
7636   return ret;
7637 }
7638
7639 #define vl_api_dhcp_proxy_details_t_endian vl_noop_handler
7640 #define vl_api_dhcp_proxy_details_t_print vl_noop_handler
7641
7642 static void
7643 vl_api_dhcp_proxy_details_t_handler (vl_api_dhcp_proxy_details_t * mp)
7644 {
7645   vat_main_t *vam = &vat_main;
7646   u32 i, count = mp->count;
7647   vl_api_dhcp_server_t *s;
7648
7649   if (mp->is_ipv6)
7650     print (vam->ofp,
7651            "RX Table-ID %d, Source Address %U, VSS FIB-ID %d, VSS OUI %d",
7652            ntohl (mp->rx_vrf_id),
7653            format_ip6_address, mp->dhcp_src_address,
7654            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
7655   else
7656     print (vam->ofp,
7657            "RX Table-ID %d, Source Address %U, VSS FIB-ID %d, VSS OUI %d",
7658            ntohl (mp->rx_vrf_id),
7659            format_ip4_address, mp->dhcp_src_address,
7660            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
7661
7662   for (i = 0; i < count; i++)
7663     {
7664       s = &mp->servers[i];
7665
7666       if (mp->is_ipv6)
7667         print (vam->ofp,
7668                " Server Table-ID %d, Server Address %U",
7669                ntohl (s->server_vrf_id), format_ip6_address, s->dhcp_server);
7670       else
7671         print (vam->ofp,
7672                " Server Table-ID %d, Server Address %U",
7673                ntohl (s->server_vrf_id), format_ip4_address, s->dhcp_server);
7674     }
7675 }
7676
7677 static void vl_api_dhcp_proxy_details_t_handler_json
7678   (vl_api_dhcp_proxy_details_t * mp)
7679 {
7680   vat_main_t *vam = &vat_main;
7681   vat_json_node_t *node = NULL;
7682   u32 i, count = mp->count;
7683   struct in_addr ip4;
7684   struct in6_addr ip6;
7685   vl_api_dhcp_server_t *s;
7686
7687   if (VAT_JSON_ARRAY != vam->json_tree.type)
7688     {
7689       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
7690       vat_json_init_array (&vam->json_tree);
7691     }
7692   node = vat_json_array_add (&vam->json_tree);
7693
7694   vat_json_init_object (node);
7695   vat_json_object_add_uint (node, "rx-table-id", ntohl (mp->rx_vrf_id));
7696   vat_json_object_add_uint (node, "vss-fib-id", ntohl (mp->vss_fib_id));
7697   vat_json_object_add_uint (node, "vss-oui", ntohl (mp->vss_oui));
7698
7699   if (mp->is_ipv6)
7700     {
7701       clib_memcpy (&ip6, &mp->dhcp_src_address, sizeof (ip6));
7702       vat_json_object_add_ip6 (node, "src_address", ip6);
7703     }
7704   else
7705     {
7706       clib_memcpy (&ip4, &mp->dhcp_src_address, sizeof (ip4));
7707       vat_json_object_add_ip4 (node, "src_address", ip4);
7708     }
7709
7710   for (i = 0; i < count; i++)
7711     {
7712       s = &mp->servers[i];
7713
7714       vat_json_object_add_uint (node, "server-table-id",
7715                                 ntohl (s->server_vrf_id));
7716
7717       if (mp->is_ipv6)
7718         {
7719           clib_memcpy (&ip4, &s->dhcp_server, sizeof (ip4));
7720           vat_json_object_add_ip4 (node, "src_address", ip4);
7721         }
7722       else
7723         {
7724           clib_memcpy (&ip6, &s->dhcp_server, sizeof (ip6));
7725           vat_json_object_add_ip6 (node, "server_address", ip6);
7726         }
7727     }
7728 }
7729
7730 static int
7731 api_dhcp_proxy_dump (vat_main_t * vam)
7732 {
7733   unformat_input_t *i = vam->input;
7734   vl_api_control_ping_t *mp_ping;
7735   vl_api_dhcp_proxy_dump_t *mp;
7736   u8 is_ipv6 = 0;
7737   int ret;
7738
7739   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7740     {
7741       if (unformat (i, "ipv6"))
7742         is_ipv6 = 1;
7743       else
7744         {
7745           clib_warning ("parse error '%U'", format_unformat_error, i);
7746           return -99;
7747         }
7748     }
7749
7750   M (DHCP_PROXY_DUMP, mp);
7751
7752   mp->is_ip6 = is_ipv6;
7753   S (mp);
7754
7755   /* Use a control ping for synchronization */
7756   M (CONTROL_PING, mp_ping);
7757   S (mp_ping);
7758
7759   W (ret);
7760   return ret;
7761 }
7762
7763 static int
7764 api_dhcp_proxy_set_vss (vat_main_t * vam)
7765 {
7766   unformat_input_t *i = vam->input;
7767   vl_api_dhcp_proxy_set_vss_t *mp;
7768   u8 is_ipv6 = 0;
7769   u8 is_add = 1;
7770   u32 tbl_id;
7771   u8 tbl_id_set = 0;
7772   u32 oui;
7773   u8 oui_set = 0;
7774   u32 fib_id;
7775   u8 fib_id_set = 0;
7776   int ret;
7777
7778   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7779     {
7780       if (unformat (i, "tbl_id %d", &tbl_id))
7781         tbl_id_set = 1;
7782       if (unformat (i, "fib_id %d", &fib_id))
7783         fib_id_set = 1;
7784       if (unformat (i, "oui %d", &oui))
7785         oui_set = 1;
7786       else if (unformat (i, "ipv6"))
7787         is_ipv6 = 1;
7788       else if (unformat (i, "del"))
7789         is_add = 0;
7790       else
7791         {
7792           clib_warning ("parse error '%U'", format_unformat_error, i);
7793           return -99;
7794         }
7795     }
7796
7797   if (tbl_id_set == 0)
7798     {
7799       errmsg ("missing tbl id");
7800       return -99;
7801     }
7802
7803   if (fib_id_set == 0)
7804     {
7805       errmsg ("missing fib id");
7806       return -99;
7807     }
7808   if (oui_set == 0)
7809     {
7810       errmsg ("missing oui");
7811       return -99;
7812     }
7813
7814   M (DHCP_PROXY_SET_VSS, mp);
7815   mp->tbl_id = ntohl (tbl_id);
7816   mp->fib_id = ntohl (fib_id);
7817   mp->oui = ntohl (oui);
7818   mp->is_ipv6 = is_ipv6;
7819   mp->is_add = is_add;
7820
7821   S (mp);
7822   W (ret);
7823   return ret;
7824 }
7825
7826 static int
7827 api_dhcp_client_config (vat_main_t * vam)
7828 {
7829   unformat_input_t *i = vam->input;
7830   vl_api_dhcp_client_config_t *mp;
7831   u32 sw_if_index;
7832   u8 sw_if_index_set = 0;
7833   u8 is_add = 1;
7834   u8 *hostname = 0;
7835   u8 disable_event = 0;
7836   int ret;
7837
7838   /* Parse args required to build the message */
7839   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7840     {
7841       if (unformat (i, "del"))
7842         is_add = 0;
7843       else
7844         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7845         sw_if_index_set = 1;
7846       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7847         sw_if_index_set = 1;
7848       else if (unformat (i, "hostname %s", &hostname))
7849         ;
7850       else if (unformat (i, "disable_event"))
7851         disable_event = 1;
7852       else
7853         break;
7854     }
7855
7856   if (sw_if_index_set == 0)
7857     {
7858       errmsg ("missing interface name or sw_if_index");
7859       return -99;
7860     }
7861
7862   if (vec_len (hostname) > 63)
7863     {
7864       errmsg ("hostname too long");
7865     }
7866   vec_add1 (hostname, 0);
7867
7868   /* Construct the API message */
7869   M (DHCP_CLIENT_CONFIG, mp);
7870
7871   mp->sw_if_index = ntohl (sw_if_index);
7872   clib_memcpy (mp->hostname, hostname, vec_len (hostname));
7873   vec_free (hostname);
7874   mp->is_add = is_add;
7875   mp->want_dhcp_event = disable_event ? 0 : 1;
7876   mp->pid = getpid ();
7877
7878   /* send it... */
7879   S (mp);
7880
7881   /* Wait for a reply, return good/bad news  */
7882   W (ret);
7883   return ret;
7884 }
7885
7886 static int
7887 api_set_ip_flow_hash (vat_main_t * vam)
7888 {
7889   unformat_input_t *i = vam->input;
7890   vl_api_set_ip_flow_hash_t *mp;
7891   u32 vrf_id = 0;
7892   u8 is_ipv6 = 0;
7893   u8 vrf_id_set = 0;
7894   u8 src = 0;
7895   u8 dst = 0;
7896   u8 sport = 0;
7897   u8 dport = 0;
7898   u8 proto = 0;
7899   u8 reverse = 0;
7900   int ret;
7901
7902   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7903     {
7904       if (unformat (i, "vrf %d", &vrf_id))
7905         vrf_id_set = 1;
7906       else if (unformat (i, "ipv6"))
7907         is_ipv6 = 1;
7908       else if (unformat (i, "src"))
7909         src = 1;
7910       else if (unformat (i, "dst"))
7911         dst = 1;
7912       else if (unformat (i, "sport"))
7913         sport = 1;
7914       else if (unformat (i, "dport"))
7915         dport = 1;
7916       else if (unformat (i, "proto"))
7917         proto = 1;
7918       else if (unformat (i, "reverse"))
7919         reverse = 1;
7920
7921       else
7922         {
7923           clib_warning ("parse error '%U'", format_unformat_error, i);
7924           return -99;
7925         }
7926     }
7927
7928   if (vrf_id_set == 0)
7929     {
7930       errmsg ("missing vrf id");
7931       return -99;
7932     }
7933
7934   M (SET_IP_FLOW_HASH, mp);
7935   mp->src = src;
7936   mp->dst = dst;
7937   mp->sport = sport;
7938   mp->dport = dport;
7939   mp->proto = proto;
7940   mp->reverse = reverse;
7941   mp->vrf_id = ntohl (vrf_id);
7942   mp->is_ipv6 = is_ipv6;
7943
7944   S (mp);
7945   W (ret);
7946   return ret;
7947 }
7948
7949 static int
7950 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
7951 {
7952   unformat_input_t *i = vam->input;
7953   vl_api_sw_interface_ip6_enable_disable_t *mp;
7954   u32 sw_if_index;
7955   u8 sw_if_index_set = 0;
7956   u8 enable = 0;
7957   int ret;
7958
7959   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7960     {
7961       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7962         sw_if_index_set = 1;
7963       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7964         sw_if_index_set = 1;
7965       else if (unformat (i, "enable"))
7966         enable = 1;
7967       else if (unformat (i, "disable"))
7968         enable = 0;
7969       else
7970         {
7971           clib_warning ("parse error '%U'", format_unformat_error, i);
7972           return -99;
7973         }
7974     }
7975
7976   if (sw_if_index_set == 0)
7977     {
7978       errmsg ("missing interface name or sw_if_index");
7979       return -99;
7980     }
7981
7982   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
7983
7984   mp->sw_if_index = ntohl (sw_if_index);
7985   mp->enable = enable;
7986
7987   S (mp);
7988   W (ret);
7989   return ret;
7990 }
7991
7992 static int
7993 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
7994 {
7995   unformat_input_t *i = vam->input;
7996   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
7997   u32 sw_if_index;
7998   u8 sw_if_index_set = 0;
7999   u8 v6_address_set = 0;
8000   ip6_address_t v6address;
8001   int ret;
8002
8003   /* Parse args required to build the message */
8004   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8005     {
8006       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8007         sw_if_index_set = 1;
8008       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8009         sw_if_index_set = 1;
8010       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
8011         v6_address_set = 1;
8012       else
8013         break;
8014     }
8015
8016   if (sw_if_index_set == 0)
8017     {
8018       errmsg ("missing interface name or sw_if_index");
8019       return -99;
8020     }
8021   if (!v6_address_set)
8022     {
8023       errmsg ("no address set");
8024       return -99;
8025     }
8026
8027   /* Construct the API message */
8028   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS, mp);
8029
8030   mp->sw_if_index = ntohl (sw_if_index);
8031   clib_memcpy (mp->address, &v6address, sizeof (v6address));
8032
8033   /* send it... */
8034   S (mp);
8035
8036   /* Wait for a reply, return good/bad news  */
8037   W (ret);
8038   return ret;
8039 }
8040
8041 static int
8042 api_ip6nd_proxy_add_del (vat_main_t * vam)
8043 {
8044   unformat_input_t *i = vam->input;
8045   vl_api_ip6nd_proxy_add_del_t *mp;
8046   u32 sw_if_index = ~0;
8047   u8 v6_address_set = 0;
8048   ip6_address_t v6address;
8049   u8 is_del = 0;
8050   int ret;
8051
8052   /* Parse args required to build the message */
8053   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8054     {
8055       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8056         ;
8057       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8058         ;
8059       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
8060         v6_address_set = 1;
8061       if (unformat (i, "del"))
8062         is_del = 1;
8063       else
8064         {
8065           clib_warning ("parse error '%U'", format_unformat_error, i);
8066           return -99;
8067         }
8068     }
8069
8070   if (sw_if_index == ~0)
8071     {
8072       errmsg ("missing interface name or sw_if_index");
8073       return -99;
8074     }
8075   if (!v6_address_set)
8076     {
8077       errmsg ("no address set");
8078       return -99;
8079     }
8080
8081   /* Construct the API message */
8082   M (IP6ND_PROXY_ADD_DEL, mp);
8083
8084   mp->is_del = is_del;
8085   mp->sw_if_index = ntohl (sw_if_index);
8086   clib_memcpy (mp->address, &v6address, sizeof (v6address));
8087
8088   /* send it... */
8089   S (mp);
8090
8091   /* Wait for a reply, return good/bad news  */
8092   W (ret);
8093   return ret;
8094 }
8095
8096 static int
8097 api_ip6nd_proxy_dump (vat_main_t * vam)
8098 {
8099   vl_api_ip6nd_proxy_dump_t *mp;
8100   vl_api_control_ping_t *mp_ping;
8101   int ret;
8102
8103   M (IP6ND_PROXY_DUMP, mp);
8104
8105   S (mp);
8106
8107   /* Use a control ping for synchronization */
8108   M (CONTROL_PING, mp_ping);
8109   S (mp_ping);
8110
8111   W (ret);
8112   return ret;
8113 }
8114
8115 static void vl_api_ip6nd_proxy_details_t_handler
8116   (vl_api_ip6nd_proxy_details_t * mp)
8117 {
8118   vat_main_t *vam = &vat_main;
8119
8120   print (vam->ofp, "host %U sw_if_index %d",
8121          format_ip6_address, mp->address, ntohl (mp->sw_if_index));
8122 }
8123
8124 static void vl_api_ip6nd_proxy_details_t_handler_json
8125   (vl_api_ip6nd_proxy_details_t * mp)
8126 {
8127   vat_main_t *vam = &vat_main;
8128   struct in6_addr ip6;
8129   vat_json_node_t *node = NULL;
8130
8131   if (VAT_JSON_ARRAY != vam->json_tree.type)
8132     {
8133       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
8134       vat_json_init_array (&vam->json_tree);
8135     }
8136   node = vat_json_array_add (&vam->json_tree);
8137
8138   vat_json_init_object (node);
8139   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
8140
8141   clib_memcpy (&ip6, mp->address, sizeof (ip6));
8142   vat_json_object_add_ip6 (node, "host", ip6);
8143 }
8144
8145 static int
8146 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
8147 {
8148   unformat_input_t *i = vam->input;
8149   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
8150   u32 sw_if_index;
8151   u8 sw_if_index_set = 0;
8152   u32 address_length = 0;
8153   u8 v6_address_set = 0;
8154   ip6_address_t v6address;
8155   u8 use_default = 0;
8156   u8 no_advertise = 0;
8157   u8 off_link = 0;
8158   u8 no_autoconfig = 0;
8159   u8 no_onlink = 0;
8160   u8 is_no = 0;
8161   u32 val_lifetime = 0;
8162   u32 pref_lifetime = 0;
8163   int ret;
8164
8165   /* Parse args required to build the message */
8166   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8167     {
8168       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8169         sw_if_index_set = 1;
8170       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8171         sw_if_index_set = 1;
8172       else if (unformat (i, "%U/%d",
8173                          unformat_ip6_address, &v6address, &address_length))
8174         v6_address_set = 1;
8175       else if (unformat (i, "val_life %d", &val_lifetime))
8176         ;
8177       else if (unformat (i, "pref_life %d", &pref_lifetime))
8178         ;
8179       else if (unformat (i, "def"))
8180         use_default = 1;
8181       else if (unformat (i, "noadv"))
8182         no_advertise = 1;
8183       else if (unformat (i, "offl"))
8184         off_link = 1;
8185       else if (unformat (i, "noauto"))
8186         no_autoconfig = 1;
8187       else if (unformat (i, "nolink"))
8188         no_onlink = 1;
8189       else if (unformat (i, "isno"))
8190         is_no = 1;
8191       else
8192         {
8193           clib_warning ("parse error '%U'", format_unformat_error, i);
8194           return -99;
8195         }
8196     }
8197
8198   if (sw_if_index_set == 0)
8199     {
8200       errmsg ("missing interface name or sw_if_index");
8201       return -99;
8202     }
8203   if (!v6_address_set)
8204     {
8205       errmsg ("no address set");
8206       return -99;
8207     }
8208
8209   /* Construct the API message */
8210   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
8211
8212   mp->sw_if_index = ntohl (sw_if_index);
8213   clib_memcpy (mp->address, &v6address, sizeof (v6address));
8214   mp->address_length = address_length;
8215   mp->use_default = use_default;
8216   mp->no_advertise = no_advertise;
8217   mp->off_link = off_link;
8218   mp->no_autoconfig = no_autoconfig;
8219   mp->no_onlink = no_onlink;
8220   mp->is_no = is_no;
8221   mp->val_lifetime = ntohl (val_lifetime);
8222   mp->pref_lifetime = ntohl (pref_lifetime);
8223
8224   /* send it... */
8225   S (mp);
8226
8227   /* Wait for a reply, return good/bad news  */
8228   W (ret);
8229   return ret;
8230 }
8231
8232 static int
8233 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
8234 {
8235   unformat_input_t *i = vam->input;
8236   vl_api_sw_interface_ip6nd_ra_config_t *mp;
8237   u32 sw_if_index;
8238   u8 sw_if_index_set = 0;
8239   u8 suppress = 0;
8240   u8 managed = 0;
8241   u8 other = 0;
8242   u8 ll_option = 0;
8243   u8 send_unicast = 0;
8244   u8 cease = 0;
8245   u8 is_no = 0;
8246   u8 default_router = 0;
8247   u32 max_interval = 0;
8248   u32 min_interval = 0;
8249   u32 lifetime = 0;
8250   u32 initial_count = 0;
8251   u32 initial_interval = 0;
8252   int ret;
8253
8254
8255   /* Parse args required to build the message */
8256   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8257     {
8258       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8259         sw_if_index_set = 1;
8260       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8261         sw_if_index_set = 1;
8262       else if (unformat (i, "maxint %d", &max_interval))
8263         ;
8264       else if (unformat (i, "minint %d", &min_interval))
8265         ;
8266       else if (unformat (i, "life %d", &lifetime))
8267         ;
8268       else if (unformat (i, "count %d", &initial_count))
8269         ;
8270       else if (unformat (i, "interval %d", &initial_interval))
8271         ;
8272       else if (unformat (i, "suppress") || unformat (i, "surpress"))
8273         suppress = 1;
8274       else if (unformat (i, "managed"))
8275         managed = 1;
8276       else if (unformat (i, "other"))
8277         other = 1;
8278       else if (unformat (i, "ll"))
8279         ll_option = 1;
8280       else if (unformat (i, "send"))
8281         send_unicast = 1;
8282       else if (unformat (i, "cease"))
8283         cease = 1;
8284       else if (unformat (i, "isno"))
8285         is_no = 1;
8286       else if (unformat (i, "def"))
8287         default_router = 1;
8288       else
8289         {
8290           clib_warning ("parse error '%U'", format_unformat_error, i);
8291           return -99;
8292         }
8293     }
8294
8295   if (sw_if_index_set == 0)
8296     {
8297       errmsg ("missing interface name or sw_if_index");
8298       return -99;
8299     }
8300
8301   /* Construct the API message */
8302   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
8303
8304   mp->sw_if_index = ntohl (sw_if_index);
8305   mp->max_interval = ntohl (max_interval);
8306   mp->min_interval = ntohl (min_interval);
8307   mp->lifetime = ntohl (lifetime);
8308   mp->initial_count = ntohl (initial_count);
8309   mp->initial_interval = ntohl (initial_interval);
8310   mp->suppress = suppress;
8311   mp->managed = managed;
8312   mp->other = other;
8313   mp->ll_option = ll_option;
8314   mp->send_unicast = send_unicast;
8315   mp->cease = cease;
8316   mp->is_no = is_no;
8317   mp->default_router = default_router;
8318
8319   /* send it... */
8320   S (mp);
8321
8322   /* Wait for a reply, return good/bad news  */
8323   W (ret);
8324   return ret;
8325 }
8326
8327 static int
8328 api_set_arp_neighbor_limit (vat_main_t * vam)
8329 {
8330   unformat_input_t *i = vam->input;
8331   vl_api_set_arp_neighbor_limit_t *mp;
8332   u32 arp_nbr_limit;
8333   u8 limit_set = 0;
8334   u8 is_ipv6 = 0;
8335   int ret;
8336
8337   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8338     {
8339       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
8340         limit_set = 1;
8341       else if (unformat (i, "ipv6"))
8342         is_ipv6 = 1;
8343       else
8344         {
8345           clib_warning ("parse error '%U'", format_unformat_error, i);
8346           return -99;
8347         }
8348     }
8349
8350   if (limit_set == 0)
8351     {
8352       errmsg ("missing limit value");
8353       return -99;
8354     }
8355
8356   M (SET_ARP_NEIGHBOR_LIMIT, mp);
8357
8358   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
8359   mp->is_ipv6 = is_ipv6;
8360
8361   S (mp);
8362   W (ret);
8363   return ret;
8364 }
8365
8366 static int
8367 api_l2_patch_add_del (vat_main_t * vam)
8368 {
8369   unformat_input_t *i = vam->input;
8370   vl_api_l2_patch_add_del_t *mp;
8371   u32 rx_sw_if_index;
8372   u8 rx_sw_if_index_set = 0;
8373   u32 tx_sw_if_index;
8374   u8 tx_sw_if_index_set = 0;
8375   u8 is_add = 1;
8376   int ret;
8377
8378   /* Parse args required to build the message */
8379   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8380     {
8381       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
8382         rx_sw_if_index_set = 1;
8383       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
8384         tx_sw_if_index_set = 1;
8385       else if (unformat (i, "rx"))
8386         {
8387           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8388             {
8389               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
8390                             &rx_sw_if_index))
8391                 rx_sw_if_index_set = 1;
8392             }
8393           else
8394             break;
8395         }
8396       else if (unformat (i, "tx"))
8397         {
8398           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8399             {
8400               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
8401                             &tx_sw_if_index))
8402                 tx_sw_if_index_set = 1;
8403             }
8404           else
8405             break;
8406         }
8407       else if (unformat (i, "del"))
8408         is_add = 0;
8409       else
8410         break;
8411     }
8412
8413   if (rx_sw_if_index_set == 0)
8414     {
8415       errmsg ("missing rx interface name or rx_sw_if_index");
8416       return -99;
8417     }
8418
8419   if (tx_sw_if_index_set == 0)
8420     {
8421       errmsg ("missing tx interface name or tx_sw_if_index");
8422       return -99;
8423     }
8424
8425   M (L2_PATCH_ADD_DEL, mp);
8426
8427   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
8428   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
8429   mp->is_add = is_add;
8430
8431   S (mp);
8432   W (ret);
8433   return ret;
8434 }
8435
8436 u8 is_del;
8437 u8 localsid_addr[16];
8438 u8 end_psp;
8439 u8 behavior;
8440 u32 sw_if_index;
8441 u32 vlan_index;
8442 u32 fib_table;
8443 u8 nh_addr[16];
8444
8445 static int
8446 api_sr_localsid_add_del (vat_main_t * vam)
8447 {
8448   unformat_input_t *i = vam->input;
8449   vl_api_sr_localsid_add_del_t *mp;
8450
8451   u8 is_del;
8452   ip6_address_t localsid;
8453   u8 end_psp = 0;
8454   u8 behavior = ~0;
8455   u32 sw_if_index;
8456   u32 fib_table = ~(u32) 0;
8457   ip6_address_t next_hop;
8458
8459   bool nexthop_set = 0;
8460
8461   int ret;
8462
8463   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8464     {
8465       if (unformat (i, "del"))
8466         is_del = 1;
8467       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
8468       else if (unformat (i, "next-hop %U", unformat_ip6_address, &next_hop))
8469         nexthop_set = 1;
8470       else if (unformat (i, "behavior %u", &behavior));
8471       else if (unformat (i, "sw_if_index %u", &sw_if_index));
8472       else if (unformat (i, "fib-table %u", &fib_table));
8473       else if (unformat (i, "end.psp %u", &behavior));
8474       else
8475         break;
8476     }
8477
8478   M (SR_LOCALSID_ADD_DEL, mp);
8479
8480   clib_memcpy (mp->localsid_addr, &localsid, sizeof (mp->localsid_addr));
8481   if (nexthop_set)
8482     clib_memcpy (mp->nh_addr, &next_hop, sizeof (mp->nh_addr));
8483   mp->behavior = behavior;
8484   mp->sw_if_index = ntohl (sw_if_index);
8485   mp->fib_table = ntohl (fib_table);
8486   mp->end_psp = end_psp;
8487   mp->is_del = is_del;
8488
8489   S (mp);
8490   W (ret);
8491   return ret;
8492 }
8493
8494 static int
8495 api_ioam_enable (vat_main_t * vam)
8496 {
8497   unformat_input_t *input = vam->input;
8498   vl_api_ioam_enable_t *mp;
8499   u32 id = 0;
8500   int has_trace_option = 0;
8501   int has_pot_option = 0;
8502   int has_seqno_option = 0;
8503   int has_analyse_option = 0;
8504   int ret;
8505
8506   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8507     {
8508       if (unformat (input, "trace"))
8509         has_trace_option = 1;
8510       else if (unformat (input, "pot"))
8511         has_pot_option = 1;
8512       else if (unformat (input, "seqno"))
8513         has_seqno_option = 1;
8514       else if (unformat (input, "analyse"))
8515         has_analyse_option = 1;
8516       else
8517         break;
8518     }
8519   M (IOAM_ENABLE, mp);
8520   mp->id = htons (id);
8521   mp->seqno = has_seqno_option;
8522   mp->analyse = has_analyse_option;
8523   mp->pot_enable = has_pot_option;
8524   mp->trace_enable = has_trace_option;
8525
8526   S (mp);
8527   W (ret);
8528   return ret;
8529 }
8530
8531
8532 static int
8533 api_ioam_disable (vat_main_t * vam)
8534 {
8535   vl_api_ioam_disable_t *mp;
8536   int ret;
8537
8538   M (IOAM_DISABLE, mp);
8539   S (mp);
8540   W (ret);
8541   return ret;
8542 }
8543
8544 #define foreach_tcp_proto_field                 \
8545 _(src_port)                                     \
8546 _(dst_port)
8547
8548 #define foreach_udp_proto_field                 \
8549 _(src_port)                                     \
8550 _(dst_port)
8551
8552 #define foreach_ip4_proto_field                 \
8553 _(src_address)                                  \
8554 _(dst_address)                                  \
8555 _(tos)                                          \
8556 _(length)                                       \
8557 _(fragment_id)                                  \
8558 _(ttl)                                          \
8559 _(protocol)                                     \
8560 _(checksum)
8561
8562 typedef struct
8563 {
8564   u16 src_port, dst_port;
8565 } tcpudp_header_t;
8566
8567 #if VPP_API_TEST_BUILTIN == 0
8568 uword
8569 unformat_tcp_mask (unformat_input_t * input, va_list * args)
8570 {
8571   u8 **maskp = va_arg (*args, u8 **);
8572   u8 *mask = 0;
8573   u8 found_something = 0;
8574   tcp_header_t *tcp;
8575
8576 #define _(a) u8 a=0;
8577   foreach_tcp_proto_field;
8578 #undef _
8579
8580   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8581     {
8582       if (0);
8583 #define _(a) else if (unformat (input, #a)) a=1;
8584       foreach_tcp_proto_field
8585 #undef _
8586         else
8587         break;
8588     }
8589
8590 #define _(a) found_something += a;
8591   foreach_tcp_proto_field;
8592 #undef _
8593
8594   if (found_something == 0)
8595     return 0;
8596
8597   vec_validate (mask, sizeof (*tcp) - 1);
8598
8599   tcp = (tcp_header_t *) mask;
8600
8601 #define _(a) if (a) memset (&tcp->a, 0xff, sizeof (tcp->a));
8602   foreach_tcp_proto_field;
8603 #undef _
8604
8605   *maskp = mask;
8606   return 1;
8607 }
8608
8609 uword
8610 unformat_udp_mask (unformat_input_t * input, va_list * args)
8611 {
8612   u8 **maskp = va_arg (*args, u8 **);
8613   u8 *mask = 0;
8614   u8 found_something = 0;
8615   udp_header_t *udp;
8616
8617 #define _(a) u8 a=0;
8618   foreach_udp_proto_field;
8619 #undef _
8620
8621   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8622     {
8623       if (0);
8624 #define _(a) else if (unformat (input, #a)) a=1;
8625       foreach_udp_proto_field
8626 #undef _
8627         else
8628         break;
8629     }
8630
8631 #define _(a) found_something += a;
8632   foreach_udp_proto_field;
8633 #undef _
8634
8635   if (found_something == 0)
8636     return 0;
8637
8638   vec_validate (mask, sizeof (*udp) - 1);
8639
8640   udp = (udp_header_t *) mask;
8641
8642 #define _(a) if (a) memset (&udp->a, 0xff, sizeof (udp->a));
8643   foreach_udp_proto_field;
8644 #undef _
8645
8646   *maskp = mask;
8647   return 1;
8648 }
8649
8650 uword
8651 unformat_l4_mask (unformat_input_t * input, va_list * args)
8652 {
8653   u8 **maskp = va_arg (*args, u8 **);
8654   u16 src_port = 0, dst_port = 0;
8655   tcpudp_header_t *tcpudp;
8656
8657   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8658     {
8659       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
8660         return 1;
8661       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
8662         return 1;
8663       else if (unformat (input, "src_port"))
8664         src_port = 0xFFFF;
8665       else if (unformat (input, "dst_port"))
8666         dst_port = 0xFFFF;
8667       else
8668         return 0;
8669     }
8670
8671   if (!src_port && !dst_port)
8672     return 0;
8673
8674   u8 *mask = 0;
8675   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
8676
8677   tcpudp = (tcpudp_header_t *) mask;
8678   tcpudp->src_port = src_port;
8679   tcpudp->dst_port = dst_port;
8680
8681   *maskp = mask;
8682
8683   return 1;
8684 }
8685
8686 uword
8687 unformat_ip4_mask (unformat_input_t * input, va_list * args)
8688 {
8689   u8 **maskp = va_arg (*args, u8 **);
8690   u8 *mask = 0;
8691   u8 found_something = 0;
8692   ip4_header_t *ip;
8693
8694 #define _(a) u8 a=0;
8695   foreach_ip4_proto_field;
8696 #undef _
8697   u8 version = 0;
8698   u8 hdr_length = 0;
8699
8700
8701   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8702     {
8703       if (unformat (input, "version"))
8704         version = 1;
8705       else if (unformat (input, "hdr_length"))
8706         hdr_length = 1;
8707       else if (unformat (input, "src"))
8708         src_address = 1;
8709       else if (unformat (input, "dst"))
8710         dst_address = 1;
8711       else if (unformat (input, "proto"))
8712         protocol = 1;
8713
8714 #define _(a) else if (unformat (input, #a)) a=1;
8715       foreach_ip4_proto_field
8716 #undef _
8717         else
8718         break;
8719     }
8720
8721 #define _(a) found_something += a;
8722   foreach_ip4_proto_field;
8723 #undef _
8724
8725   if (found_something == 0)
8726     return 0;
8727
8728   vec_validate (mask, sizeof (*ip) - 1);
8729
8730   ip = (ip4_header_t *) mask;
8731
8732 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
8733   foreach_ip4_proto_field;
8734 #undef _
8735
8736   ip->ip_version_and_header_length = 0;
8737
8738   if (version)
8739     ip->ip_version_and_header_length |= 0xF0;
8740
8741   if (hdr_length)
8742     ip->ip_version_and_header_length |= 0x0F;
8743
8744   *maskp = mask;
8745   return 1;
8746 }
8747
8748 #define foreach_ip6_proto_field                 \
8749 _(src_address)                                  \
8750 _(dst_address)                                  \
8751 _(payload_length)                               \
8752 _(hop_limit)                                    \
8753 _(protocol)
8754
8755 uword
8756 unformat_ip6_mask (unformat_input_t * input, va_list * args)
8757 {
8758   u8 **maskp = va_arg (*args, u8 **);
8759   u8 *mask = 0;
8760   u8 found_something = 0;
8761   ip6_header_t *ip;
8762   u32 ip_version_traffic_class_and_flow_label;
8763
8764 #define _(a) u8 a=0;
8765   foreach_ip6_proto_field;
8766 #undef _
8767   u8 version = 0;
8768   u8 traffic_class = 0;
8769   u8 flow_label = 0;
8770
8771   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8772     {
8773       if (unformat (input, "version"))
8774         version = 1;
8775       else if (unformat (input, "traffic-class"))
8776         traffic_class = 1;
8777       else if (unformat (input, "flow-label"))
8778         flow_label = 1;
8779       else if (unformat (input, "src"))
8780         src_address = 1;
8781       else if (unformat (input, "dst"))
8782         dst_address = 1;
8783       else if (unformat (input, "proto"))
8784         protocol = 1;
8785
8786 #define _(a) else if (unformat (input, #a)) a=1;
8787       foreach_ip6_proto_field
8788 #undef _
8789         else
8790         break;
8791     }
8792
8793 #define _(a) found_something += a;
8794   foreach_ip6_proto_field;
8795 #undef _
8796
8797   if (found_something == 0)
8798     return 0;
8799
8800   vec_validate (mask, sizeof (*ip) - 1);
8801
8802   ip = (ip6_header_t *) mask;
8803
8804 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
8805   foreach_ip6_proto_field;
8806 #undef _
8807
8808   ip_version_traffic_class_and_flow_label = 0;
8809
8810   if (version)
8811     ip_version_traffic_class_and_flow_label |= 0xF0000000;
8812
8813   if (traffic_class)
8814     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
8815
8816   if (flow_label)
8817     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
8818
8819   ip->ip_version_traffic_class_and_flow_label =
8820     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
8821
8822   *maskp = mask;
8823   return 1;
8824 }
8825
8826 uword
8827 unformat_l3_mask (unformat_input_t * input, va_list * args)
8828 {
8829   u8 **maskp = va_arg (*args, u8 **);
8830
8831   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8832     {
8833       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
8834         return 1;
8835       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
8836         return 1;
8837       else
8838         break;
8839     }
8840   return 0;
8841 }
8842
8843 uword
8844 unformat_l2_mask (unformat_input_t * input, va_list * args)
8845 {
8846   u8 **maskp = va_arg (*args, u8 **);
8847   u8 *mask = 0;
8848   u8 src = 0;
8849   u8 dst = 0;
8850   u8 proto = 0;
8851   u8 tag1 = 0;
8852   u8 tag2 = 0;
8853   u8 ignore_tag1 = 0;
8854   u8 ignore_tag2 = 0;
8855   u8 cos1 = 0;
8856   u8 cos2 = 0;
8857   u8 dot1q = 0;
8858   u8 dot1ad = 0;
8859   int len = 14;
8860
8861   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8862     {
8863       if (unformat (input, "src"))
8864         src = 1;
8865       else if (unformat (input, "dst"))
8866         dst = 1;
8867       else if (unformat (input, "proto"))
8868         proto = 1;
8869       else if (unformat (input, "tag1"))
8870         tag1 = 1;
8871       else if (unformat (input, "tag2"))
8872         tag2 = 1;
8873       else if (unformat (input, "ignore-tag1"))
8874         ignore_tag1 = 1;
8875       else if (unformat (input, "ignore-tag2"))
8876         ignore_tag2 = 1;
8877       else if (unformat (input, "cos1"))
8878         cos1 = 1;
8879       else if (unformat (input, "cos2"))
8880         cos2 = 1;
8881       else if (unformat (input, "dot1q"))
8882         dot1q = 1;
8883       else if (unformat (input, "dot1ad"))
8884         dot1ad = 1;
8885       else
8886         break;
8887     }
8888   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
8889        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
8890     return 0;
8891
8892   if (tag1 || ignore_tag1 || cos1 || dot1q)
8893     len = 18;
8894   if (tag2 || ignore_tag2 || cos2 || dot1ad)
8895     len = 22;
8896
8897   vec_validate (mask, len - 1);
8898
8899   if (dst)
8900     memset (mask, 0xff, 6);
8901
8902   if (src)
8903     memset (mask + 6, 0xff, 6);
8904
8905   if (tag2 || dot1ad)
8906     {
8907       /* inner vlan tag */
8908       if (tag2)
8909         {
8910           mask[19] = 0xff;
8911           mask[18] = 0x0f;
8912         }
8913       if (cos2)
8914         mask[18] |= 0xe0;
8915       if (proto)
8916         mask[21] = mask[20] = 0xff;
8917       if (tag1)
8918         {
8919           mask[15] = 0xff;
8920           mask[14] = 0x0f;
8921         }
8922       if (cos1)
8923         mask[14] |= 0xe0;
8924       *maskp = mask;
8925       return 1;
8926     }
8927   if (tag1 | dot1q)
8928     {
8929       if (tag1)
8930         {
8931           mask[15] = 0xff;
8932           mask[14] = 0x0f;
8933         }
8934       if (cos1)
8935         mask[14] |= 0xe0;
8936       if (proto)
8937         mask[16] = mask[17] = 0xff;
8938
8939       *maskp = mask;
8940       return 1;
8941     }
8942   if (cos2)
8943     mask[18] |= 0xe0;
8944   if (cos1)
8945     mask[14] |= 0xe0;
8946   if (proto)
8947     mask[12] = mask[13] = 0xff;
8948
8949   *maskp = mask;
8950   return 1;
8951 }
8952
8953 uword
8954 unformat_classify_mask (unformat_input_t * input, va_list * args)
8955 {
8956   u8 **maskp = va_arg (*args, u8 **);
8957   u32 *skipp = va_arg (*args, u32 *);
8958   u32 *matchp = va_arg (*args, u32 *);
8959   u32 match;
8960   u8 *mask = 0;
8961   u8 *l2 = 0;
8962   u8 *l3 = 0;
8963   u8 *l4 = 0;
8964   int i;
8965
8966   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8967     {
8968       if (unformat (input, "hex %U", unformat_hex_string, &mask))
8969         ;
8970       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
8971         ;
8972       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
8973         ;
8974       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
8975         ;
8976       else
8977         break;
8978     }
8979
8980   if (l4 && !l3)
8981     {
8982       vec_free (mask);
8983       vec_free (l2);
8984       vec_free (l4);
8985       return 0;
8986     }
8987
8988   if (mask || l2 || l3 || l4)
8989     {
8990       if (l2 || l3 || l4)
8991         {
8992           /* "With a free Ethernet header in every package" */
8993           if (l2 == 0)
8994             vec_validate (l2, 13);
8995           mask = l2;
8996           if (vec_len (l3))
8997             {
8998               vec_append (mask, l3);
8999               vec_free (l3);
9000             }
9001           if (vec_len (l4))
9002             {
9003               vec_append (mask, l4);
9004               vec_free (l4);
9005             }
9006         }
9007
9008       /* Scan forward looking for the first significant mask octet */
9009       for (i = 0; i < vec_len (mask); i++)
9010         if (mask[i])
9011           break;
9012
9013       /* compute (skip, match) params */
9014       *skipp = i / sizeof (u32x4);
9015       vec_delete (mask, *skipp * sizeof (u32x4), 0);
9016
9017       /* Pad mask to an even multiple of the vector size */
9018       while (vec_len (mask) % sizeof (u32x4))
9019         vec_add1 (mask, 0);
9020
9021       match = vec_len (mask) / sizeof (u32x4);
9022
9023       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
9024         {
9025           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
9026           if (*tmp || *(tmp + 1))
9027             break;
9028           match--;
9029         }
9030       if (match == 0)
9031         clib_warning ("BUG: match 0");
9032
9033       _vec_len (mask) = match * sizeof (u32x4);
9034
9035       *matchp = match;
9036       *maskp = mask;
9037
9038       return 1;
9039     }
9040
9041   return 0;
9042 }
9043 #endif /* VPP_API_TEST_BUILTIN */
9044
9045 #define foreach_l2_next                         \
9046 _(drop, DROP)                                   \
9047 _(ethernet, ETHERNET_INPUT)                     \
9048 _(ip4, IP4_INPUT)                               \
9049 _(ip6, IP6_INPUT)
9050
9051 uword
9052 unformat_l2_next_index (unformat_input_t * input, va_list * args)
9053 {
9054   u32 *miss_next_indexp = va_arg (*args, u32 *);
9055   u32 next_index = 0;
9056   u32 tmp;
9057
9058 #define _(n,N) \
9059   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
9060   foreach_l2_next;
9061 #undef _
9062
9063   if (unformat (input, "%d", &tmp))
9064     {
9065       next_index = tmp;
9066       goto out;
9067     }
9068
9069   return 0;
9070
9071 out:
9072   *miss_next_indexp = next_index;
9073   return 1;
9074 }
9075
9076 #define foreach_ip_next                         \
9077 _(drop, DROP)                                   \
9078 _(local, LOCAL)                                 \
9079 _(rewrite, REWRITE)
9080
9081 uword
9082 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
9083 {
9084   u32 *miss_next_indexp = va_arg (*args, u32 *);
9085   u32 next_index = 0;
9086   u32 tmp;
9087
9088 #define _(n,N) \
9089   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
9090   foreach_ip_next;
9091 #undef _
9092
9093   if (unformat (input, "%d", &tmp))
9094     {
9095       next_index = tmp;
9096       goto out;
9097     }
9098
9099   return 0;
9100
9101 out:
9102   *miss_next_indexp = next_index;
9103   return 1;
9104 }
9105
9106 #define foreach_acl_next                        \
9107 _(deny, DENY)
9108
9109 uword
9110 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
9111 {
9112   u32 *miss_next_indexp = va_arg (*args, u32 *);
9113   u32 next_index = 0;
9114   u32 tmp;
9115
9116 #define _(n,N) \
9117   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
9118   foreach_acl_next;
9119 #undef _
9120
9121   if (unformat (input, "permit"))
9122     {
9123       next_index = ~0;
9124       goto out;
9125     }
9126   else if (unformat (input, "%d", &tmp))
9127     {
9128       next_index = tmp;
9129       goto out;
9130     }
9131
9132   return 0;
9133
9134 out:
9135   *miss_next_indexp = next_index;
9136   return 1;
9137 }
9138
9139 uword
9140 unformat_policer_precolor (unformat_input_t * input, va_list * args)
9141 {
9142   u32 *r = va_arg (*args, u32 *);
9143
9144   if (unformat (input, "conform-color"))
9145     *r = POLICE_CONFORM;
9146   else if (unformat (input, "exceed-color"))
9147     *r = POLICE_EXCEED;
9148   else
9149     return 0;
9150
9151   return 1;
9152 }
9153
9154 static int
9155 api_classify_add_del_table (vat_main_t * vam)
9156 {
9157   unformat_input_t *i = vam->input;
9158   vl_api_classify_add_del_table_t *mp;
9159
9160   u32 nbuckets = 2;
9161   u32 skip = ~0;
9162   u32 match = ~0;
9163   int is_add = 1;
9164   int del_chain = 0;
9165   u32 table_index = ~0;
9166   u32 next_table_index = ~0;
9167   u32 miss_next_index = ~0;
9168   u32 memory_size = 32 << 20;
9169   u8 *mask = 0;
9170   u32 current_data_flag = 0;
9171   int current_data_offset = 0;
9172   int ret;
9173
9174   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9175     {
9176       if (unformat (i, "del"))
9177         is_add = 0;
9178       else if (unformat (i, "del-chain"))
9179         {
9180           is_add = 0;
9181           del_chain = 1;
9182         }
9183       else if (unformat (i, "buckets %d", &nbuckets))
9184         ;
9185       else if (unformat (i, "memory_size %d", &memory_size))
9186         ;
9187       else if (unformat (i, "skip %d", &skip))
9188         ;
9189       else if (unformat (i, "match %d", &match))
9190         ;
9191       else if (unformat (i, "table %d", &table_index))
9192         ;
9193       else if (unformat (i, "mask %U", unformat_classify_mask,
9194                          &mask, &skip, &match))
9195         ;
9196       else if (unformat (i, "next-table %d", &next_table_index))
9197         ;
9198       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
9199                          &miss_next_index))
9200         ;
9201       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
9202                          &miss_next_index))
9203         ;
9204       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
9205                          &miss_next_index))
9206         ;
9207       else if (unformat (i, "current-data-flag %d", &current_data_flag))
9208         ;
9209       else if (unformat (i, "current-data-offset %d", &current_data_offset))
9210         ;
9211       else
9212         break;
9213     }
9214
9215   if (is_add && mask == 0)
9216     {
9217       errmsg ("Mask required");
9218       return -99;
9219     }
9220
9221   if (is_add && skip == ~0)
9222     {
9223       errmsg ("skip count required");
9224       return -99;
9225     }
9226
9227   if (is_add && match == ~0)
9228     {
9229       errmsg ("match count required");
9230       return -99;
9231     }
9232
9233   if (!is_add && table_index == ~0)
9234     {
9235       errmsg ("table index required for delete");
9236       return -99;
9237     }
9238
9239   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
9240
9241   mp->is_add = is_add;
9242   mp->del_chain = del_chain;
9243   mp->table_index = ntohl (table_index);
9244   mp->nbuckets = ntohl (nbuckets);
9245   mp->memory_size = ntohl (memory_size);
9246   mp->skip_n_vectors = ntohl (skip);
9247   mp->match_n_vectors = ntohl (match);
9248   mp->next_table_index = ntohl (next_table_index);
9249   mp->miss_next_index = ntohl (miss_next_index);
9250   mp->current_data_flag = ntohl (current_data_flag);
9251   mp->current_data_offset = ntohl (current_data_offset);
9252   clib_memcpy (mp->mask, mask, vec_len (mask));
9253
9254   vec_free (mask);
9255
9256   S (mp);
9257   W (ret);
9258   return ret;
9259 }
9260
9261 #if VPP_API_TEST_BUILTIN == 0
9262 uword
9263 unformat_l4_match (unformat_input_t * input, va_list * args)
9264 {
9265   u8 **matchp = va_arg (*args, u8 **);
9266
9267   u8 *proto_header = 0;
9268   int src_port = 0;
9269   int dst_port = 0;
9270
9271   tcpudp_header_t h;
9272
9273   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9274     {
9275       if (unformat (input, "src_port %d", &src_port))
9276         ;
9277       else if (unformat (input, "dst_port %d", &dst_port))
9278         ;
9279       else
9280         return 0;
9281     }
9282
9283   h.src_port = clib_host_to_net_u16 (src_port);
9284   h.dst_port = clib_host_to_net_u16 (dst_port);
9285   vec_validate (proto_header, sizeof (h) - 1);
9286   memcpy (proto_header, &h, sizeof (h));
9287
9288   *matchp = proto_header;
9289
9290   return 1;
9291 }
9292
9293 uword
9294 unformat_ip4_match (unformat_input_t * input, va_list * args)
9295 {
9296   u8 **matchp = va_arg (*args, u8 **);
9297   u8 *match = 0;
9298   ip4_header_t *ip;
9299   int version = 0;
9300   u32 version_val;
9301   int hdr_length = 0;
9302   u32 hdr_length_val;
9303   int src = 0, dst = 0;
9304   ip4_address_t src_val, dst_val;
9305   int proto = 0;
9306   u32 proto_val;
9307   int tos = 0;
9308   u32 tos_val;
9309   int length = 0;
9310   u32 length_val;
9311   int fragment_id = 0;
9312   u32 fragment_id_val;
9313   int ttl = 0;
9314   int ttl_val;
9315   int checksum = 0;
9316   u32 checksum_val;
9317
9318   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9319     {
9320       if (unformat (input, "version %d", &version_val))
9321         version = 1;
9322       else if (unformat (input, "hdr_length %d", &hdr_length_val))
9323         hdr_length = 1;
9324       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
9325         src = 1;
9326       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
9327         dst = 1;
9328       else if (unformat (input, "proto %d", &proto_val))
9329         proto = 1;
9330       else if (unformat (input, "tos %d", &tos_val))
9331         tos = 1;
9332       else if (unformat (input, "length %d", &length_val))
9333         length = 1;
9334       else if (unformat (input, "fragment_id %d", &fragment_id_val))
9335         fragment_id = 1;
9336       else if (unformat (input, "ttl %d", &ttl_val))
9337         ttl = 1;
9338       else if (unformat (input, "checksum %d", &checksum_val))
9339         checksum = 1;
9340       else
9341         break;
9342     }
9343
9344   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
9345       + ttl + checksum == 0)
9346     return 0;
9347
9348   /*
9349    * Aligned because we use the real comparison functions
9350    */
9351   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
9352
9353   ip = (ip4_header_t *) match;
9354
9355   /* These are realistically matched in practice */
9356   if (src)
9357     ip->src_address.as_u32 = src_val.as_u32;
9358
9359   if (dst)
9360     ip->dst_address.as_u32 = dst_val.as_u32;
9361
9362   if (proto)
9363     ip->protocol = proto_val;
9364
9365
9366   /* These are not, but they're included for completeness */
9367   if (version)
9368     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
9369
9370   if (hdr_length)
9371     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
9372
9373   if (tos)
9374     ip->tos = tos_val;
9375
9376   if (length)
9377     ip->length = clib_host_to_net_u16 (length_val);
9378
9379   if (ttl)
9380     ip->ttl = ttl_val;
9381
9382   if (checksum)
9383     ip->checksum = clib_host_to_net_u16 (checksum_val);
9384
9385   *matchp = match;
9386   return 1;
9387 }
9388
9389 uword
9390 unformat_ip6_match (unformat_input_t * input, va_list * args)
9391 {
9392   u8 **matchp = va_arg (*args, u8 **);
9393   u8 *match = 0;
9394   ip6_header_t *ip;
9395   int version = 0;
9396   u32 version_val;
9397   u8 traffic_class = 0;
9398   u32 traffic_class_val = 0;
9399   u8 flow_label = 0;
9400   u8 flow_label_val;
9401   int src = 0, dst = 0;
9402   ip6_address_t src_val, dst_val;
9403   int proto = 0;
9404   u32 proto_val;
9405   int payload_length = 0;
9406   u32 payload_length_val;
9407   int hop_limit = 0;
9408   int hop_limit_val;
9409   u32 ip_version_traffic_class_and_flow_label;
9410
9411   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9412     {
9413       if (unformat (input, "version %d", &version_val))
9414         version = 1;
9415       else if (unformat (input, "traffic_class %d", &traffic_class_val))
9416         traffic_class = 1;
9417       else if (unformat (input, "flow_label %d", &flow_label_val))
9418         flow_label = 1;
9419       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
9420         src = 1;
9421       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
9422         dst = 1;
9423       else if (unformat (input, "proto %d", &proto_val))
9424         proto = 1;
9425       else if (unformat (input, "payload_length %d", &payload_length_val))
9426         payload_length = 1;
9427       else if (unformat (input, "hop_limit %d", &hop_limit_val))
9428         hop_limit = 1;
9429       else
9430         break;
9431     }
9432
9433   if (version + traffic_class + flow_label + src + dst + proto +
9434       payload_length + hop_limit == 0)
9435     return 0;
9436
9437   /*
9438    * Aligned because we use the real comparison functions
9439    */
9440   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
9441
9442   ip = (ip6_header_t *) match;
9443
9444   if (src)
9445     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
9446
9447   if (dst)
9448     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
9449
9450   if (proto)
9451     ip->protocol = proto_val;
9452
9453   ip_version_traffic_class_and_flow_label = 0;
9454
9455   if (version)
9456     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
9457
9458   if (traffic_class)
9459     ip_version_traffic_class_and_flow_label |=
9460       (traffic_class_val & 0xFF) << 20;
9461
9462   if (flow_label)
9463     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
9464
9465   ip->ip_version_traffic_class_and_flow_label =
9466     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
9467
9468   if (payload_length)
9469     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
9470
9471   if (hop_limit)
9472     ip->hop_limit = hop_limit_val;
9473
9474   *matchp = match;
9475   return 1;
9476 }
9477
9478 uword
9479 unformat_l3_match (unformat_input_t * input, va_list * args)
9480 {
9481   u8 **matchp = va_arg (*args, u8 **);
9482
9483   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9484     {
9485       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
9486         return 1;
9487       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
9488         return 1;
9489       else
9490         break;
9491     }
9492   return 0;
9493 }
9494
9495 uword
9496 unformat_vlan_tag (unformat_input_t * input, va_list * args)
9497 {
9498   u8 *tagp = va_arg (*args, u8 *);
9499   u32 tag;
9500
9501   if (unformat (input, "%d", &tag))
9502     {
9503       tagp[0] = (tag >> 8) & 0x0F;
9504       tagp[1] = tag & 0xFF;
9505       return 1;
9506     }
9507
9508   return 0;
9509 }
9510
9511 uword
9512 unformat_l2_match (unformat_input_t * input, va_list * args)
9513 {
9514   u8 **matchp = va_arg (*args, u8 **);
9515   u8 *match = 0;
9516   u8 src = 0;
9517   u8 src_val[6];
9518   u8 dst = 0;
9519   u8 dst_val[6];
9520   u8 proto = 0;
9521   u16 proto_val;
9522   u8 tag1 = 0;
9523   u8 tag1_val[2];
9524   u8 tag2 = 0;
9525   u8 tag2_val[2];
9526   int len = 14;
9527   u8 ignore_tag1 = 0;
9528   u8 ignore_tag2 = 0;
9529   u8 cos1 = 0;
9530   u8 cos2 = 0;
9531   u32 cos1_val = 0;
9532   u32 cos2_val = 0;
9533
9534   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9535     {
9536       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
9537         src = 1;
9538       else
9539         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
9540         dst = 1;
9541       else if (unformat (input, "proto %U",
9542                          unformat_ethernet_type_host_byte_order, &proto_val))
9543         proto = 1;
9544       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
9545         tag1 = 1;
9546       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
9547         tag2 = 1;
9548       else if (unformat (input, "ignore-tag1"))
9549         ignore_tag1 = 1;
9550       else if (unformat (input, "ignore-tag2"))
9551         ignore_tag2 = 1;
9552       else if (unformat (input, "cos1 %d", &cos1_val))
9553         cos1 = 1;
9554       else if (unformat (input, "cos2 %d", &cos2_val))
9555         cos2 = 1;
9556       else
9557         break;
9558     }
9559   if ((src + dst + proto + tag1 + tag2 +
9560        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
9561     return 0;
9562
9563   if (tag1 || ignore_tag1 || cos1)
9564     len = 18;
9565   if (tag2 || ignore_tag2 || cos2)
9566     len = 22;
9567
9568   vec_validate_aligned (match, len - 1, sizeof (u32x4));
9569
9570   if (dst)
9571     clib_memcpy (match, dst_val, 6);
9572
9573   if (src)
9574     clib_memcpy (match + 6, src_val, 6);
9575
9576   if (tag2)
9577     {
9578       /* inner vlan tag */
9579       match[19] = tag2_val[1];
9580       match[18] = tag2_val[0];
9581       if (cos2)
9582         match[18] |= (cos2_val & 0x7) << 5;
9583       if (proto)
9584         {
9585           match[21] = proto_val & 0xff;
9586           match[20] = proto_val >> 8;
9587         }
9588       if (tag1)
9589         {
9590           match[15] = tag1_val[1];
9591           match[14] = tag1_val[0];
9592         }
9593       if (cos1)
9594         match[14] |= (cos1_val & 0x7) << 5;
9595       *matchp = match;
9596       return 1;
9597     }
9598   if (tag1)
9599     {
9600       match[15] = tag1_val[1];
9601       match[14] = tag1_val[0];
9602       if (proto)
9603         {
9604           match[17] = proto_val & 0xff;
9605           match[16] = proto_val >> 8;
9606         }
9607       if (cos1)
9608         match[14] |= (cos1_val & 0x7) << 5;
9609
9610       *matchp = match;
9611       return 1;
9612     }
9613   if (cos2)
9614     match[18] |= (cos2_val & 0x7) << 5;
9615   if (cos1)
9616     match[14] |= (cos1_val & 0x7) << 5;
9617   if (proto)
9618     {
9619       match[13] = proto_val & 0xff;
9620       match[12] = proto_val >> 8;
9621     }
9622
9623   *matchp = match;
9624   return 1;
9625 }
9626 #endif
9627
9628 uword
9629 api_unformat_classify_match (unformat_input_t * input, va_list * args)
9630 {
9631   u8 **matchp = va_arg (*args, u8 **);
9632   u32 skip_n_vectors = va_arg (*args, u32);
9633   u32 match_n_vectors = va_arg (*args, u32);
9634
9635   u8 *match = 0;
9636   u8 *l2 = 0;
9637   u8 *l3 = 0;
9638   u8 *l4 = 0;
9639
9640   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9641     {
9642       if (unformat (input, "hex %U", unformat_hex_string, &match))
9643         ;
9644       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
9645         ;
9646       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
9647         ;
9648       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
9649         ;
9650       else
9651         break;
9652     }
9653
9654   if (l4 && !l3)
9655     {
9656       vec_free (match);
9657       vec_free (l2);
9658       vec_free (l4);
9659       return 0;
9660     }
9661
9662   if (match || l2 || l3 || l4)
9663     {
9664       if (l2 || l3 || l4)
9665         {
9666           /* "Win a free Ethernet header in every packet" */
9667           if (l2 == 0)
9668             vec_validate_aligned (l2, 13, sizeof (u32x4));
9669           match = l2;
9670           if (vec_len (l3))
9671             {
9672               vec_append_aligned (match, l3, sizeof (u32x4));
9673               vec_free (l3);
9674             }
9675           if (vec_len (l4))
9676             {
9677               vec_append_aligned (match, l4, sizeof (u32x4));
9678               vec_free (l4);
9679             }
9680         }
9681
9682       /* Make sure the vector is big enough even if key is all 0's */
9683       vec_validate_aligned
9684         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
9685          sizeof (u32x4));
9686
9687       /* Set size, include skipped vectors */
9688       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
9689
9690       *matchp = match;
9691
9692       return 1;
9693     }
9694
9695   return 0;
9696 }
9697
9698 static int
9699 api_classify_add_del_session (vat_main_t * vam)
9700 {
9701   unformat_input_t *i = vam->input;
9702   vl_api_classify_add_del_session_t *mp;
9703   int is_add = 1;
9704   u32 table_index = ~0;
9705   u32 hit_next_index = ~0;
9706   u32 opaque_index = ~0;
9707   u8 *match = 0;
9708   i32 advance = 0;
9709   u32 skip_n_vectors = 0;
9710   u32 match_n_vectors = 0;
9711   u32 action = 0;
9712   u32 metadata = 0;
9713   int ret;
9714
9715   /*
9716    * Warning: you have to supply skip_n and match_n
9717    * because the API client cant simply look at the classify
9718    * table object.
9719    */
9720
9721   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9722     {
9723       if (unformat (i, "del"))
9724         is_add = 0;
9725       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
9726                          &hit_next_index))
9727         ;
9728       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
9729                          &hit_next_index))
9730         ;
9731       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
9732                          &hit_next_index))
9733         ;
9734       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
9735         ;
9736       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
9737         ;
9738       else if (unformat (i, "opaque-index %d", &opaque_index))
9739         ;
9740       else if (unformat (i, "skip_n %d", &skip_n_vectors))
9741         ;
9742       else if (unformat (i, "match_n %d", &match_n_vectors))
9743         ;
9744       else if (unformat (i, "match %U", api_unformat_classify_match,
9745                          &match, skip_n_vectors, match_n_vectors))
9746         ;
9747       else if (unformat (i, "advance %d", &advance))
9748         ;
9749       else if (unformat (i, "table-index %d", &table_index))
9750         ;
9751       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
9752         action = 1;
9753       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
9754         action = 2;
9755       else if (unformat (i, "action %d", &action))
9756         ;
9757       else if (unformat (i, "metadata %d", &metadata))
9758         ;
9759       else
9760         break;
9761     }
9762
9763   if (table_index == ~0)
9764     {
9765       errmsg ("Table index required");
9766       return -99;
9767     }
9768
9769   if (is_add && match == 0)
9770     {
9771       errmsg ("Match value required");
9772       return -99;
9773     }
9774
9775   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
9776
9777   mp->is_add = is_add;
9778   mp->table_index = ntohl (table_index);
9779   mp->hit_next_index = ntohl (hit_next_index);
9780   mp->opaque_index = ntohl (opaque_index);
9781   mp->advance = ntohl (advance);
9782   mp->action = action;
9783   mp->metadata = ntohl (metadata);
9784   clib_memcpy (mp->match, match, vec_len (match));
9785   vec_free (match);
9786
9787   S (mp);
9788   W (ret);
9789   return ret;
9790 }
9791
9792 static int
9793 api_classify_set_interface_ip_table (vat_main_t * vam)
9794 {
9795   unformat_input_t *i = vam->input;
9796   vl_api_classify_set_interface_ip_table_t *mp;
9797   u32 sw_if_index;
9798   int sw_if_index_set;
9799   u32 table_index = ~0;
9800   u8 is_ipv6 = 0;
9801   int ret;
9802
9803   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9804     {
9805       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9806         sw_if_index_set = 1;
9807       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9808         sw_if_index_set = 1;
9809       else if (unformat (i, "table %d", &table_index))
9810         ;
9811       else
9812         {
9813           clib_warning ("parse error '%U'", format_unformat_error, i);
9814           return -99;
9815         }
9816     }
9817
9818   if (sw_if_index_set == 0)
9819     {
9820       errmsg ("missing interface name or sw_if_index");
9821       return -99;
9822     }
9823
9824
9825   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
9826
9827   mp->sw_if_index = ntohl (sw_if_index);
9828   mp->table_index = ntohl (table_index);
9829   mp->is_ipv6 = is_ipv6;
9830
9831   S (mp);
9832   W (ret);
9833   return ret;
9834 }
9835
9836 static int
9837 api_classify_set_interface_l2_tables (vat_main_t * vam)
9838 {
9839   unformat_input_t *i = vam->input;
9840   vl_api_classify_set_interface_l2_tables_t *mp;
9841   u32 sw_if_index;
9842   int sw_if_index_set;
9843   u32 ip4_table_index = ~0;
9844   u32 ip6_table_index = ~0;
9845   u32 other_table_index = ~0;
9846   u32 is_input = 1;
9847   int ret;
9848
9849   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9850     {
9851       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9852         sw_if_index_set = 1;
9853       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9854         sw_if_index_set = 1;
9855       else if (unformat (i, "ip4-table %d", &ip4_table_index))
9856         ;
9857       else if (unformat (i, "ip6-table %d", &ip6_table_index))
9858         ;
9859       else if (unformat (i, "other-table %d", &other_table_index))
9860         ;
9861       else if (unformat (i, "is-input %d", &is_input))
9862         ;
9863       else
9864         {
9865           clib_warning ("parse error '%U'", format_unformat_error, i);
9866           return -99;
9867         }
9868     }
9869
9870   if (sw_if_index_set == 0)
9871     {
9872       errmsg ("missing interface name or sw_if_index");
9873       return -99;
9874     }
9875
9876
9877   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
9878
9879   mp->sw_if_index = ntohl (sw_if_index);
9880   mp->ip4_table_index = ntohl (ip4_table_index);
9881   mp->ip6_table_index = ntohl (ip6_table_index);
9882   mp->other_table_index = ntohl (other_table_index);
9883   mp->is_input = (u8) is_input;
9884
9885   S (mp);
9886   W (ret);
9887   return ret;
9888 }
9889
9890 static int
9891 api_set_ipfix_exporter (vat_main_t * vam)
9892 {
9893   unformat_input_t *i = vam->input;
9894   vl_api_set_ipfix_exporter_t *mp;
9895   ip4_address_t collector_address;
9896   u8 collector_address_set = 0;
9897   u32 collector_port = ~0;
9898   ip4_address_t src_address;
9899   u8 src_address_set = 0;
9900   u32 vrf_id = ~0;
9901   u32 path_mtu = ~0;
9902   u32 template_interval = ~0;
9903   u8 udp_checksum = 0;
9904   int ret;
9905
9906   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9907     {
9908       if (unformat (i, "collector_address %U", unformat_ip4_address,
9909                     &collector_address))
9910         collector_address_set = 1;
9911       else if (unformat (i, "collector_port %d", &collector_port))
9912         ;
9913       else if (unformat (i, "src_address %U", unformat_ip4_address,
9914                          &src_address))
9915         src_address_set = 1;
9916       else if (unformat (i, "vrf_id %d", &vrf_id))
9917         ;
9918       else if (unformat (i, "path_mtu %d", &path_mtu))
9919         ;
9920       else if (unformat (i, "template_interval %d", &template_interval))
9921         ;
9922       else if (unformat (i, "udp_checksum"))
9923         udp_checksum = 1;
9924       else
9925         break;
9926     }
9927
9928   if (collector_address_set == 0)
9929     {
9930       errmsg ("collector_address required");
9931       return -99;
9932     }
9933
9934   if (src_address_set == 0)
9935     {
9936       errmsg ("src_address required");
9937       return -99;
9938     }
9939
9940   M (SET_IPFIX_EXPORTER, mp);
9941
9942   memcpy (mp->collector_address, collector_address.data,
9943           sizeof (collector_address.data));
9944   mp->collector_port = htons ((u16) collector_port);
9945   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
9946   mp->vrf_id = htonl (vrf_id);
9947   mp->path_mtu = htonl (path_mtu);
9948   mp->template_interval = htonl (template_interval);
9949   mp->udp_checksum = udp_checksum;
9950
9951   S (mp);
9952   W (ret);
9953   return ret;
9954 }
9955
9956 static int
9957 api_set_ipfix_classify_stream (vat_main_t * vam)
9958 {
9959   unformat_input_t *i = vam->input;
9960   vl_api_set_ipfix_classify_stream_t *mp;
9961   u32 domain_id = 0;
9962   u32 src_port = UDP_DST_PORT_ipfix;
9963   int ret;
9964
9965   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9966     {
9967       if (unformat (i, "domain %d", &domain_id))
9968         ;
9969       else if (unformat (i, "src_port %d", &src_port))
9970         ;
9971       else
9972         {
9973           errmsg ("unknown input `%U'", format_unformat_error, i);
9974           return -99;
9975         }
9976     }
9977
9978   M (SET_IPFIX_CLASSIFY_STREAM, mp);
9979
9980   mp->domain_id = htonl (domain_id);
9981   mp->src_port = htons ((u16) src_port);
9982
9983   S (mp);
9984   W (ret);
9985   return ret;
9986 }
9987
9988 static int
9989 api_ipfix_classify_table_add_del (vat_main_t * vam)
9990 {
9991   unformat_input_t *i = vam->input;
9992   vl_api_ipfix_classify_table_add_del_t *mp;
9993   int is_add = -1;
9994   u32 classify_table_index = ~0;
9995   u8 ip_version = 0;
9996   u8 transport_protocol = 255;
9997   int ret;
9998
9999   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10000     {
10001       if (unformat (i, "add"))
10002         is_add = 1;
10003       else if (unformat (i, "del"))
10004         is_add = 0;
10005       else if (unformat (i, "table %d", &classify_table_index))
10006         ;
10007       else if (unformat (i, "ip4"))
10008         ip_version = 4;
10009       else if (unformat (i, "ip6"))
10010         ip_version = 6;
10011       else if (unformat (i, "tcp"))
10012         transport_protocol = 6;
10013       else if (unformat (i, "udp"))
10014         transport_protocol = 17;
10015       else
10016         {
10017           errmsg ("unknown input `%U'", format_unformat_error, i);
10018           return -99;
10019         }
10020     }
10021
10022   if (is_add == -1)
10023     {
10024       errmsg ("expecting: add|del");
10025       return -99;
10026     }
10027   if (classify_table_index == ~0)
10028     {
10029       errmsg ("classifier table not specified");
10030       return -99;
10031     }
10032   if (ip_version == 0)
10033     {
10034       errmsg ("IP version not specified");
10035       return -99;
10036     }
10037
10038   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
10039
10040   mp->is_add = is_add;
10041   mp->table_id = htonl (classify_table_index);
10042   mp->ip_version = ip_version;
10043   mp->transport_protocol = transport_protocol;
10044
10045   S (mp);
10046   W (ret);
10047   return ret;
10048 }
10049
10050 static int
10051 api_get_node_index (vat_main_t * vam)
10052 {
10053   unformat_input_t *i = vam->input;
10054   vl_api_get_node_index_t *mp;
10055   u8 *name = 0;
10056   int ret;
10057
10058   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10059     {
10060       if (unformat (i, "node %s", &name))
10061         ;
10062       else
10063         break;
10064     }
10065   if (name == 0)
10066     {
10067       errmsg ("node name required");
10068       return -99;
10069     }
10070   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
10071     {
10072       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10073       return -99;
10074     }
10075
10076   M (GET_NODE_INDEX, mp);
10077   clib_memcpy (mp->node_name, name, vec_len (name));
10078   vec_free (name);
10079
10080   S (mp);
10081   W (ret);
10082   return ret;
10083 }
10084
10085 static int
10086 api_get_next_index (vat_main_t * vam)
10087 {
10088   unformat_input_t *i = vam->input;
10089   vl_api_get_next_index_t *mp;
10090   u8 *node_name = 0, *next_node_name = 0;
10091   int ret;
10092
10093   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10094     {
10095       if (unformat (i, "node-name %s", &node_name))
10096         ;
10097       else if (unformat (i, "next-node-name %s", &next_node_name))
10098         break;
10099     }
10100
10101   if (node_name == 0)
10102     {
10103       errmsg ("node name required");
10104       return -99;
10105     }
10106   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
10107     {
10108       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10109       return -99;
10110     }
10111
10112   if (next_node_name == 0)
10113     {
10114       errmsg ("next node name required");
10115       return -99;
10116     }
10117   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
10118     {
10119       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
10120       return -99;
10121     }
10122
10123   M (GET_NEXT_INDEX, mp);
10124   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
10125   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
10126   vec_free (node_name);
10127   vec_free (next_node_name);
10128
10129   S (mp);
10130   W (ret);
10131   return ret;
10132 }
10133
10134 static int
10135 api_add_node_next (vat_main_t * vam)
10136 {
10137   unformat_input_t *i = vam->input;
10138   vl_api_add_node_next_t *mp;
10139   u8 *name = 0;
10140   u8 *next = 0;
10141   int ret;
10142
10143   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10144     {
10145       if (unformat (i, "node %s", &name))
10146         ;
10147       else if (unformat (i, "next %s", &next))
10148         ;
10149       else
10150         break;
10151     }
10152   if (name == 0)
10153     {
10154       errmsg ("node name required");
10155       return -99;
10156     }
10157   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
10158     {
10159       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10160       return -99;
10161     }
10162   if (next == 0)
10163     {
10164       errmsg ("next node required");
10165       return -99;
10166     }
10167   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
10168     {
10169       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
10170       return -99;
10171     }
10172
10173   M (ADD_NODE_NEXT, mp);
10174   clib_memcpy (mp->node_name, name, vec_len (name));
10175   clib_memcpy (mp->next_name, next, vec_len (next));
10176   vec_free (name);
10177   vec_free (next);
10178
10179   S (mp);
10180   W (ret);
10181   return ret;
10182 }
10183
10184 static int
10185 api_l2tpv3_create_tunnel (vat_main_t * vam)
10186 {
10187   unformat_input_t *i = vam->input;
10188   ip6_address_t client_address, our_address;
10189   int client_address_set = 0;
10190   int our_address_set = 0;
10191   u32 local_session_id = 0;
10192   u32 remote_session_id = 0;
10193   u64 local_cookie = 0;
10194   u64 remote_cookie = 0;
10195   u8 l2_sublayer_present = 0;
10196   vl_api_l2tpv3_create_tunnel_t *mp;
10197   int ret;
10198
10199   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10200     {
10201       if (unformat (i, "client_address %U", unformat_ip6_address,
10202                     &client_address))
10203         client_address_set = 1;
10204       else if (unformat (i, "our_address %U", unformat_ip6_address,
10205                          &our_address))
10206         our_address_set = 1;
10207       else if (unformat (i, "local_session_id %d", &local_session_id))
10208         ;
10209       else if (unformat (i, "remote_session_id %d", &remote_session_id))
10210         ;
10211       else if (unformat (i, "local_cookie %lld", &local_cookie))
10212         ;
10213       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
10214         ;
10215       else if (unformat (i, "l2-sublayer-present"))
10216         l2_sublayer_present = 1;
10217       else
10218         break;
10219     }
10220
10221   if (client_address_set == 0)
10222     {
10223       errmsg ("client_address required");
10224       return -99;
10225     }
10226
10227   if (our_address_set == 0)
10228     {
10229       errmsg ("our_address required");
10230       return -99;
10231     }
10232
10233   M (L2TPV3_CREATE_TUNNEL, mp);
10234
10235   clib_memcpy (mp->client_address, client_address.as_u8,
10236                sizeof (mp->client_address));
10237
10238   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
10239
10240   mp->local_session_id = ntohl (local_session_id);
10241   mp->remote_session_id = ntohl (remote_session_id);
10242   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
10243   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
10244   mp->l2_sublayer_present = l2_sublayer_present;
10245   mp->is_ipv6 = 1;
10246
10247   S (mp);
10248   W (ret);
10249   return ret;
10250 }
10251
10252 static int
10253 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
10254 {
10255   unformat_input_t *i = vam->input;
10256   u32 sw_if_index;
10257   u8 sw_if_index_set = 0;
10258   u64 new_local_cookie = 0;
10259   u64 new_remote_cookie = 0;
10260   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
10261   int ret;
10262
10263   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10264     {
10265       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10266         sw_if_index_set = 1;
10267       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10268         sw_if_index_set = 1;
10269       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
10270         ;
10271       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
10272         ;
10273       else
10274         break;
10275     }
10276
10277   if (sw_if_index_set == 0)
10278     {
10279       errmsg ("missing interface name or sw_if_index");
10280       return -99;
10281     }
10282
10283   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
10284
10285   mp->sw_if_index = ntohl (sw_if_index);
10286   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
10287   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
10288
10289   S (mp);
10290   W (ret);
10291   return ret;
10292 }
10293
10294 static int
10295 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
10296 {
10297   unformat_input_t *i = vam->input;
10298   vl_api_l2tpv3_interface_enable_disable_t *mp;
10299   u32 sw_if_index;
10300   u8 sw_if_index_set = 0;
10301   u8 enable_disable = 1;
10302   int ret;
10303
10304   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10305     {
10306       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10307         sw_if_index_set = 1;
10308       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10309         sw_if_index_set = 1;
10310       else if (unformat (i, "enable"))
10311         enable_disable = 1;
10312       else if (unformat (i, "disable"))
10313         enable_disable = 0;
10314       else
10315         break;
10316     }
10317
10318   if (sw_if_index_set == 0)
10319     {
10320       errmsg ("missing interface name or sw_if_index");
10321       return -99;
10322     }
10323
10324   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
10325
10326   mp->sw_if_index = ntohl (sw_if_index);
10327   mp->enable_disable = enable_disable;
10328
10329   S (mp);
10330   W (ret);
10331   return ret;
10332 }
10333
10334 static int
10335 api_l2tpv3_set_lookup_key (vat_main_t * vam)
10336 {
10337   unformat_input_t *i = vam->input;
10338   vl_api_l2tpv3_set_lookup_key_t *mp;
10339   u8 key = ~0;
10340   int ret;
10341
10342   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10343     {
10344       if (unformat (i, "lookup_v6_src"))
10345         key = L2T_LOOKUP_SRC_ADDRESS;
10346       else if (unformat (i, "lookup_v6_dst"))
10347         key = L2T_LOOKUP_DST_ADDRESS;
10348       else if (unformat (i, "lookup_session_id"))
10349         key = L2T_LOOKUP_SESSION_ID;
10350       else
10351         break;
10352     }
10353
10354   if (key == (u8) ~ 0)
10355     {
10356       errmsg ("l2tp session lookup key unset");
10357       return -99;
10358     }
10359
10360   M (L2TPV3_SET_LOOKUP_KEY, mp);
10361
10362   mp->key = key;
10363
10364   S (mp);
10365   W (ret);
10366   return ret;
10367 }
10368
10369 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
10370   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
10371 {
10372   vat_main_t *vam = &vat_main;
10373
10374   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
10375          format_ip6_address, mp->our_address,
10376          format_ip6_address, mp->client_address,
10377          clib_net_to_host_u32 (mp->sw_if_index));
10378
10379   print (vam->ofp,
10380          "   local cookies %016llx %016llx remote cookie %016llx",
10381          clib_net_to_host_u64 (mp->local_cookie[0]),
10382          clib_net_to_host_u64 (mp->local_cookie[1]),
10383          clib_net_to_host_u64 (mp->remote_cookie));
10384
10385   print (vam->ofp, "   local session-id %d remote session-id %d",
10386          clib_net_to_host_u32 (mp->local_session_id),
10387          clib_net_to_host_u32 (mp->remote_session_id));
10388
10389   print (vam->ofp, "   l2 specific sublayer %s\n",
10390          mp->l2_sublayer_present ? "preset" : "absent");
10391
10392 }
10393
10394 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
10395   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
10396 {
10397   vat_main_t *vam = &vat_main;
10398   vat_json_node_t *node = NULL;
10399   struct in6_addr addr;
10400
10401   if (VAT_JSON_ARRAY != vam->json_tree.type)
10402     {
10403       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10404       vat_json_init_array (&vam->json_tree);
10405     }
10406   node = vat_json_array_add (&vam->json_tree);
10407
10408   vat_json_init_object (node);
10409
10410   clib_memcpy (&addr, mp->our_address, sizeof (addr));
10411   vat_json_object_add_ip6 (node, "our_address", addr);
10412   clib_memcpy (&addr, mp->client_address, sizeof (addr));
10413   vat_json_object_add_ip6 (node, "client_address", addr);
10414
10415   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
10416   vat_json_init_array (lc);
10417   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
10418   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
10419   vat_json_object_add_uint (node, "remote_cookie",
10420                             clib_net_to_host_u64 (mp->remote_cookie));
10421
10422   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
10423   vat_json_object_add_uint (node, "local_session_id",
10424                             clib_net_to_host_u32 (mp->local_session_id));
10425   vat_json_object_add_uint (node, "remote_session_id",
10426                             clib_net_to_host_u32 (mp->remote_session_id));
10427   vat_json_object_add_string_copy (node, "l2_sublayer",
10428                                    mp->l2_sublayer_present ? (u8 *) "present"
10429                                    : (u8 *) "absent");
10430 }
10431
10432 static int
10433 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
10434 {
10435   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
10436   vl_api_control_ping_t *mp_ping;
10437   int ret;
10438
10439   /* Get list of l2tpv3-tunnel interfaces */
10440   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
10441   S (mp);
10442
10443   /* Use a control ping for synchronization */
10444   M (CONTROL_PING, mp_ping);
10445   S (mp_ping);
10446
10447   W (ret);
10448   return ret;
10449 }
10450
10451
10452 static void vl_api_sw_interface_tap_details_t_handler
10453   (vl_api_sw_interface_tap_details_t * mp)
10454 {
10455   vat_main_t *vam = &vat_main;
10456
10457   print (vam->ofp, "%-16s %d",
10458          mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
10459 }
10460
10461 static void vl_api_sw_interface_tap_details_t_handler_json
10462   (vl_api_sw_interface_tap_details_t * mp)
10463 {
10464   vat_main_t *vam = &vat_main;
10465   vat_json_node_t *node = NULL;
10466
10467   if (VAT_JSON_ARRAY != vam->json_tree.type)
10468     {
10469       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10470       vat_json_init_array (&vam->json_tree);
10471     }
10472   node = vat_json_array_add (&vam->json_tree);
10473
10474   vat_json_init_object (node);
10475   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10476   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
10477 }
10478
10479 static int
10480 api_sw_interface_tap_dump (vat_main_t * vam)
10481 {
10482   vl_api_sw_interface_tap_dump_t *mp;
10483   vl_api_control_ping_t *mp_ping;
10484   int ret;
10485
10486   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
10487   /* Get list of tap interfaces */
10488   M (SW_INTERFACE_TAP_DUMP, mp);
10489   S (mp);
10490
10491   /* Use a control ping for synchronization */
10492   M (CONTROL_PING, mp_ping);
10493   S (mp_ping);
10494
10495   W (ret);
10496   return ret;
10497 }
10498
10499 static uword unformat_vxlan_decap_next
10500   (unformat_input_t * input, va_list * args)
10501 {
10502   u32 *result = va_arg (*args, u32 *);
10503   u32 tmp;
10504
10505   if (unformat (input, "l2"))
10506     *result = VXLAN_INPUT_NEXT_L2_INPUT;
10507   else if (unformat (input, "%d", &tmp))
10508     *result = tmp;
10509   else
10510     return 0;
10511   return 1;
10512 }
10513
10514 static int
10515 api_vxlan_add_del_tunnel (vat_main_t * vam)
10516 {
10517   unformat_input_t *line_input = vam->input;
10518   vl_api_vxlan_add_del_tunnel_t *mp;
10519   ip46_address_t src, dst;
10520   u8 is_add = 1;
10521   u8 ipv4_set = 0, ipv6_set = 0;
10522   u8 src_set = 0;
10523   u8 dst_set = 0;
10524   u8 grp_set = 0;
10525   u32 mcast_sw_if_index = ~0;
10526   u32 encap_vrf_id = 0;
10527   u32 decap_next_index = ~0;
10528   u32 vni = 0;
10529   int ret;
10530
10531   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
10532   memset (&src, 0, sizeof src);
10533   memset (&dst, 0, sizeof dst);
10534
10535   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10536     {
10537       if (unformat (line_input, "del"))
10538         is_add = 0;
10539       else
10540         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
10541         {
10542           ipv4_set = 1;
10543           src_set = 1;
10544         }
10545       else
10546         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
10547         {
10548           ipv4_set = 1;
10549           dst_set = 1;
10550         }
10551       else
10552         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
10553         {
10554           ipv6_set = 1;
10555           src_set = 1;
10556         }
10557       else
10558         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
10559         {
10560           ipv6_set = 1;
10561           dst_set = 1;
10562         }
10563       else if (unformat (line_input, "group %U %U",
10564                          unformat_ip4_address, &dst.ip4,
10565                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
10566         {
10567           grp_set = dst_set = 1;
10568           ipv4_set = 1;
10569         }
10570       else if (unformat (line_input, "group %U",
10571                          unformat_ip4_address, &dst.ip4))
10572         {
10573           grp_set = dst_set = 1;
10574           ipv4_set = 1;
10575         }
10576       else if (unformat (line_input, "group %U %U",
10577                          unformat_ip6_address, &dst.ip6,
10578                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
10579         {
10580           grp_set = dst_set = 1;
10581           ipv6_set = 1;
10582         }
10583       else if (unformat (line_input, "group %U",
10584                          unformat_ip6_address, &dst.ip6))
10585         {
10586           grp_set = dst_set = 1;
10587           ipv6_set = 1;
10588         }
10589       else
10590         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
10591         ;
10592       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
10593         ;
10594       else if (unformat (line_input, "decap-next %U",
10595                          unformat_vxlan_decap_next, &decap_next_index))
10596         ;
10597       else if (unformat (line_input, "vni %d", &vni))
10598         ;
10599       else
10600         {
10601           errmsg ("parse error '%U'", format_unformat_error, line_input);
10602           return -99;
10603         }
10604     }
10605
10606   if (src_set == 0)
10607     {
10608       errmsg ("tunnel src address not specified");
10609       return -99;
10610     }
10611   if (dst_set == 0)
10612     {
10613       errmsg ("tunnel dst address not specified");
10614       return -99;
10615     }
10616
10617   if (grp_set && !ip46_address_is_multicast (&dst))
10618     {
10619       errmsg ("tunnel group address not multicast");
10620       return -99;
10621     }
10622   if (grp_set && mcast_sw_if_index == ~0)
10623     {
10624       errmsg ("tunnel nonexistent multicast device");
10625       return -99;
10626     }
10627   if (grp_set == 0 && ip46_address_is_multicast (&dst))
10628     {
10629       errmsg ("tunnel dst address must be unicast");
10630       return -99;
10631     }
10632
10633
10634   if (ipv4_set && ipv6_set)
10635     {
10636       errmsg ("both IPv4 and IPv6 addresses specified");
10637       return -99;
10638     }
10639
10640   if ((vni == 0) || (vni >> 24))
10641     {
10642       errmsg ("vni not specified or out of range");
10643       return -99;
10644     }
10645
10646   M (VXLAN_ADD_DEL_TUNNEL, mp);
10647
10648   if (ipv6_set)
10649     {
10650       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
10651       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
10652     }
10653   else
10654     {
10655       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
10656       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
10657     }
10658   mp->encap_vrf_id = ntohl (encap_vrf_id);
10659   mp->decap_next_index = ntohl (decap_next_index);
10660   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
10661   mp->vni = ntohl (vni);
10662   mp->is_add = is_add;
10663   mp->is_ipv6 = ipv6_set;
10664
10665   S (mp);
10666   W (ret);
10667   return ret;
10668 }
10669
10670 static void vl_api_vxlan_tunnel_details_t_handler
10671   (vl_api_vxlan_tunnel_details_t * mp)
10672 {
10673   vat_main_t *vam = &vat_main;
10674   ip46_address_t src, dst;
10675
10676   ip46_from_addr_buf (mp->is_ipv6, mp->src_address, &src);
10677   ip46_from_addr_buf (mp->is_ipv6, mp->dst_address, &dst);
10678
10679   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
10680          ntohl (mp->sw_if_index),
10681          format_ip46_address, &src, IP46_TYPE_ANY,
10682          format_ip46_address, &dst, IP46_TYPE_ANY,
10683          ntohl (mp->encap_vrf_id),
10684          ntohl (mp->decap_next_index), ntohl (mp->vni),
10685          ntohl (mp->mcast_sw_if_index));
10686 }
10687
10688 static void vl_api_vxlan_tunnel_details_t_handler_json
10689   (vl_api_vxlan_tunnel_details_t * mp)
10690 {
10691   vat_main_t *vam = &vat_main;
10692   vat_json_node_t *node = NULL;
10693
10694   if (VAT_JSON_ARRAY != vam->json_tree.type)
10695     {
10696       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10697       vat_json_init_array (&vam->json_tree);
10698     }
10699   node = vat_json_array_add (&vam->json_tree);
10700
10701   vat_json_init_object (node);
10702   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10703   if (mp->is_ipv6)
10704     {
10705       struct in6_addr ip6;
10706
10707       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
10708       vat_json_object_add_ip6 (node, "src_address", ip6);
10709       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
10710       vat_json_object_add_ip6 (node, "dst_address", ip6);
10711     }
10712   else
10713     {
10714       struct in_addr ip4;
10715
10716       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
10717       vat_json_object_add_ip4 (node, "src_address", ip4);
10718       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
10719       vat_json_object_add_ip4 (node, "dst_address", ip4);
10720     }
10721   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
10722   vat_json_object_add_uint (node, "decap_next_index",
10723                             ntohl (mp->decap_next_index));
10724   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
10725   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
10726   vat_json_object_add_uint (node, "mcast_sw_if_index",
10727                             ntohl (mp->mcast_sw_if_index));
10728 }
10729
10730 static int
10731 api_vxlan_tunnel_dump (vat_main_t * vam)
10732 {
10733   unformat_input_t *i = vam->input;
10734   vl_api_vxlan_tunnel_dump_t *mp;
10735   vl_api_control_ping_t *mp_ping;
10736   u32 sw_if_index;
10737   u8 sw_if_index_set = 0;
10738   int ret;
10739
10740   /* Parse args required to build the message */
10741   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10742     {
10743       if (unformat (i, "sw_if_index %d", &sw_if_index))
10744         sw_if_index_set = 1;
10745       else
10746         break;
10747     }
10748
10749   if (sw_if_index_set == 0)
10750     {
10751       sw_if_index = ~0;
10752     }
10753
10754   if (!vam->json_output)
10755     {
10756       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
10757              "sw_if_index", "src_address", "dst_address",
10758              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
10759     }
10760
10761   /* Get list of vxlan-tunnel interfaces */
10762   M (VXLAN_TUNNEL_DUMP, mp);
10763
10764   mp->sw_if_index = htonl (sw_if_index);
10765
10766   S (mp);
10767
10768   /* Use a control ping for synchronization */
10769   M (CONTROL_PING, mp_ping);
10770   S (mp_ping);
10771
10772   W (ret);
10773   return ret;
10774 }
10775
10776 static int
10777 api_gre_add_del_tunnel (vat_main_t * vam)
10778 {
10779   unformat_input_t *line_input = vam->input;
10780   vl_api_gre_add_del_tunnel_t *mp;
10781   ip4_address_t src4, dst4;
10782   u8 is_add = 1;
10783   u8 teb = 0;
10784   u8 src_set = 0;
10785   u8 dst_set = 0;
10786   u32 outer_fib_id = 0;
10787   int ret;
10788
10789   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10790     {
10791       if (unformat (line_input, "del"))
10792         is_add = 0;
10793       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
10794         src_set = 1;
10795       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
10796         dst_set = 1;
10797       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
10798         ;
10799       else if (unformat (line_input, "teb"))
10800         teb = 1;
10801       else
10802         {
10803           errmsg ("parse error '%U'", format_unformat_error, line_input);
10804           return -99;
10805         }
10806     }
10807
10808   if (src_set == 0)
10809     {
10810       errmsg ("tunnel src address not specified");
10811       return -99;
10812     }
10813   if (dst_set == 0)
10814     {
10815       errmsg ("tunnel dst address not specified");
10816       return -99;
10817     }
10818
10819
10820   M (GRE_ADD_DEL_TUNNEL, mp);
10821
10822   clib_memcpy (&mp->src_address, &src4, sizeof (src4));
10823   clib_memcpy (&mp->dst_address, &dst4, sizeof (dst4));
10824   mp->outer_fib_id = ntohl (outer_fib_id);
10825   mp->is_add = is_add;
10826   mp->teb = teb;
10827
10828   S (mp);
10829   W (ret);
10830   return ret;
10831 }
10832
10833 static void vl_api_gre_tunnel_details_t_handler
10834   (vl_api_gre_tunnel_details_t * mp)
10835 {
10836   vat_main_t *vam = &vat_main;
10837
10838   print (vam->ofp, "%11d%15U%15U%6d%14d",
10839          ntohl (mp->sw_if_index),
10840          format_ip4_address, &mp->src_address,
10841          format_ip4_address, &mp->dst_address,
10842          mp->teb, ntohl (mp->outer_fib_id));
10843 }
10844
10845 static void vl_api_gre_tunnel_details_t_handler_json
10846   (vl_api_gre_tunnel_details_t * mp)
10847 {
10848   vat_main_t *vam = &vat_main;
10849   vat_json_node_t *node = NULL;
10850   struct in_addr ip4;
10851
10852   if (VAT_JSON_ARRAY != vam->json_tree.type)
10853     {
10854       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10855       vat_json_init_array (&vam->json_tree);
10856     }
10857   node = vat_json_array_add (&vam->json_tree);
10858
10859   vat_json_init_object (node);
10860   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10861   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
10862   vat_json_object_add_ip4 (node, "src_address", ip4);
10863   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
10864   vat_json_object_add_ip4 (node, "dst_address", ip4);
10865   vat_json_object_add_uint (node, "teb", mp->teb);
10866   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
10867 }
10868
10869 static int
10870 api_gre_tunnel_dump (vat_main_t * vam)
10871 {
10872   unformat_input_t *i = vam->input;
10873   vl_api_gre_tunnel_dump_t *mp;
10874   vl_api_control_ping_t *mp_ping;
10875   u32 sw_if_index;
10876   u8 sw_if_index_set = 0;
10877   int ret;
10878
10879   /* Parse args required to build the message */
10880   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10881     {
10882       if (unformat (i, "sw_if_index %d", &sw_if_index))
10883         sw_if_index_set = 1;
10884       else
10885         break;
10886     }
10887
10888   if (sw_if_index_set == 0)
10889     {
10890       sw_if_index = ~0;
10891     }
10892
10893   if (!vam->json_output)
10894     {
10895       print (vam->ofp, "%11s%15s%15s%6s%14s",
10896              "sw_if_index", "src_address", "dst_address", "teb",
10897              "outer_fib_id");
10898     }
10899
10900   /* Get list of gre-tunnel interfaces */
10901   M (GRE_TUNNEL_DUMP, mp);
10902
10903   mp->sw_if_index = htonl (sw_if_index);
10904
10905   S (mp);
10906
10907   /* Use a control ping for synchronization */
10908   M (CONTROL_PING, mp_ping);
10909   S (mp_ping);
10910
10911   W (ret);
10912   return ret;
10913 }
10914
10915 static int
10916 api_l2_fib_clear_table (vat_main_t * vam)
10917 {
10918 //  unformat_input_t * i = vam->input;
10919   vl_api_l2_fib_clear_table_t *mp;
10920   int ret;
10921
10922   M (L2_FIB_CLEAR_TABLE, mp);
10923
10924   S (mp);
10925   W (ret);
10926   return ret;
10927 }
10928
10929 static int
10930 api_l2_interface_efp_filter (vat_main_t * vam)
10931 {
10932   unformat_input_t *i = vam->input;
10933   vl_api_l2_interface_efp_filter_t *mp;
10934   u32 sw_if_index;
10935   u8 enable = 1;
10936   u8 sw_if_index_set = 0;
10937   int ret;
10938
10939   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10940     {
10941       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10942         sw_if_index_set = 1;
10943       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10944         sw_if_index_set = 1;
10945       else if (unformat (i, "enable"))
10946         enable = 1;
10947       else if (unformat (i, "disable"))
10948         enable = 0;
10949       else
10950         {
10951           clib_warning ("parse error '%U'", format_unformat_error, i);
10952           return -99;
10953         }
10954     }
10955
10956   if (sw_if_index_set == 0)
10957     {
10958       errmsg ("missing sw_if_index");
10959       return -99;
10960     }
10961
10962   M (L2_INTERFACE_EFP_FILTER, mp);
10963
10964   mp->sw_if_index = ntohl (sw_if_index);
10965   mp->enable_disable = enable;
10966
10967   S (mp);
10968   W (ret);
10969   return ret;
10970 }
10971
10972 #define foreach_vtr_op                          \
10973 _("disable",  L2_VTR_DISABLED)                  \
10974 _("push-1",  L2_VTR_PUSH_1)                     \
10975 _("push-2",  L2_VTR_PUSH_2)                     \
10976 _("pop-1",  L2_VTR_POP_1)                       \
10977 _("pop-2",  L2_VTR_POP_2)                       \
10978 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
10979 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
10980 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
10981 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
10982
10983 static int
10984 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
10985 {
10986   unformat_input_t *i = vam->input;
10987   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
10988   u32 sw_if_index;
10989   u8 sw_if_index_set = 0;
10990   u8 vtr_op_set = 0;
10991   u32 vtr_op = 0;
10992   u32 push_dot1q = 1;
10993   u32 tag1 = ~0;
10994   u32 tag2 = ~0;
10995   int ret;
10996
10997   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10998     {
10999       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11000         sw_if_index_set = 1;
11001       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11002         sw_if_index_set = 1;
11003       else if (unformat (i, "vtr_op %d", &vtr_op))
11004         vtr_op_set = 1;
11005 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
11006       foreach_vtr_op
11007 #undef _
11008         else if (unformat (i, "push_dot1q %d", &push_dot1q))
11009         ;
11010       else if (unformat (i, "tag1 %d", &tag1))
11011         ;
11012       else if (unformat (i, "tag2 %d", &tag2))
11013         ;
11014       else
11015         {
11016           clib_warning ("parse error '%U'", format_unformat_error, i);
11017           return -99;
11018         }
11019     }
11020
11021   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
11022     {
11023       errmsg ("missing vtr operation or sw_if_index");
11024       return -99;
11025     }
11026
11027   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
11028   mp->sw_if_index = ntohl (sw_if_index);
11029   mp->vtr_op = ntohl (vtr_op);
11030   mp->push_dot1q = ntohl (push_dot1q);
11031   mp->tag1 = ntohl (tag1);
11032   mp->tag2 = ntohl (tag2);
11033
11034   S (mp);
11035   W (ret);
11036   return ret;
11037 }
11038
11039 static int
11040 api_create_vhost_user_if (vat_main_t * vam)
11041 {
11042   unformat_input_t *i = vam->input;
11043   vl_api_create_vhost_user_if_t *mp;
11044   u8 *file_name;
11045   u8 is_server = 0;
11046   u8 file_name_set = 0;
11047   u32 custom_dev_instance = ~0;
11048   u8 hwaddr[6];
11049   u8 use_custom_mac = 0;
11050   u8 *tag = 0;
11051   int ret;
11052
11053   /* Shut up coverity */
11054   memset (hwaddr, 0, sizeof (hwaddr));
11055
11056   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11057     {
11058       if (unformat (i, "socket %s", &file_name))
11059         {
11060           file_name_set = 1;
11061         }
11062       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
11063         ;
11064       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
11065         use_custom_mac = 1;
11066       else if (unformat (i, "server"))
11067         is_server = 1;
11068       else if (unformat (i, "tag %s", &tag))
11069         ;
11070       else
11071         break;
11072     }
11073
11074   if (file_name_set == 0)
11075     {
11076       errmsg ("missing socket file name");
11077       return -99;
11078     }
11079
11080   if (vec_len (file_name) > 255)
11081     {
11082       errmsg ("socket file name too long");
11083       return -99;
11084     }
11085   vec_add1 (file_name, 0);
11086
11087   M (CREATE_VHOST_USER_IF, mp);
11088
11089   mp->is_server = is_server;
11090   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
11091   vec_free (file_name);
11092   if (custom_dev_instance != ~0)
11093     {
11094       mp->renumber = 1;
11095       mp->custom_dev_instance = ntohl (custom_dev_instance);
11096     }
11097   mp->use_custom_mac = use_custom_mac;
11098   clib_memcpy (mp->mac_address, hwaddr, 6);
11099   if (tag)
11100     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
11101   vec_free (tag);
11102
11103   S (mp);
11104   W (ret);
11105   return ret;
11106 }
11107
11108 static int
11109 api_modify_vhost_user_if (vat_main_t * vam)
11110 {
11111   unformat_input_t *i = vam->input;
11112   vl_api_modify_vhost_user_if_t *mp;
11113   u8 *file_name;
11114   u8 is_server = 0;
11115   u8 file_name_set = 0;
11116   u32 custom_dev_instance = ~0;
11117   u8 sw_if_index_set = 0;
11118   u32 sw_if_index = (u32) ~ 0;
11119   int ret;
11120
11121   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11122     {
11123       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11124         sw_if_index_set = 1;
11125       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11126         sw_if_index_set = 1;
11127       else if (unformat (i, "socket %s", &file_name))
11128         {
11129           file_name_set = 1;
11130         }
11131       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
11132         ;
11133       else if (unformat (i, "server"))
11134         is_server = 1;
11135       else
11136         break;
11137     }
11138
11139   if (sw_if_index_set == 0)
11140     {
11141       errmsg ("missing sw_if_index or interface name");
11142       return -99;
11143     }
11144
11145   if (file_name_set == 0)
11146     {
11147       errmsg ("missing socket file name");
11148       return -99;
11149     }
11150
11151   if (vec_len (file_name) > 255)
11152     {
11153       errmsg ("socket file name too long");
11154       return -99;
11155     }
11156   vec_add1 (file_name, 0);
11157
11158   M (MODIFY_VHOST_USER_IF, mp);
11159
11160   mp->sw_if_index = ntohl (sw_if_index);
11161   mp->is_server = is_server;
11162   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
11163   vec_free (file_name);
11164   if (custom_dev_instance != ~0)
11165     {
11166       mp->renumber = 1;
11167       mp->custom_dev_instance = ntohl (custom_dev_instance);
11168     }
11169
11170   S (mp);
11171   W (ret);
11172   return ret;
11173 }
11174
11175 static int
11176 api_delete_vhost_user_if (vat_main_t * vam)
11177 {
11178   unformat_input_t *i = vam->input;
11179   vl_api_delete_vhost_user_if_t *mp;
11180   u32 sw_if_index = ~0;
11181   u8 sw_if_index_set = 0;
11182   int ret;
11183
11184   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11185     {
11186       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11187         sw_if_index_set = 1;
11188       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11189         sw_if_index_set = 1;
11190       else
11191         break;
11192     }
11193
11194   if (sw_if_index_set == 0)
11195     {
11196       errmsg ("missing sw_if_index or interface name");
11197       return -99;
11198     }
11199
11200
11201   M (DELETE_VHOST_USER_IF, mp);
11202
11203   mp->sw_if_index = ntohl (sw_if_index);
11204
11205   S (mp);
11206   W (ret);
11207   return ret;
11208 }
11209
11210 static void vl_api_sw_interface_vhost_user_details_t_handler
11211   (vl_api_sw_interface_vhost_user_details_t * mp)
11212 {
11213   vat_main_t *vam = &vat_main;
11214
11215   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
11216          (char *) mp->interface_name,
11217          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
11218          clib_net_to_host_u64 (mp->features), mp->is_server,
11219          ntohl (mp->num_regions), (char *) mp->sock_filename);
11220   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
11221 }
11222
11223 static void vl_api_sw_interface_vhost_user_details_t_handler_json
11224   (vl_api_sw_interface_vhost_user_details_t * mp)
11225 {
11226   vat_main_t *vam = &vat_main;
11227   vat_json_node_t *node = NULL;
11228
11229   if (VAT_JSON_ARRAY != vam->json_tree.type)
11230     {
11231       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11232       vat_json_init_array (&vam->json_tree);
11233     }
11234   node = vat_json_array_add (&vam->json_tree);
11235
11236   vat_json_init_object (node);
11237   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11238   vat_json_object_add_string_copy (node, "interface_name",
11239                                    mp->interface_name);
11240   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
11241                             ntohl (mp->virtio_net_hdr_sz));
11242   vat_json_object_add_uint (node, "features",
11243                             clib_net_to_host_u64 (mp->features));
11244   vat_json_object_add_uint (node, "is_server", mp->is_server);
11245   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
11246   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
11247   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
11248 }
11249
11250 static int
11251 api_sw_interface_vhost_user_dump (vat_main_t * vam)
11252 {
11253   vl_api_sw_interface_vhost_user_dump_t *mp;
11254   vl_api_control_ping_t *mp_ping;
11255   int ret;
11256   print (vam->ofp,
11257          "Interface name           idx hdr_sz features server regions filename");
11258
11259   /* Get list of vhost-user interfaces */
11260   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
11261   S (mp);
11262
11263   /* Use a control ping for synchronization */
11264   M (CONTROL_PING, mp_ping);
11265   S (mp_ping);
11266
11267   W (ret);
11268   return ret;
11269 }
11270
11271 static int
11272 api_show_version (vat_main_t * vam)
11273 {
11274   vl_api_show_version_t *mp;
11275   int ret;
11276
11277   M (SHOW_VERSION, mp);
11278
11279   S (mp);
11280   W (ret);
11281   return ret;
11282 }
11283
11284
11285 static int
11286 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
11287 {
11288   unformat_input_t *line_input = vam->input;
11289   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
11290   ip4_address_t local4, remote4;
11291   ip6_address_t local6, remote6;
11292   u8 is_add = 1;
11293   u8 ipv4_set = 0, ipv6_set = 0;
11294   u8 local_set = 0;
11295   u8 remote_set = 0;
11296   u32 encap_vrf_id = 0;
11297   u32 decap_vrf_id = 0;
11298   u8 protocol = ~0;
11299   u32 vni;
11300   u8 vni_set = 0;
11301   int ret;
11302
11303   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11304     {
11305       if (unformat (line_input, "del"))
11306         is_add = 0;
11307       else if (unformat (line_input, "local %U",
11308                          unformat_ip4_address, &local4))
11309         {
11310           local_set = 1;
11311           ipv4_set = 1;
11312         }
11313       else if (unformat (line_input, "remote %U",
11314                          unformat_ip4_address, &remote4))
11315         {
11316           remote_set = 1;
11317           ipv4_set = 1;
11318         }
11319       else if (unformat (line_input, "local %U",
11320                          unformat_ip6_address, &local6))
11321         {
11322           local_set = 1;
11323           ipv6_set = 1;
11324         }
11325       else if (unformat (line_input, "remote %U",
11326                          unformat_ip6_address, &remote6))
11327         {
11328           remote_set = 1;
11329           ipv6_set = 1;
11330         }
11331       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
11332         ;
11333       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
11334         ;
11335       else if (unformat (line_input, "vni %d", &vni))
11336         vni_set = 1;
11337       else if (unformat (line_input, "next-ip4"))
11338         protocol = 1;
11339       else if (unformat (line_input, "next-ip6"))
11340         protocol = 2;
11341       else if (unformat (line_input, "next-ethernet"))
11342         protocol = 3;
11343       else if (unformat (line_input, "next-nsh"))
11344         protocol = 4;
11345       else
11346         {
11347           errmsg ("parse error '%U'", format_unformat_error, line_input);
11348           return -99;
11349         }
11350     }
11351
11352   if (local_set == 0)
11353     {
11354       errmsg ("tunnel local address not specified");
11355       return -99;
11356     }
11357   if (remote_set == 0)
11358     {
11359       errmsg ("tunnel remote address not specified");
11360       return -99;
11361     }
11362   if (ipv4_set && ipv6_set)
11363     {
11364       errmsg ("both IPv4 and IPv6 addresses specified");
11365       return -99;
11366     }
11367
11368   if (vni_set == 0)
11369     {
11370       errmsg ("vni not specified");
11371       return -99;
11372     }
11373
11374   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
11375
11376
11377   if (ipv6_set)
11378     {
11379       clib_memcpy (&mp->local, &local6, sizeof (local6));
11380       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
11381     }
11382   else
11383     {
11384       clib_memcpy (&mp->local, &local4, sizeof (local4));
11385       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
11386     }
11387
11388   mp->encap_vrf_id = ntohl (encap_vrf_id);
11389   mp->decap_vrf_id = ntohl (decap_vrf_id);
11390   mp->protocol = protocol;
11391   mp->vni = ntohl (vni);
11392   mp->is_add = is_add;
11393   mp->is_ipv6 = ipv6_set;
11394
11395   S (mp);
11396   W (ret);
11397   return ret;
11398 }
11399
11400 static void vl_api_vxlan_gpe_tunnel_details_t_handler
11401   (vl_api_vxlan_gpe_tunnel_details_t * mp)
11402 {
11403   vat_main_t *vam = &vat_main;
11404
11405   print (vam->ofp, "%11d%24U%24U%13d%12d%14d%14d",
11406          ntohl (mp->sw_if_index),
11407          format_ip46_address, &(mp->local[0]),
11408          format_ip46_address, &(mp->remote[0]),
11409          ntohl (mp->vni),
11410          ntohl (mp->protocol),
11411          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
11412 }
11413
11414 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
11415   (vl_api_vxlan_gpe_tunnel_details_t * mp)
11416 {
11417   vat_main_t *vam = &vat_main;
11418   vat_json_node_t *node = NULL;
11419   struct in_addr ip4;
11420   struct in6_addr ip6;
11421
11422   if (VAT_JSON_ARRAY != vam->json_tree.type)
11423     {
11424       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11425       vat_json_init_array (&vam->json_tree);
11426     }
11427   node = vat_json_array_add (&vam->json_tree);
11428
11429   vat_json_init_object (node);
11430   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11431   if (mp->is_ipv6)
11432     {
11433       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
11434       vat_json_object_add_ip6 (node, "local", ip6);
11435       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
11436       vat_json_object_add_ip6 (node, "remote", ip6);
11437     }
11438   else
11439     {
11440       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
11441       vat_json_object_add_ip4 (node, "local", ip4);
11442       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
11443       vat_json_object_add_ip4 (node, "remote", ip4);
11444     }
11445   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
11446   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
11447   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
11448   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
11449   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
11450 }
11451
11452 static int
11453 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
11454 {
11455   unformat_input_t *i = vam->input;
11456   vl_api_vxlan_gpe_tunnel_dump_t *mp;
11457   vl_api_control_ping_t *mp_ping;
11458   u32 sw_if_index;
11459   u8 sw_if_index_set = 0;
11460   int ret;
11461
11462   /* Parse args required to build the message */
11463   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11464     {
11465       if (unformat (i, "sw_if_index %d", &sw_if_index))
11466         sw_if_index_set = 1;
11467       else
11468         break;
11469     }
11470
11471   if (sw_if_index_set == 0)
11472     {
11473       sw_if_index = ~0;
11474     }
11475
11476   if (!vam->json_output)
11477     {
11478       print (vam->ofp, "%11s%24s%24s%13s%15s%14s%14s",
11479              "sw_if_index", "local", "remote", "vni",
11480              "protocol", "encap_vrf_id", "decap_vrf_id");
11481     }
11482
11483   /* Get list of vxlan-tunnel interfaces */
11484   M (VXLAN_GPE_TUNNEL_DUMP, mp);
11485
11486   mp->sw_if_index = htonl (sw_if_index);
11487
11488   S (mp);
11489
11490   /* Use a control ping for synchronization */
11491   M (CONTROL_PING, mp_ping);
11492   S (mp_ping);
11493
11494   W (ret);
11495   return ret;
11496 }
11497
11498 u8 *
11499 format_l2_fib_mac_address (u8 * s, va_list * args)
11500 {
11501   u8 *a = va_arg (*args, u8 *);
11502
11503   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
11504                  a[2], a[3], a[4], a[5], a[6], a[7]);
11505 }
11506
11507 static void vl_api_l2_fib_table_entry_t_handler
11508   (vl_api_l2_fib_table_entry_t * mp)
11509 {
11510   vat_main_t *vam = &vat_main;
11511
11512   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
11513          "       %d       %d     %d",
11514          ntohl (mp->bd_id), format_l2_fib_mac_address, &mp->mac,
11515          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
11516          mp->bvi_mac);
11517 }
11518
11519 static void vl_api_l2_fib_table_entry_t_handler_json
11520   (vl_api_l2_fib_table_entry_t * mp)
11521 {
11522   vat_main_t *vam = &vat_main;
11523   vat_json_node_t *node = NULL;
11524
11525   if (VAT_JSON_ARRAY != vam->json_tree.type)
11526     {
11527       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11528       vat_json_init_array (&vam->json_tree);
11529     }
11530   node = vat_json_array_add (&vam->json_tree);
11531
11532   vat_json_init_object (node);
11533   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
11534   vat_json_object_add_uint (node, "mac", clib_net_to_host_u64 (mp->mac));
11535   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11536   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
11537   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
11538   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
11539 }
11540
11541 static int
11542 api_l2_fib_table_dump (vat_main_t * vam)
11543 {
11544   unformat_input_t *i = vam->input;
11545   vl_api_l2_fib_table_dump_t *mp;
11546   vl_api_control_ping_t *mp_ping;
11547   u32 bd_id;
11548   u8 bd_id_set = 0;
11549   int ret;
11550
11551   /* Parse args required to build the message */
11552   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11553     {
11554       if (unformat (i, "bd_id %d", &bd_id))
11555         bd_id_set = 1;
11556       else
11557         break;
11558     }
11559
11560   if (bd_id_set == 0)
11561     {
11562       errmsg ("missing bridge domain");
11563       return -99;
11564     }
11565
11566   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
11567
11568   /* Get list of l2 fib entries */
11569   M (L2_FIB_TABLE_DUMP, mp);
11570
11571   mp->bd_id = ntohl (bd_id);
11572   S (mp);
11573
11574   /* Use a control ping for synchronization */
11575   M (CONTROL_PING, mp_ping);
11576   S (mp_ping);
11577
11578   W (ret);
11579   return ret;
11580 }
11581
11582
11583 static int
11584 api_interface_name_renumber (vat_main_t * vam)
11585 {
11586   unformat_input_t *line_input = vam->input;
11587   vl_api_interface_name_renumber_t *mp;
11588   u32 sw_if_index = ~0;
11589   u32 new_show_dev_instance = ~0;
11590   int ret;
11591
11592   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11593     {
11594       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
11595                     &sw_if_index))
11596         ;
11597       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
11598         ;
11599       else if (unformat (line_input, "new_show_dev_instance %d",
11600                          &new_show_dev_instance))
11601         ;
11602       else
11603         break;
11604     }
11605
11606   if (sw_if_index == ~0)
11607     {
11608       errmsg ("missing interface name or sw_if_index");
11609       return -99;
11610     }
11611
11612   if (new_show_dev_instance == ~0)
11613     {
11614       errmsg ("missing new_show_dev_instance");
11615       return -99;
11616     }
11617
11618   M (INTERFACE_NAME_RENUMBER, mp);
11619
11620   mp->sw_if_index = ntohl (sw_if_index);
11621   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
11622
11623   S (mp);
11624   W (ret);
11625   return ret;
11626 }
11627
11628 static int
11629 api_want_ip4_arp_events (vat_main_t * vam)
11630 {
11631   unformat_input_t *line_input = vam->input;
11632   vl_api_want_ip4_arp_events_t *mp;
11633   ip4_address_t address;
11634   int address_set = 0;
11635   u32 enable_disable = 1;
11636   int ret;
11637
11638   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11639     {
11640       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
11641         address_set = 1;
11642       else if (unformat (line_input, "del"))
11643         enable_disable = 0;
11644       else
11645         break;
11646     }
11647
11648   if (address_set == 0)
11649     {
11650       errmsg ("missing addresses");
11651       return -99;
11652     }
11653
11654   M (WANT_IP4_ARP_EVENTS, mp);
11655   mp->enable_disable = enable_disable;
11656   mp->pid = getpid ();
11657   mp->address = address.as_u32;
11658
11659   S (mp);
11660   W (ret);
11661   return ret;
11662 }
11663
11664 static int
11665 api_want_ip6_nd_events (vat_main_t * vam)
11666 {
11667   unformat_input_t *line_input = vam->input;
11668   vl_api_want_ip6_nd_events_t *mp;
11669   ip6_address_t address;
11670   int address_set = 0;
11671   u32 enable_disable = 1;
11672   int ret;
11673
11674   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11675     {
11676       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
11677         address_set = 1;
11678       else if (unformat (line_input, "del"))
11679         enable_disable = 0;
11680       else
11681         break;
11682     }
11683
11684   if (address_set == 0)
11685     {
11686       errmsg ("missing addresses");
11687       return -99;
11688     }
11689
11690   M (WANT_IP6_ND_EVENTS, mp);
11691   mp->enable_disable = enable_disable;
11692   mp->pid = getpid ();
11693   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
11694
11695   S (mp);
11696   W (ret);
11697   return ret;
11698 }
11699
11700 static int
11701 api_input_acl_set_interface (vat_main_t * vam)
11702 {
11703   unformat_input_t *i = vam->input;
11704   vl_api_input_acl_set_interface_t *mp;
11705   u32 sw_if_index;
11706   int sw_if_index_set;
11707   u32 ip4_table_index = ~0;
11708   u32 ip6_table_index = ~0;
11709   u32 l2_table_index = ~0;
11710   u8 is_add = 1;
11711   int ret;
11712
11713   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11714     {
11715       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11716         sw_if_index_set = 1;
11717       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11718         sw_if_index_set = 1;
11719       else if (unformat (i, "del"))
11720         is_add = 0;
11721       else if (unformat (i, "ip4-table %d", &ip4_table_index))
11722         ;
11723       else if (unformat (i, "ip6-table %d", &ip6_table_index))
11724         ;
11725       else if (unformat (i, "l2-table %d", &l2_table_index))
11726         ;
11727       else
11728         {
11729           clib_warning ("parse error '%U'", format_unformat_error, i);
11730           return -99;
11731         }
11732     }
11733
11734   if (sw_if_index_set == 0)
11735     {
11736       errmsg ("missing interface name or sw_if_index");
11737       return -99;
11738     }
11739
11740   M (INPUT_ACL_SET_INTERFACE, mp);
11741
11742   mp->sw_if_index = ntohl (sw_if_index);
11743   mp->ip4_table_index = ntohl (ip4_table_index);
11744   mp->ip6_table_index = ntohl (ip6_table_index);
11745   mp->l2_table_index = ntohl (l2_table_index);
11746   mp->is_add = is_add;
11747
11748   S (mp);
11749   W (ret);
11750   return ret;
11751 }
11752
11753 static int
11754 api_ip_address_dump (vat_main_t * vam)
11755 {
11756   unformat_input_t *i = vam->input;
11757   vl_api_ip_address_dump_t *mp;
11758   vl_api_control_ping_t *mp_ping;
11759   u32 sw_if_index = ~0;
11760   u8 sw_if_index_set = 0;
11761   u8 ipv4_set = 0;
11762   u8 ipv6_set = 0;
11763   int ret;
11764
11765   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11766     {
11767       if (unformat (i, "sw_if_index %d", &sw_if_index))
11768         sw_if_index_set = 1;
11769       else
11770         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11771         sw_if_index_set = 1;
11772       else if (unformat (i, "ipv4"))
11773         ipv4_set = 1;
11774       else if (unformat (i, "ipv6"))
11775         ipv6_set = 1;
11776       else
11777         break;
11778     }
11779
11780   if (ipv4_set && ipv6_set)
11781     {
11782       errmsg ("ipv4 and ipv6 flags cannot be both set");
11783       return -99;
11784     }
11785
11786   if ((!ipv4_set) && (!ipv6_set))
11787     {
11788       errmsg ("no ipv4 nor ipv6 flag set");
11789       return -99;
11790     }
11791
11792   if (sw_if_index_set == 0)
11793     {
11794       errmsg ("missing interface name or sw_if_index");
11795       return -99;
11796     }
11797
11798   vam->current_sw_if_index = sw_if_index;
11799   vam->is_ipv6 = ipv6_set;
11800
11801   M (IP_ADDRESS_DUMP, mp);
11802   mp->sw_if_index = ntohl (sw_if_index);
11803   mp->is_ipv6 = ipv6_set;
11804   S (mp);
11805
11806   /* Use a control ping for synchronization */
11807   M (CONTROL_PING, mp_ping);
11808   S (mp_ping);
11809
11810   W (ret);
11811   return ret;
11812 }
11813
11814 static int
11815 api_ip_dump (vat_main_t * vam)
11816 {
11817   vl_api_ip_dump_t *mp;
11818   vl_api_control_ping_t *mp_ping;
11819   unformat_input_t *in = vam->input;
11820   int ipv4_set = 0;
11821   int ipv6_set = 0;
11822   int is_ipv6;
11823   int i;
11824   int ret;
11825
11826   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
11827     {
11828       if (unformat (in, "ipv4"))
11829         ipv4_set = 1;
11830       else if (unformat (in, "ipv6"))
11831         ipv6_set = 1;
11832       else
11833         break;
11834     }
11835
11836   if (ipv4_set && ipv6_set)
11837     {
11838       errmsg ("ipv4 and ipv6 flags cannot be both set");
11839       return -99;
11840     }
11841
11842   if ((!ipv4_set) && (!ipv6_set))
11843     {
11844       errmsg ("no ipv4 nor ipv6 flag set");
11845       return -99;
11846     }
11847
11848   is_ipv6 = ipv6_set;
11849   vam->is_ipv6 = is_ipv6;
11850
11851   /* free old data */
11852   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
11853     {
11854       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
11855     }
11856   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
11857
11858   M (IP_DUMP, mp);
11859   mp->is_ipv6 = ipv6_set;
11860   S (mp);
11861
11862   /* Use a control ping for synchronization */
11863   M (CONTROL_PING, mp_ping);
11864   S (mp_ping);
11865
11866   W (ret);
11867   return ret;
11868 }
11869
11870 static int
11871 api_ipsec_spd_add_del (vat_main_t * vam)
11872 {
11873   unformat_input_t *i = vam->input;
11874   vl_api_ipsec_spd_add_del_t *mp;
11875   u32 spd_id = ~0;
11876   u8 is_add = 1;
11877   int ret;
11878
11879   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11880     {
11881       if (unformat (i, "spd_id %d", &spd_id))
11882         ;
11883       else if (unformat (i, "del"))
11884         is_add = 0;
11885       else
11886         {
11887           clib_warning ("parse error '%U'", format_unformat_error, i);
11888           return -99;
11889         }
11890     }
11891   if (spd_id == ~0)
11892     {
11893       errmsg ("spd_id must be set");
11894       return -99;
11895     }
11896
11897   M (IPSEC_SPD_ADD_DEL, mp);
11898
11899   mp->spd_id = ntohl (spd_id);
11900   mp->is_add = is_add;
11901
11902   S (mp);
11903   W (ret);
11904   return ret;
11905 }
11906
11907 static int
11908 api_ipsec_interface_add_del_spd (vat_main_t * vam)
11909 {
11910   unformat_input_t *i = vam->input;
11911   vl_api_ipsec_interface_add_del_spd_t *mp;
11912   u32 sw_if_index;
11913   u8 sw_if_index_set = 0;
11914   u32 spd_id = (u32) ~ 0;
11915   u8 is_add = 1;
11916   int ret;
11917
11918   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11919     {
11920       if (unformat (i, "del"))
11921         is_add = 0;
11922       else if (unformat (i, "spd_id %d", &spd_id))
11923         ;
11924       else
11925         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11926         sw_if_index_set = 1;
11927       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11928         sw_if_index_set = 1;
11929       else
11930         {
11931           clib_warning ("parse error '%U'", format_unformat_error, i);
11932           return -99;
11933         }
11934
11935     }
11936
11937   if (spd_id == (u32) ~ 0)
11938     {
11939       errmsg ("spd_id must be set");
11940       return -99;
11941     }
11942
11943   if (sw_if_index_set == 0)
11944     {
11945       errmsg ("missing interface name or sw_if_index");
11946       return -99;
11947     }
11948
11949   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
11950
11951   mp->spd_id = ntohl (spd_id);
11952   mp->sw_if_index = ntohl (sw_if_index);
11953   mp->is_add = is_add;
11954
11955   S (mp);
11956   W (ret);
11957   return ret;
11958 }
11959
11960 static int
11961 api_ipsec_spd_add_del_entry (vat_main_t * vam)
11962 {
11963   unformat_input_t *i = vam->input;
11964   vl_api_ipsec_spd_add_del_entry_t *mp;
11965   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
11966   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
11967   i32 priority = 0;
11968   u32 rport_start = 0, rport_stop = (u32) ~ 0;
11969   u32 lport_start = 0, lport_stop = (u32) ~ 0;
11970   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
11971   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
11972   int ret;
11973
11974   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
11975   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
11976   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
11977   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
11978   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
11979   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
11980
11981   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11982     {
11983       if (unformat (i, "del"))
11984         is_add = 0;
11985       if (unformat (i, "outbound"))
11986         is_outbound = 1;
11987       if (unformat (i, "inbound"))
11988         is_outbound = 0;
11989       else if (unformat (i, "spd_id %d", &spd_id))
11990         ;
11991       else if (unformat (i, "sa_id %d", &sa_id))
11992         ;
11993       else if (unformat (i, "priority %d", &priority))
11994         ;
11995       else if (unformat (i, "protocol %d", &protocol))
11996         ;
11997       else if (unformat (i, "lport_start %d", &lport_start))
11998         ;
11999       else if (unformat (i, "lport_stop %d", &lport_stop))
12000         ;
12001       else if (unformat (i, "rport_start %d", &rport_start))
12002         ;
12003       else if (unformat (i, "rport_stop %d", &rport_stop))
12004         ;
12005       else
12006         if (unformat
12007             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
12008         {
12009           is_ipv6 = 0;
12010           is_ip_any = 0;
12011         }
12012       else
12013         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
12014         {
12015           is_ipv6 = 0;
12016           is_ip_any = 0;
12017         }
12018       else
12019         if (unformat
12020             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
12021         {
12022           is_ipv6 = 0;
12023           is_ip_any = 0;
12024         }
12025       else
12026         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
12027         {
12028           is_ipv6 = 0;
12029           is_ip_any = 0;
12030         }
12031       else
12032         if (unformat
12033             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
12034         {
12035           is_ipv6 = 1;
12036           is_ip_any = 0;
12037         }
12038       else
12039         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
12040         {
12041           is_ipv6 = 1;
12042           is_ip_any = 0;
12043         }
12044       else
12045         if (unformat
12046             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
12047         {
12048           is_ipv6 = 1;
12049           is_ip_any = 0;
12050         }
12051       else
12052         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
12053         {
12054           is_ipv6 = 1;
12055           is_ip_any = 0;
12056         }
12057       else
12058         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
12059         {
12060           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
12061             {
12062               clib_warning ("unsupported action: 'resolve'");
12063               return -99;
12064             }
12065         }
12066       else
12067         {
12068           clib_warning ("parse error '%U'", format_unformat_error, i);
12069           return -99;
12070         }
12071
12072     }
12073
12074   M (IPSEC_SPD_ADD_DEL_ENTRY, mp);
12075
12076   mp->spd_id = ntohl (spd_id);
12077   mp->priority = ntohl (priority);
12078   mp->is_outbound = is_outbound;
12079
12080   mp->is_ipv6 = is_ipv6;
12081   if (is_ipv6 || is_ip_any)
12082     {
12083       clib_memcpy (mp->remote_address_start, &raddr6_start,
12084                    sizeof (ip6_address_t));
12085       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
12086                    sizeof (ip6_address_t));
12087       clib_memcpy (mp->local_address_start, &laddr6_start,
12088                    sizeof (ip6_address_t));
12089       clib_memcpy (mp->local_address_stop, &laddr6_stop,
12090                    sizeof (ip6_address_t));
12091     }
12092   else
12093     {
12094       clib_memcpy (mp->remote_address_start, &raddr4_start,
12095                    sizeof (ip4_address_t));
12096       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
12097                    sizeof (ip4_address_t));
12098       clib_memcpy (mp->local_address_start, &laddr4_start,
12099                    sizeof (ip4_address_t));
12100       clib_memcpy (mp->local_address_stop, &laddr4_stop,
12101                    sizeof (ip4_address_t));
12102     }
12103   mp->protocol = (u8) protocol;
12104   mp->local_port_start = ntohs ((u16) lport_start);
12105   mp->local_port_stop = ntohs ((u16) lport_stop);
12106   mp->remote_port_start = ntohs ((u16) rport_start);
12107   mp->remote_port_stop = ntohs ((u16) rport_stop);
12108   mp->policy = (u8) policy;
12109   mp->sa_id = ntohl (sa_id);
12110   mp->is_add = is_add;
12111   mp->is_ip_any = is_ip_any;
12112   S (mp);
12113   W (ret);
12114   return ret;
12115 }
12116
12117 static int
12118 api_ipsec_sad_add_del_entry (vat_main_t * vam)
12119 {
12120   unformat_input_t *i = vam->input;
12121   vl_api_ipsec_sad_add_del_entry_t *mp;
12122   u32 sad_id = 0, spi = 0;
12123   u8 *ck = 0, *ik = 0;
12124   u8 is_add = 1;
12125
12126   u8 protocol = IPSEC_PROTOCOL_AH;
12127   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
12128   u32 crypto_alg = 0, integ_alg = 0;
12129   ip4_address_t tun_src4;
12130   ip4_address_t tun_dst4;
12131   ip6_address_t tun_src6;
12132   ip6_address_t tun_dst6;
12133   int ret;
12134
12135   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12136     {
12137       if (unformat (i, "del"))
12138         is_add = 0;
12139       else if (unformat (i, "sad_id %d", &sad_id))
12140         ;
12141       else if (unformat (i, "spi %d", &spi))
12142         ;
12143       else if (unformat (i, "esp"))
12144         protocol = IPSEC_PROTOCOL_ESP;
12145       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
12146         {
12147           is_tunnel = 1;
12148           is_tunnel_ipv6 = 0;
12149         }
12150       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
12151         {
12152           is_tunnel = 1;
12153           is_tunnel_ipv6 = 0;
12154         }
12155       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
12156         {
12157           is_tunnel = 1;
12158           is_tunnel_ipv6 = 1;
12159         }
12160       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
12161         {
12162           is_tunnel = 1;
12163           is_tunnel_ipv6 = 1;
12164         }
12165       else
12166         if (unformat
12167             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
12168         {
12169           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
12170               crypto_alg >= IPSEC_CRYPTO_N_ALG)
12171             {
12172               clib_warning ("unsupported crypto-alg: '%U'",
12173                             format_ipsec_crypto_alg, crypto_alg);
12174               return -99;
12175             }
12176         }
12177       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
12178         ;
12179       else
12180         if (unformat
12181             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
12182         {
12183           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
12184               integ_alg >= IPSEC_INTEG_N_ALG)
12185             {
12186               clib_warning ("unsupported integ-alg: '%U'",
12187                             format_ipsec_integ_alg, integ_alg);
12188               return -99;
12189             }
12190         }
12191       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
12192         ;
12193       else
12194         {
12195           clib_warning ("parse error '%U'", format_unformat_error, i);
12196           return -99;
12197         }
12198
12199     }
12200
12201   M (IPSEC_SAD_ADD_DEL_ENTRY, mp);
12202
12203   mp->sad_id = ntohl (sad_id);
12204   mp->is_add = is_add;
12205   mp->protocol = protocol;
12206   mp->spi = ntohl (spi);
12207   mp->is_tunnel = is_tunnel;
12208   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
12209   mp->crypto_algorithm = crypto_alg;
12210   mp->integrity_algorithm = integ_alg;
12211   mp->crypto_key_length = vec_len (ck);
12212   mp->integrity_key_length = vec_len (ik);
12213
12214   if (mp->crypto_key_length > sizeof (mp->crypto_key))
12215     mp->crypto_key_length = sizeof (mp->crypto_key);
12216
12217   if (mp->integrity_key_length > sizeof (mp->integrity_key))
12218     mp->integrity_key_length = sizeof (mp->integrity_key);
12219
12220   if (ck)
12221     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
12222   if (ik)
12223     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
12224
12225   if (is_tunnel)
12226     {
12227       if (is_tunnel_ipv6)
12228         {
12229           clib_memcpy (mp->tunnel_src_address, &tun_src6,
12230                        sizeof (ip6_address_t));
12231           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
12232                        sizeof (ip6_address_t));
12233         }
12234       else
12235         {
12236           clib_memcpy (mp->tunnel_src_address, &tun_src4,
12237                        sizeof (ip4_address_t));
12238           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
12239                        sizeof (ip4_address_t));
12240         }
12241     }
12242
12243   S (mp);
12244   W (ret);
12245   return ret;
12246 }
12247
12248 static int
12249 api_ipsec_sa_set_key (vat_main_t * vam)
12250 {
12251   unformat_input_t *i = vam->input;
12252   vl_api_ipsec_sa_set_key_t *mp;
12253   u32 sa_id;
12254   u8 *ck = 0, *ik = 0;
12255   int ret;
12256
12257   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12258     {
12259       if (unformat (i, "sa_id %d", &sa_id))
12260         ;
12261       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
12262         ;
12263       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
12264         ;
12265       else
12266         {
12267           clib_warning ("parse error '%U'", format_unformat_error, i);
12268           return -99;
12269         }
12270     }
12271
12272   M (IPSEC_SA_SET_KEY, mp);
12273
12274   mp->sa_id = ntohl (sa_id);
12275   mp->crypto_key_length = vec_len (ck);
12276   mp->integrity_key_length = vec_len (ik);
12277
12278   if (mp->crypto_key_length > sizeof (mp->crypto_key))
12279     mp->crypto_key_length = sizeof (mp->crypto_key);
12280
12281   if (mp->integrity_key_length > sizeof (mp->integrity_key))
12282     mp->integrity_key_length = sizeof (mp->integrity_key);
12283
12284   if (ck)
12285     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
12286   if (ik)
12287     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
12288
12289   S (mp);
12290   W (ret);
12291   return ret;
12292 }
12293
12294 static int
12295 api_ikev2_profile_add_del (vat_main_t * vam)
12296 {
12297   unformat_input_t *i = vam->input;
12298   vl_api_ikev2_profile_add_del_t *mp;
12299   u8 is_add = 1;
12300   u8 *name = 0;
12301   int ret;
12302
12303   const char *valid_chars = "a-zA-Z0-9_";
12304
12305   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12306     {
12307       if (unformat (i, "del"))
12308         is_add = 0;
12309       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12310         vec_add1 (name, 0);
12311       else
12312         {
12313           errmsg ("parse error '%U'", format_unformat_error, i);
12314           return -99;
12315         }
12316     }
12317
12318   if (!vec_len (name))
12319     {
12320       errmsg ("profile name must be specified");
12321       return -99;
12322     }
12323
12324   if (vec_len (name) > 64)
12325     {
12326       errmsg ("profile name too long");
12327       return -99;
12328     }
12329
12330   M (IKEV2_PROFILE_ADD_DEL, mp);
12331
12332   clib_memcpy (mp->name, name, vec_len (name));
12333   mp->is_add = is_add;
12334   vec_free (name);
12335
12336   S (mp);
12337   W (ret);
12338   return ret;
12339 }
12340
12341 static int
12342 api_ikev2_profile_set_auth (vat_main_t * vam)
12343 {
12344   unformat_input_t *i = vam->input;
12345   vl_api_ikev2_profile_set_auth_t *mp;
12346   u8 *name = 0;
12347   u8 *data = 0;
12348   u32 auth_method = 0;
12349   u8 is_hex = 0;
12350   int ret;
12351
12352   const char *valid_chars = "a-zA-Z0-9_";
12353
12354   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12355     {
12356       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12357         vec_add1 (name, 0);
12358       else if (unformat (i, "auth_method %U",
12359                          unformat_ikev2_auth_method, &auth_method))
12360         ;
12361       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
12362         is_hex = 1;
12363       else if (unformat (i, "auth_data %v", &data))
12364         ;
12365       else
12366         {
12367           errmsg ("parse error '%U'", format_unformat_error, i);
12368           return -99;
12369         }
12370     }
12371
12372   if (!vec_len (name))
12373     {
12374       errmsg ("profile name must be specified");
12375       return -99;
12376     }
12377
12378   if (vec_len (name) > 64)
12379     {
12380       errmsg ("profile name too long");
12381       return -99;
12382     }
12383
12384   if (!vec_len (data))
12385     {
12386       errmsg ("auth_data must be specified");
12387       return -99;
12388     }
12389
12390   if (!auth_method)
12391     {
12392       errmsg ("auth_method must be specified");
12393       return -99;
12394     }
12395
12396   M (IKEV2_PROFILE_SET_AUTH, mp);
12397
12398   mp->is_hex = is_hex;
12399   mp->auth_method = (u8) auth_method;
12400   mp->data_len = vec_len (data);
12401   clib_memcpy (mp->name, name, vec_len (name));
12402   clib_memcpy (mp->data, data, vec_len (data));
12403   vec_free (name);
12404   vec_free (data);
12405
12406   S (mp);
12407   W (ret);
12408   return ret;
12409 }
12410
12411 static int
12412 api_ikev2_profile_set_id (vat_main_t * vam)
12413 {
12414   unformat_input_t *i = vam->input;
12415   vl_api_ikev2_profile_set_id_t *mp;
12416   u8 *name = 0;
12417   u8 *data = 0;
12418   u8 is_local = 0;
12419   u32 id_type = 0;
12420   ip4_address_t ip4;
12421   int ret;
12422
12423   const char *valid_chars = "a-zA-Z0-9_";
12424
12425   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12426     {
12427       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12428         vec_add1 (name, 0);
12429       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
12430         ;
12431       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
12432         {
12433           data = vec_new (u8, 4);
12434           clib_memcpy (data, ip4.as_u8, 4);
12435         }
12436       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
12437         ;
12438       else if (unformat (i, "id_data %v", &data))
12439         ;
12440       else if (unformat (i, "local"))
12441         is_local = 1;
12442       else if (unformat (i, "remote"))
12443         is_local = 0;
12444       else
12445         {
12446           errmsg ("parse error '%U'", format_unformat_error, i);
12447           return -99;
12448         }
12449     }
12450
12451   if (!vec_len (name))
12452     {
12453       errmsg ("profile name must be specified");
12454       return -99;
12455     }
12456
12457   if (vec_len (name) > 64)
12458     {
12459       errmsg ("profile name too long");
12460       return -99;
12461     }
12462
12463   if (!vec_len (data))
12464     {
12465       errmsg ("id_data must be specified");
12466       return -99;
12467     }
12468
12469   if (!id_type)
12470     {
12471       errmsg ("id_type must be specified");
12472       return -99;
12473     }
12474
12475   M (IKEV2_PROFILE_SET_ID, mp);
12476
12477   mp->is_local = is_local;
12478   mp->id_type = (u8) id_type;
12479   mp->data_len = vec_len (data);
12480   clib_memcpy (mp->name, name, vec_len (name));
12481   clib_memcpy (mp->data, data, vec_len (data));
12482   vec_free (name);
12483   vec_free (data);
12484
12485   S (mp);
12486   W (ret);
12487   return ret;
12488 }
12489
12490 static int
12491 api_ikev2_profile_set_ts (vat_main_t * vam)
12492 {
12493   unformat_input_t *i = vam->input;
12494   vl_api_ikev2_profile_set_ts_t *mp;
12495   u8 *name = 0;
12496   u8 is_local = 0;
12497   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
12498   ip4_address_t start_addr, end_addr;
12499
12500   const char *valid_chars = "a-zA-Z0-9_";
12501   int ret;
12502
12503   start_addr.as_u32 = 0;
12504   end_addr.as_u32 = (u32) ~ 0;
12505
12506   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12507     {
12508       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12509         vec_add1 (name, 0);
12510       else if (unformat (i, "protocol %d", &proto))
12511         ;
12512       else if (unformat (i, "start_port %d", &start_port))
12513         ;
12514       else if (unformat (i, "end_port %d", &end_port))
12515         ;
12516       else
12517         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
12518         ;
12519       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
12520         ;
12521       else if (unformat (i, "local"))
12522         is_local = 1;
12523       else if (unformat (i, "remote"))
12524         is_local = 0;
12525       else
12526         {
12527           errmsg ("parse error '%U'", format_unformat_error, i);
12528           return -99;
12529         }
12530     }
12531
12532   if (!vec_len (name))
12533     {
12534       errmsg ("profile name must be specified");
12535       return -99;
12536     }
12537
12538   if (vec_len (name) > 64)
12539     {
12540       errmsg ("profile name too long");
12541       return -99;
12542     }
12543
12544   M (IKEV2_PROFILE_SET_TS, mp);
12545
12546   mp->is_local = is_local;
12547   mp->proto = (u8) proto;
12548   mp->start_port = (u16) start_port;
12549   mp->end_port = (u16) end_port;
12550   mp->start_addr = start_addr.as_u32;
12551   mp->end_addr = end_addr.as_u32;
12552   clib_memcpy (mp->name, name, vec_len (name));
12553   vec_free (name);
12554
12555   S (mp);
12556   W (ret);
12557   return ret;
12558 }
12559
12560 static int
12561 api_ikev2_set_local_key (vat_main_t * vam)
12562 {
12563   unformat_input_t *i = vam->input;
12564   vl_api_ikev2_set_local_key_t *mp;
12565   u8 *file = 0;
12566   int ret;
12567
12568   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12569     {
12570       if (unformat (i, "file %v", &file))
12571         vec_add1 (file, 0);
12572       else
12573         {
12574           errmsg ("parse error '%U'", format_unformat_error, i);
12575           return -99;
12576         }
12577     }
12578
12579   if (!vec_len (file))
12580     {
12581       errmsg ("RSA key file must be specified");
12582       return -99;
12583     }
12584
12585   if (vec_len (file) > 256)
12586     {
12587       errmsg ("file name too long");
12588       return -99;
12589     }
12590
12591   M (IKEV2_SET_LOCAL_KEY, mp);
12592
12593   clib_memcpy (mp->key_file, file, vec_len (file));
12594   vec_free (file);
12595
12596   S (mp);
12597   W (ret);
12598   return ret;
12599 }
12600
12601 static int
12602 api_ikev2_set_responder (vat_main_t * vam)
12603 {
12604   unformat_input_t *i = vam->input;
12605   vl_api_ikev2_set_responder_t *mp;
12606   int ret;
12607   u8 *name = 0;
12608   u32 sw_if_index = ~0;
12609   ip4_address_t address;
12610
12611   const char *valid_chars = "a-zA-Z0-9_";
12612
12613   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12614     {
12615       if (unformat
12616           (i, "%U interface %d address %U", unformat_token, valid_chars,
12617            &name, &sw_if_index, unformat_ip4_address, &address))
12618         vec_add1 (name, 0);
12619       else
12620         {
12621           errmsg ("parse error '%U'", format_unformat_error, i);
12622           return -99;
12623         }
12624     }
12625
12626   if (!vec_len (name))
12627     {
12628       errmsg ("profile name must be specified");
12629       return -99;
12630     }
12631
12632   if (vec_len (name) > 64)
12633     {
12634       errmsg ("profile name too long");
12635       return -99;
12636     }
12637
12638   M (IKEV2_SET_RESPONDER, mp);
12639
12640   clib_memcpy (mp->name, name, vec_len (name));
12641   vec_free (name);
12642
12643   mp->sw_if_index = sw_if_index;
12644   clib_memcpy (mp->address, &address, sizeof (address));
12645
12646   S (mp);
12647   W (ret);
12648   return ret;
12649 }
12650
12651 static int
12652 api_ikev2_set_ike_transforms (vat_main_t * vam)
12653 {
12654   unformat_input_t *i = vam->input;
12655   vl_api_ikev2_set_ike_transforms_t *mp;
12656   int ret;
12657   u8 *name = 0;
12658   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
12659
12660   const char *valid_chars = "a-zA-Z0-9_";
12661
12662   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12663     {
12664       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
12665                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
12666         vec_add1 (name, 0);
12667       else
12668         {
12669           errmsg ("parse error '%U'", format_unformat_error, i);
12670           return -99;
12671         }
12672     }
12673
12674   if (!vec_len (name))
12675     {
12676       errmsg ("profile name must be specified");
12677       return -99;
12678     }
12679
12680   if (vec_len (name) > 64)
12681     {
12682       errmsg ("profile name too long");
12683       return -99;
12684     }
12685
12686   M (IKEV2_SET_IKE_TRANSFORMS, mp);
12687
12688   clib_memcpy (mp->name, name, vec_len (name));
12689   vec_free (name);
12690   mp->crypto_alg = crypto_alg;
12691   mp->crypto_key_size = crypto_key_size;
12692   mp->integ_alg = integ_alg;
12693   mp->dh_group = dh_group;
12694
12695   S (mp);
12696   W (ret);
12697   return ret;
12698 }
12699
12700
12701 static int
12702 api_ikev2_set_esp_transforms (vat_main_t * vam)
12703 {
12704   unformat_input_t *i = vam->input;
12705   vl_api_ikev2_set_esp_transforms_t *mp;
12706   int ret;
12707   u8 *name = 0;
12708   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
12709
12710   const char *valid_chars = "a-zA-Z0-9_";
12711
12712   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12713     {
12714       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
12715                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
12716         vec_add1 (name, 0);
12717       else
12718         {
12719           errmsg ("parse error '%U'", format_unformat_error, i);
12720           return -99;
12721         }
12722     }
12723
12724   if (!vec_len (name))
12725     {
12726       errmsg ("profile name must be specified");
12727       return -99;
12728     }
12729
12730   if (vec_len (name) > 64)
12731     {
12732       errmsg ("profile name too long");
12733       return -99;
12734     }
12735
12736   M (IKEV2_SET_ESP_TRANSFORMS, mp);
12737
12738   clib_memcpy (mp->name, name, vec_len (name));
12739   vec_free (name);
12740   mp->crypto_alg = crypto_alg;
12741   mp->crypto_key_size = crypto_key_size;
12742   mp->integ_alg = integ_alg;
12743   mp->dh_group = dh_group;
12744
12745   S (mp);
12746   W (ret);
12747   return ret;
12748 }
12749
12750 static int
12751 api_ikev2_set_sa_lifetime (vat_main_t * vam)
12752 {
12753   unformat_input_t *i = vam->input;
12754   vl_api_ikev2_set_sa_lifetime_t *mp;
12755   int ret;
12756   u8 *name = 0;
12757   u64 lifetime, lifetime_maxdata;
12758   u32 lifetime_jitter, handover;
12759
12760   const char *valid_chars = "a-zA-Z0-9_";
12761
12762   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12763     {
12764       if (unformat (i, "%U %lu %u %u %lu", unformat_token, valid_chars, &name,
12765                     &lifetime, &lifetime_jitter, &handover,
12766                     &lifetime_maxdata))
12767         vec_add1 (name, 0);
12768       else
12769         {
12770           errmsg ("parse error '%U'", format_unformat_error, i);
12771           return -99;
12772         }
12773     }
12774
12775   if (!vec_len (name))
12776     {
12777       errmsg ("profile name must be specified");
12778       return -99;
12779     }
12780
12781   if (vec_len (name) > 64)
12782     {
12783       errmsg ("profile name too long");
12784       return -99;
12785     }
12786
12787   M (IKEV2_SET_SA_LIFETIME, mp);
12788
12789   clib_memcpy (mp->name, name, vec_len (name));
12790   vec_free (name);
12791   mp->lifetime = lifetime;
12792   mp->lifetime_jitter = lifetime_jitter;
12793   mp->handover = handover;
12794   mp->lifetime_maxdata = lifetime_maxdata;
12795
12796   S (mp);
12797   W (ret);
12798   return ret;
12799 }
12800
12801 static int
12802 api_ikev2_initiate_sa_init (vat_main_t * vam)
12803 {
12804   unformat_input_t *i = vam->input;
12805   vl_api_ikev2_initiate_sa_init_t *mp;
12806   int ret;
12807   u8 *name = 0;
12808
12809   const char *valid_chars = "a-zA-Z0-9_";
12810
12811   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12812     {
12813       if (unformat (i, "%U", unformat_token, valid_chars, &name))
12814         vec_add1 (name, 0);
12815       else
12816         {
12817           errmsg ("parse error '%U'", format_unformat_error, i);
12818           return -99;
12819         }
12820     }
12821
12822   if (!vec_len (name))
12823     {
12824       errmsg ("profile name must be specified");
12825       return -99;
12826     }
12827
12828   if (vec_len (name) > 64)
12829     {
12830       errmsg ("profile name too long");
12831       return -99;
12832     }
12833
12834   M (IKEV2_INITIATE_SA_INIT, mp);
12835
12836   clib_memcpy (mp->name, name, vec_len (name));
12837   vec_free (name);
12838
12839   S (mp);
12840   W (ret);
12841   return ret;
12842 }
12843
12844 static int
12845 api_ikev2_initiate_del_ike_sa (vat_main_t * vam)
12846 {
12847   unformat_input_t *i = vam->input;
12848   vl_api_ikev2_initiate_del_ike_sa_t *mp;
12849   int ret;
12850   u64 ispi;
12851
12852
12853   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12854     {
12855       if (unformat (i, "%lx", &ispi))
12856         ;
12857       else
12858         {
12859           errmsg ("parse error '%U'", format_unformat_error, i);
12860           return -99;
12861         }
12862     }
12863
12864   M (IKEV2_INITIATE_DEL_IKE_SA, mp);
12865
12866   mp->ispi = ispi;
12867
12868   S (mp);
12869   W (ret);
12870   return ret;
12871 }
12872
12873 static int
12874 api_ikev2_initiate_del_child_sa (vat_main_t * vam)
12875 {
12876   unformat_input_t *i = vam->input;
12877   vl_api_ikev2_initiate_del_child_sa_t *mp;
12878   int ret;
12879   u32 ispi;
12880
12881
12882   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12883     {
12884       if (unformat (i, "%x", &ispi))
12885         ;
12886       else
12887         {
12888           errmsg ("parse error '%U'", format_unformat_error, i);
12889           return -99;
12890         }
12891     }
12892
12893   M (IKEV2_INITIATE_DEL_CHILD_SA, mp);
12894
12895   mp->ispi = ispi;
12896
12897   S (mp);
12898   W (ret);
12899   return ret;
12900 }
12901
12902 static int
12903 api_ikev2_initiate_rekey_child_sa (vat_main_t * vam)
12904 {
12905   unformat_input_t *i = vam->input;
12906   vl_api_ikev2_initiate_rekey_child_sa_t *mp;
12907   int ret;
12908   u32 ispi;
12909
12910
12911   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12912     {
12913       if (unformat (i, "%x", &ispi))
12914         ;
12915       else
12916         {
12917           errmsg ("parse error '%U'", format_unformat_error, i);
12918           return -99;
12919         }
12920     }
12921
12922   M (IKEV2_INITIATE_REKEY_CHILD_SA, mp);
12923
12924   mp->ispi = ispi;
12925
12926   S (mp);
12927   W (ret);
12928   return ret;
12929 }
12930
12931 /*
12932  * MAP
12933  */
12934 static int
12935 api_map_add_domain (vat_main_t * vam)
12936 {
12937   unformat_input_t *i = vam->input;
12938   vl_api_map_add_domain_t *mp;
12939
12940   ip4_address_t ip4_prefix;
12941   ip6_address_t ip6_prefix;
12942   ip6_address_t ip6_src;
12943   u32 num_m_args = 0;
12944   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
12945     0, psid_length = 0;
12946   u8 is_translation = 0;
12947   u32 mtu = 0;
12948   u32 ip6_src_len = 128;
12949   int ret;
12950
12951   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12952     {
12953       if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
12954                     &ip4_prefix, &ip4_prefix_len))
12955         num_m_args++;
12956       else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
12957                          &ip6_prefix, &ip6_prefix_len))
12958         num_m_args++;
12959       else
12960         if (unformat
12961             (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
12962              &ip6_src_len))
12963         num_m_args++;
12964       else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
12965         num_m_args++;
12966       else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
12967         num_m_args++;
12968       else if (unformat (i, "psid-offset %d", &psid_offset))
12969         num_m_args++;
12970       else if (unformat (i, "psid-len %d", &psid_length))
12971         num_m_args++;
12972       else if (unformat (i, "mtu %d", &mtu))
12973         num_m_args++;
12974       else if (unformat (i, "map-t"))
12975         is_translation = 1;
12976       else
12977         {
12978           clib_warning ("parse error '%U'", format_unformat_error, i);
12979           return -99;
12980         }
12981     }
12982
12983   if (num_m_args < 3)
12984     {
12985       errmsg ("mandatory argument(s) missing");
12986       return -99;
12987     }
12988
12989   /* Construct the API message */
12990   M (MAP_ADD_DOMAIN, mp);
12991
12992   clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
12993   mp->ip4_prefix_len = ip4_prefix_len;
12994
12995   clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
12996   mp->ip6_prefix_len = ip6_prefix_len;
12997
12998   clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
12999   mp->ip6_src_prefix_len = ip6_src_len;
13000
13001   mp->ea_bits_len = ea_bits_len;
13002   mp->psid_offset = psid_offset;
13003   mp->psid_length = psid_length;
13004   mp->is_translation = is_translation;
13005   mp->mtu = htons (mtu);
13006
13007   /* send it... */
13008   S (mp);
13009
13010   /* Wait for a reply, return good/bad news  */
13011   W (ret);
13012   return ret;
13013 }
13014
13015 static int
13016 api_map_del_domain (vat_main_t * vam)
13017 {
13018   unformat_input_t *i = vam->input;
13019   vl_api_map_del_domain_t *mp;
13020
13021   u32 num_m_args = 0;
13022   u32 index;
13023   int ret;
13024
13025   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13026     {
13027       if (unformat (i, "index %d", &index))
13028         num_m_args++;
13029       else
13030         {
13031           clib_warning ("parse error '%U'", format_unformat_error, i);
13032           return -99;
13033         }
13034     }
13035
13036   if (num_m_args != 1)
13037     {
13038       errmsg ("mandatory argument(s) missing");
13039       return -99;
13040     }
13041
13042   /* Construct the API message */
13043   M (MAP_DEL_DOMAIN, mp);
13044
13045   mp->index = ntohl (index);
13046
13047   /* send it... */
13048   S (mp);
13049
13050   /* Wait for a reply, return good/bad news  */
13051   W (ret);
13052   return ret;
13053 }
13054
13055 static int
13056 api_map_add_del_rule (vat_main_t * vam)
13057 {
13058   unformat_input_t *i = vam->input;
13059   vl_api_map_add_del_rule_t *mp;
13060   u8 is_add = 1;
13061   ip6_address_t ip6_dst;
13062   u32 num_m_args = 0, index, psid = 0;
13063   int ret;
13064
13065   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13066     {
13067       if (unformat (i, "index %d", &index))
13068         num_m_args++;
13069       else if (unformat (i, "psid %d", &psid))
13070         num_m_args++;
13071       else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
13072         num_m_args++;
13073       else if (unformat (i, "del"))
13074         {
13075           is_add = 0;
13076         }
13077       else
13078         {
13079           clib_warning ("parse error '%U'", format_unformat_error, i);
13080           return -99;
13081         }
13082     }
13083
13084   /* Construct the API message */
13085   M (MAP_ADD_DEL_RULE, mp);
13086
13087   mp->index = ntohl (index);
13088   mp->is_add = is_add;
13089   clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
13090   mp->psid = ntohs (psid);
13091
13092   /* send it... */
13093   S (mp);
13094
13095   /* Wait for a reply, return good/bad news  */
13096   W (ret);
13097   return ret;
13098 }
13099
13100 static int
13101 api_map_domain_dump (vat_main_t * vam)
13102 {
13103   vl_api_map_domain_dump_t *mp;
13104   vl_api_control_ping_t *mp_ping;
13105   int ret;
13106
13107   /* Construct the API message */
13108   M (MAP_DOMAIN_DUMP, mp);
13109
13110   /* send it... */
13111   S (mp);
13112
13113   /* Use a control ping for synchronization */
13114   M (CONTROL_PING, mp_ping);
13115   S (mp_ping);
13116
13117   W (ret);
13118   return ret;
13119 }
13120
13121 static int
13122 api_map_rule_dump (vat_main_t * vam)
13123 {
13124   unformat_input_t *i = vam->input;
13125   vl_api_map_rule_dump_t *mp;
13126   vl_api_control_ping_t *mp_ping;
13127   u32 domain_index = ~0;
13128   int ret;
13129
13130   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13131     {
13132       if (unformat (i, "index %u", &domain_index))
13133         ;
13134       else
13135         break;
13136     }
13137
13138   if (domain_index == ~0)
13139     {
13140       clib_warning ("parse error: domain index expected");
13141       return -99;
13142     }
13143
13144   /* Construct the API message */
13145   M (MAP_RULE_DUMP, mp);
13146
13147   mp->domain_index = htonl (domain_index);
13148
13149   /* send it... */
13150   S (mp);
13151
13152   /* Use a control ping for synchronization */
13153   M (CONTROL_PING, mp_ping);
13154   S (mp_ping);
13155
13156   W (ret);
13157   return ret;
13158 }
13159
13160 static void vl_api_map_add_domain_reply_t_handler
13161   (vl_api_map_add_domain_reply_t * mp)
13162 {
13163   vat_main_t *vam = &vat_main;
13164   i32 retval = ntohl (mp->retval);
13165
13166   if (vam->async_mode)
13167     {
13168       vam->async_errors += (retval < 0);
13169     }
13170   else
13171     {
13172       vam->retval = retval;
13173       vam->result_ready = 1;
13174     }
13175 }
13176
13177 static void vl_api_map_add_domain_reply_t_handler_json
13178   (vl_api_map_add_domain_reply_t * mp)
13179 {
13180   vat_main_t *vam = &vat_main;
13181   vat_json_node_t node;
13182
13183   vat_json_init_object (&node);
13184   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
13185   vat_json_object_add_uint (&node, "index", ntohl (mp->index));
13186
13187   vat_json_print (vam->ofp, &node);
13188   vat_json_free (&node);
13189
13190   vam->retval = ntohl (mp->retval);
13191   vam->result_ready = 1;
13192 }
13193
13194 static int
13195 api_get_first_msg_id (vat_main_t * vam)
13196 {
13197   vl_api_get_first_msg_id_t *mp;
13198   unformat_input_t *i = vam->input;
13199   u8 *name;
13200   u8 name_set = 0;
13201   int ret;
13202
13203   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13204     {
13205       if (unformat (i, "client %s", &name))
13206         name_set = 1;
13207       else
13208         break;
13209     }
13210
13211   if (name_set == 0)
13212     {
13213       errmsg ("missing client name");
13214       return -99;
13215     }
13216   vec_add1 (name, 0);
13217
13218   if (vec_len (name) > 63)
13219     {
13220       errmsg ("client name too long");
13221       return -99;
13222     }
13223
13224   M (GET_FIRST_MSG_ID, mp);
13225   clib_memcpy (mp->name, name, vec_len (name));
13226   S (mp);
13227   W (ret);
13228   return ret;
13229 }
13230
13231 static int
13232 api_cop_interface_enable_disable (vat_main_t * vam)
13233 {
13234   unformat_input_t *line_input = vam->input;
13235   vl_api_cop_interface_enable_disable_t *mp;
13236   u32 sw_if_index = ~0;
13237   u8 enable_disable = 1;
13238   int ret;
13239
13240   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13241     {
13242       if (unformat (line_input, "disable"))
13243         enable_disable = 0;
13244       if (unformat (line_input, "enable"))
13245         enable_disable = 1;
13246       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
13247                          vam, &sw_if_index))
13248         ;
13249       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13250         ;
13251       else
13252         break;
13253     }
13254
13255   if (sw_if_index == ~0)
13256     {
13257       errmsg ("missing interface name or sw_if_index");
13258       return -99;
13259     }
13260
13261   /* Construct the API message */
13262   M (COP_INTERFACE_ENABLE_DISABLE, mp);
13263   mp->sw_if_index = ntohl (sw_if_index);
13264   mp->enable_disable = enable_disable;
13265
13266   /* send it... */
13267   S (mp);
13268   /* Wait for the reply */
13269   W (ret);
13270   return ret;
13271 }
13272
13273 static int
13274 api_cop_whitelist_enable_disable (vat_main_t * vam)
13275 {
13276   unformat_input_t *line_input = vam->input;
13277   vl_api_cop_whitelist_enable_disable_t *mp;
13278   u32 sw_if_index = ~0;
13279   u8 ip4 = 0, ip6 = 0, default_cop = 0;
13280   u32 fib_id = 0;
13281   int ret;
13282
13283   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13284     {
13285       if (unformat (line_input, "ip4"))
13286         ip4 = 1;
13287       else if (unformat (line_input, "ip6"))
13288         ip6 = 1;
13289       else if (unformat (line_input, "default"))
13290         default_cop = 1;
13291       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
13292                          vam, &sw_if_index))
13293         ;
13294       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13295         ;
13296       else if (unformat (line_input, "fib-id %d", &fib_id))
13297         ;
13298       else
13299         break;
13300     }
13301
13302   if (sw_if_index == ~0)
13303     {
13304       errmsg ("missing interface name or sw_if_index");
13305       return -99;
13306     }
13307
13308   /* Construct the API message */
13309   M (COP_WHITELIST_ENABLE_DISABLE, mp);
13310   mp->sw_if_index = ntohl (sw_if_index);
13311   mp->fib_id = ntohl (fib_id);
13312   mp->ip4 = ip4;
13313   mp->ip6 = ip6;
13314   mp->default_cop = default_cop;
13315
13316   /* send it... */
13317   S (mp);
13318   /* Wait for the reply */
13319   W (ret);
13320   return ret;
13321 }
13322
13323 static int
13324 api_get_node_graph (vat_main_t * vam)
13325 {
13326   vl_api_get_node_graph_t *mp;
13327   int ret;
13328
13329   M (GET_NODE_GRAPH, mp);
13330
13331   /* send it... */
13332   S (mp);
13333   /* Wait for the reply */
13334   W (ret);
13335   return ret;
13336 }
13337
13338 /* *INDENT-OFF* */
13339 /** Used for parsing LISP eids */
13340 typedef CLIB_PACKED(struct{
13341   u8 addr[16];   /**< eid address */
13342   u32 len;       /**< prefix length if IP */
13343   u8 type;      /**< type of eid */
13344 }) lisp_eid_vat_t;
13345 /* *INDENT-ON* */
13346
13347 static uword
13348 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
13349 {
13350   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
13351
13352   memset (a, 0, sizeof (a[0]));
13353
13354   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
13355     {
13356       a->type = 0;              /* ipv4 type */
13357     }
13358   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
13359     {
13360       a->type = 1;              /* ipv6 type */
13361     }
13362   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
13363     {
13364       a->type = 2;              /* mac type */
13365     }
13366   else
13367     {
13368       return 0;
13369     }
13370
13371   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
13372     {
13373       return 0;
13374     }
13375
13376   return 1;
13377 }
13378
13379 static int
13380 lisp_eid_size_vat (u8 type)
13381 {
13382   switch (type)
13383     {
13384     case 0:
13385       return 4;
13386     case 1:
13387       return 16;
13388     case 2:
13389       return 6;
13390     }
13391   return 0;
13392 }
13393
13394 static void
13395 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
13396 {
13397   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
13398 }
13399
13400 static int
13401 api_one_add_del_locator_set (vat_main_t * vam)
13402 {
13403   unformat_input_t *input = vam->input;
13404   vl_api_one_add_del_locator_set_t *mp;
13405   u8 is_add = 1;
13406   u8 *locator_set_name = NULL;
13407   u8 locator_set_name_set = 0;
13408   vl_api_local_locator_t locator, *locators = 0;
13409   u32 sw_if_index, priority, weight;
13410   u32 data_len = 0;
13411
13412   int ret;
13413   /* Parse args required to build the message */
13414   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13415     {
13416       if (unformat (input, "del"))
13417         {
13418           is_add = 0;
13419         }
13420       else if (unformat (input, "locator-set %s", &locator_set_name))
13421         {
13422           locator_set_name_set = 1;
13423         }
13424       else if (unformat (input, "sw_if_index %u p %u w %u",
13425                          &sw_if_index, &priority, &weight))
13426         {
13427           locator.sw_if_index = htonl (sw_if_index);
13428           locator.priority = priority;
13429           locator.weight = weight;
13430           vec_add1 (locators, locator);
13431         }
13432       else
13433         if (unformat
13434             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
13435              &sw_if_index, &priority, &weight))
13436         {
13437           locator.sw_if_index = htonl (sw_if_index);
13438           locator.priority = priority;
13439           locator.weight = weight;
13440           vec_add1 (locators, locator);
13441         }
13442       else
13443         break;
13444     }
13445
13446   if (locator_set_name_set == 0)
13447     {
13448       errmsg ("missing locator-set name");
13449       vec_free (locators);
13450       return -99;
13451     }
13452
13453   if (vec_len (locator_set_name) > 64)
13454     {
13455       errmsg ("locator-set name too long");
13456       vec_free (locator_set_name);
13457       vec_free (locators);
13458       return -99;
13459     }
13460   vec_add1 (locator_set_name, 0);
13461
13462   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
13463
13464   /* Construct the API message */
13465   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
13466
13467   mp->is_add = is_add;
13468   clib_memcpy (mp->locator_set_name, locator_set_name,
13469                vec_len (locator_set_name));
13470   vec_free (locator_set_name);
13471
13472   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
13473   if (locators)
13474     clib_memcpy (mp->locators, locators, data_len);
13475   vec_free (locators);
13476
13477   /* send it... */
13478   S (mp);
13479
13480   /* Wait for a reply... */
13481   W (ret);
13482   return ret;
13483 }
13484
13485 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
13486
13487 static int
13488 api_one_add_del_locator (vat_main_t * vam)
13489 {
13490   unformat_input_t *input = vam->input;
13491   vl_api_one_add_del_locator_t *mp;
13492   u32 tmp_if_index = ~0;
13493   u32 sw_if_index = ~0;
13494   u8 sw_if_index_set = 0;
13495   u8 sw_if_index_if_name_set = 0;
13496   u32 priority = ~0;
13497   u8 priority_set = 0;
13498   u32 weight = ~0;
13499   u8 weight_set = 0;
13500   u8 is_add = 1;
13501   u8 *locator_set_name = NULL;
13502   u8 locator_set_name_set = 0;
13503   int ret;
13504
13505   /* Parse args required to build the message */
13506   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13507     {
13508       if (unformat (input, "del"))
13509         {
13510           is_add = 0;
13511         }
13512       else if (unformat (input, "locator-set %s", &locator_set_name))
13513         {
13514           locator_set_name_set = 1;
13515         }
13516       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
13517                          &tmp_if_index))
13518         {
13519           sw_if_index_if_name_set = 1;
13520           sw_if_index = tmp_if_index;
13521         }
13522       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
13523         {
13524           sw_if_index_set = 1;
13525           sw_if_index = tmp_if_index;
13526         }
13527       else if (unformat (input, "p %d", &priority))
13528         {
13529           priority_set = 1;
13530         }
13531       else if (unformat (input, "w %d", &weight))
13532         {
13533           weight_set = 1;
13534         }
13535       else
13536         break;
13537     }
13538
13539   if (locator_set_name_set == 0)
13540     {
13541       errmsg ("missing locator-set name");
13542       return -99;
13543     }
13544
13545   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
13546     {
13547       errmsg ("missing sw_if_index");
13548       vec_free (locator_set_name);
13549       return -99;
13550     }
13551
13552   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
13553     {
13554       errmsg ("cannot use both params interface name and sw_if_index");
13555       vec_free (locator_set_name);
13556       return -99;
13557     }
13558
13559   if (priority_set == 0)
13560     {
13561       errmsg ("missing locator-set priority");
13562       vec_free (locator_set_name);
13563       return -99;
13564     }
13565
13566   if (weight_set == 0)
13567     {
13568       errmsg ("missing locator-set weight");
13569       vec_free (locator_set_name);
13570       return -99;
13571     }
13572
13573   if (vec_len (locator_set_name) > 64)
13574     {
13575       errmsg ("locator-set name too long");
13576       vec_free (locator_set_name);
13577       return -99;
13578     }
13579   vec_add1 (locator_set_name, 0);
13580
13581   /* Construct the API message */
13582   M (ONE_ADD_DEL_LOCATOR, mp);
13583
13584   mp->is_add = is_add;
13585   mp->sw_if_index = ntohl (sw_if_index);
13586   mp->priority = priority;
13587   mp->weight = weight;
13588   clib_memcpy (mp->locator_set_name, locator_set_name,
13589                vec_len (locator_set_name));
13590   vec_free (locator_set_name);
13591
13592   /* send it... */
13593   S (mp);
13594
13595   /* Wait for a reply... */
13596   W (ret);
13597   return ret;
13598 }
13599
13600 #define api_lisp_add_del_locator api_one_add_del_locator
13601
13602 uword
13603 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
13604 {
13605   u32 *key_id = va_arg (*args, u32 *);
13606   u8 *s = 0;
13607
13608   if (unformat (input, "%s", &s))
13609     {
13610       if (!strcmp ((char *) s, "sha1"))
13611         key_id[0] = HMAC_SHA_1_96;
13612       else if (!strcmp ((char *) s, "sha256"))
13613         key_id[0] = HMAC_SHA_256_128;
13614       else
13615         {
13616           clib_warning ("invalid key_id: '%s'", s);
13617           key_id[0] = HMAC_NO_KEY;
13618         }
13619     }
13620   else
13621     return 0;
13622
13623   vec_free (s);
13624   return 1;
13625 }
13626
13627 static int
13628 api_one_add_del_local_eid (vat_main_t * vam)
13629 {
13630   unformat_input_t *input = vam->input;
13631   vl_api_one_add_del_local_eid_t *mp;
13632   u8 is_add = 1;
13633   u8 eid_set = 0;
13634   lisp_eid_vat_t _eid, *eid = &_eid;
13635   u8 *locator_set_name = 0;
13636   u8 locator_set_name_set = 0;
13637   u32 vni = 0;
13638   u16 key_id = 0;
13639   u8 *key = 0;
13640   int ret;
13641
13642   /* Parse args required to build the message */
13643   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13644     {
13645       if (unformat (input, "del"))
13646         {
13647           is_add = 0;
13648         }
13649       else if (unformat (input, "vni %d", &vni))
13650         {
13651           ;
13652         }
13653       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
13654         {
13655           eid_set = 1;
13656         }
13657       else if (unformat (input, "locator-set %s", &locator_set_name))
13658         {
13659           locator_set_name_set = 1;
13660         }
13661       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
13662         ;
13663       else if (unformat (input, "secret-key %_%v%_", &key))
13664         ;
13665       else
13666         break;
13667     }
13668
13669   if (locator_set_name_set == 0)
13670     {
13671       errmsg ("missing locator-set name");
13672       return -99;
13673     }
13674
13675   if (0 == eid_set)
13676     {
13677       errmsg ("EID address not set!");
13678       vec_free (locator_set_name);
13679       return -99;
13680     }
13681
13682   if (key && (0 == key_id))
13683     {
13684       errmsg ("invalid key_id!");
13685       return -99;
13686     }
13687
13688   if (vec_len (key) > 64)
13689     {
13690       errmsg ("key too long");
13691       vec_free (key);
13692       return -99;
13693     }
13694
13695   if (vec_len (locator_set_name) > 64)
13696     {
13697       errmsg ("locator-set name too long");
13698       vec_free (locator_set_name);
13699       return -99;
13700     }
13701   vec_add1 (locator_set_name, 0);
13702
13703   /* Construct the API message */
13704   M (ONE_ADD_DEL_LOCAL_EID, mp);
13705
13706   mp->is_add = is_add;
13707   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
13708   mp->eid_type = eid->type;
13709   mp->prefix_len = eid->len;
13710   mp->vni = clib_host_to_net_u32 (vni);
13711   mp->key_id = clib_host_to_net_u16 (key_id);
13712   clib_memcpy (mp->locator_set_name, locator_set_name,
13713                vec_len (locator_set_name));
13714   clib_memcpy (mp->key, key, vec_len (key));
13715
13716   vec_free (locator_set_name);
13717   vec_free (key);
13718
13719   /* send it... */
13720   S (mp);
13721
13722   /* Wait for a reply... */
13723   W (ret);
13724   return ret;
13725 }
13726
13727 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
13728
13729 static int
13730 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
13731 {
13732   u32 dp_table = 0, vni = 0;;
13733   unformat_input_t *input = vam->input;
13734   vl_api_gpe_add_del_fwd_entry_t *mp;
13735   u8 is_add = 1;
13736   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
13737   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
13738   u8 rmt_eid_set = 0, lcl_eid_set = 0;
13739   u32 action = ~0, w;
13740   ip4_address_t rmt_rloc4, lcl_rloc4;
13741   ip6_address_t rmt_rloc6, lcl_rloc6;
13742   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
13743   int ret;
13744
13745   memset (&rloc, 0, sizeof (rloc));
13746
13747   /* Parse args required to build the message */
13748   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13749     {
13750       if (unformat (input, "del"))
13751         is_add = 0;
13752       else if (unformat (input, "add"))
13753         is_add = 1;
13754       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
13755         {
13756           rmt_eid_set = 1;
13757         }
13758       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
13759         {
13760           lcl_eid_set = 1;
13761         }
13762       else if (unformat (input, "vrf %d", &dp_table))
13763         ;
13764       else if (unformat (input, "bd %d", &dp_table))
13765         ;
13766       else if (unformat (input, "vni %d", &vni))
13767         ;
13768       else if (unformat (input, "w %d", &w))
13769         {
13770           if (!curr_rloc)
13771             {
13772               errmsg ("No RLOC configured for setting priority/weight!");
13773               return -99;
13774             }
13775           curr_rloc->weight = w;
13776         }
13777       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
13778                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
13779         {
13780           rloc.is_ip4 = 1;
13781
13782           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
13783           rloc.weight = 0;
13784           vec_add1 (lcl_locs, rloc);
13785
13786           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
13787           vec_add1 (rmt_locs, rloc);
13788           /* weight saved in rmt loc */
13789           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
13790         }
13791       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
13792                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
13793         {
13794           rloc.is_ip4 = 0;
13795           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
13796           rloc.weight = 0;
13797           vec_add1 (lcl_locs, rloc);
13798
13799           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
13800           vec_add1 (rmt_locs, rloc);
13801           /* weight saved in rmt loc */
13802           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
13803         }
13804       else if (unformat (input, "action %d", &action))
13805         {
13806           ;
13807         }
13808       else
13809         {
13810           clib_warning ("parse error '%U'", format_unformat_error, input);
13811           return -99;
13812         }
13813     }
13814
13815   if (!rmt_eid_set)
13816     {
13817       errmsg ("remote eid addresses not set");
13818       return -99;
13819     }
13820
13821   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
13822     {
13823       errmsg ("eid types don't match");
13824       return -99;
13825     }
13826
13827   if (0 == rmt_locs && (u32) ~ 0 == action)
13828     {
13829       errmsg ("action not set for negative mapping");
13830       return -99;
13831     }
13832
13833   /* Construct the API message */
13834   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
13835       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
13836
13837   mp->is_add = is_add;
13838   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
13839   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
13840   mp->eid_type = rmt_eid->type;
13841   mp->dp_table = clib_host_to_net_u32 (dp_table);
13842   mp->vni = clib_host_to_net_u32 (vni);
13843   mp->rmt_len = rmt_eid->len;
13844   mp->lcl_len = lcl_eid->len;
13845   mp->action = action;
13846
13847   if (0 != rmt_locs && 0 != lcl_locs)
13848     {
13849       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
13850       clib_memcpy (mp->locs, lcl_locs,
13851                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
13852
13853       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
13854       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
13855                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
13856     }
13857   vec_free (lcl_locs);
13858   vec_free (rmt_locs);
13859
13860   /* send it... */
13861   S (mp);
13862
13863   /* Wait for a reply... */
13864   W (ret);
13865   return ret;
13866 }
13867
13868 static int
13869 api_one_add_del_map_server (vat_main_t * vam)
13870 {
13871   unformat_input_t *input = vam->input;
13872   vl_api_one_add_del_map_server_t *mp;
13873   u8 is_add = 1;
13874   u8 ipv4_set = 0;
13875   u8 ipv6_set = 0;
13876   ip4_address_t ipv4;
13877   ip6_address_t ipv6;
13878   int ret;
13879
13880   /* Parse args required to build the message */
13881   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13882     {
13883       if (unformat (input, "del"))
13884         {
13885           is_add = 0;
13886         }
13887       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
13888         {
13889           ipv4_set = 1;
13890         }
13891       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
13892         {
13893           ipv6_set = 1;
13894         }
13895       else
13896         break;
13897     }
13898
13899   if (ipv4_set && ipv6_set)
13900     {
13901       errmsg ("both eid v4 and v6 addresses set");
13902       return -99;
13903     }
13904
13905   if (!ipv4_set && !ipv6_set)
13906     {
13907       errmsg ("eid addresses not set");
13908       return -99;
13909     }
13910
13911   /* Construct the API message */
13912   M (ONE_ADD_DEL_MAP_SERVER, mp);
13913
13914   mp->is_add = is_add;
13915   if (ipv6_set)
13916     {
13917       mp->is_ipv6 = 1;
13918       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
13919     }
13920   else
13921     {
13922       mp->is_ipv6 = 0;
13923       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
13924     }
13925
13926   /* send it... */
13927   S (mp);
13928
13929   /* Wait for a reply... */
13930   W (ret);
13931   return ret;
13932 }
13933
13934 #define api_lisp_add_del_map_server api_one_add_del_map_server
13935
13936 static int
13937 api_one_add_del_map_resolver (vat_main_t * vam)
13938 {
13939   unformat_input_t *input = vam->input;
13940   vl_api_one_add_del_map_resolver_t *mp;
13941   u8 is_add = 1;
13942   u8 ipv4_set = 0;
13943   u8 ipv6_set = 0;
13944   ip4_address_t ipv4;
13945   ip6_address_t ipv6;
13946   int ret;
13947
13948   /* Parse args required to build the message */
13949   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13950     {
13951       if (unformat (input, "del"))
13952         {
13953           is_add = 0;
13954         }
13955       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
13956         {
13957           ipv4_set = 1;
13958         }
13959       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
13960         {
13961           ipv6_set = 1;
13962         }
13963       else
13964         break;
13965     }
13966
13967   if (ipv4_set && ipv6_set)
13968     {
13969       errmsg ("both eid v4 and v6 addresses set");
13970       return -99;
13971     }
13972
13973   if (!ipv4_set && !ipv6_set)
13974     {
13975       errmsg ("eid addresses not set");
13976       return -99;
13977     }
13978
13979   /* Construct the API message */
13980   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
13981
13982   mp->is_add = is_add;
13983   if (ipv6_set)
13984     {
13985       mp->is_ipv6 = 1;
13986       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
13987     }
13988   else
13989     {
13990       mp->is_ipv6 = 0;
13991       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
13992     }
13993
13994   /* send it... */
13995   S (mp);
13996
13997   /* Wait for a reply... */
13998   W (ret);
13999   return ret;
14000 }
14001
14002 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
14003
14004 static int
14005 api_lisp_gpe_enable_disable (vat_main_t * vam)
14006 {
14007   unformat_input_t *input = vam->input;
14008   vl_api_gpe_enable_disable_t *mp;
14009   u8 is_set = 0;
14010   u8 is_en = 1;
14011   int ret;
14012
14013   /* Parse args required to build the message */
14014   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14015     {
14016       if (unformat (input, "enable"))
14017         {
14018           is_set = 1;
14019           is_en = 1;
14020         }
14021       else if (unformat (input, "disable"))
14022         {
14023           is_set = 1;
14024           is_en = 0;
14025         }
14026       else
14027         break;
14028     }
14029
14030   if (is_set == 0)
14031     {
14032       errmsg ("Value not set");
14033       return -99;
14034     }
14035
14036   /* Construct the API message */
14037   M (GPE_ENABLE_DISABLE, mp);
14038
14039   mp->is_en = is_en;
14040
14041   /* send it... */
14042   S (mp);
14043
14044   /* Wait for a reply... */
14045   W (ret);
14046   return ret;
14047 }
14048
14049 static int
14050 api_one_rloc_probe_enable_disable (vat_main_t * vam)
14051 {
14052   unformat_input_t *input = vam->input;
14053   vl_api_one_rloc_probe_enable_disable_t *mp;
14054   u8 is_set = 0;
14055   u8 is_en = 0;
14056   int ret;
14057
14058   /* Parse args required to build the message */
14059   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14060     {
14061       if (unformat (input, "enable"))
14062         {
14063           is_set = 1;
14064           is_en = 1;
14065         }
14066       else if (unformat (input, "disable"))
14067         is_set = 1;
14068       else
14069         break;
14070     }
14071
14072   if (!is_set)
14073     {
14074       errmsg ("Value not set");
14075       return -99;
14076     }
14077
14078   /* Construct the API message */
14079   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
14080
14081   mp->is_enabled = is_en;
14082
14083   /* send it... */
14084   S (mp);
14085
14086   /* Wait for a reply... */
14087   W (ret);
14088   return ret;
14089 }
14090
14091 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
14092
14093 static int
14094 api_one_map_register_enable_disable (vat_main_t * vam)
14095 {
14096   unformat_input_t *input = vam->input;
14097   vl_api_one_map_register_enable_disable_t *mp;
14098   u8 is_set = 0;
14099   u8 is_en = 0;
14100   int ret;
14101
14102   /* Parse args required to build the message */
14103   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14104     {
14105       if (unformat (input, "enable"))
14106         {
14107           is_set = 1;
14108           is_en = 1;
14109         }
14110       else if (unformat (input, "disable"))
14111         is_set = 1;
14112       else
14113         break;
14114     }
14115
14116   if (!is_set)
14117     {
14118       errmsg ("Value not set");
14119       return -99;
14120     }
14121
14122   /* Construct the API message */
14123   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
14124
14125   mp->is_enabled = is_en;
14126
14127   /* send it... */
14128   S (mp);
14129
14130   /* Wait for a reply... */
14131   W (ret);
14132   return ret;
14133 }
14134
14135 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
14136
14137 static int
14138 api_one_enable_disable (vat_main_t * vam)
14139 {
14140   unformat_input_t *input = vam->input;
14141   vl_api_one_enable_disable_t *mp;
14142   u8 is_set = 0;
14143   u8 is_en = 0;
14144   int ret;
14145
14146   /* Parse args required to build the message */
14147   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14148     {
14149       if (unformat (input, "enable"))
14150         {
14151           is_set = 1;
14152           is_en = 1;
14153         }
14154       else if (unformat (input, "disable"))
14155         {
14156           is_set = 1;
14157         }
14158       else
14159         break;
14160     }
14161
14162   if (!is_set)
14163     {
14164       errmsg ("Value not set");
14165       return -99;
14166     }
14167
14168   /* Construct the API message */
14169   M (ONE_ENABLE_DISABLE, mp);
14170
14171   mp->is_en = is_en;
14172
14173   /* send it... */
14174   S (mp);
14175
14176   /* Wait for a reply... */
14177   W (ret);
14178   return ret;
14179 }
14180
14181 #define api_lisp_enable_disable api_one_enable_disable
14182
14183 static int
14184 api_show_one_map_register_state (vat_main_t * vam)
14185 {
14186   vl_api_show_one_map_register_state_t *mp;
14187   int ret;
14188
14189   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
14190
14191   /* send */
14192   S (mp);
14193
14194   /* wait for reply */
14195   W (ret);
14196   return ret;
14197 }
14198
14199 #define api_show_lisp_map_register_state api_show_one_map_register_state
14200
14201 static int
14202 api_show_one_rloc_probe_state (vat_main_t * vam)
14203 {
14204   vl_api_show_one_rloc_probe_state_t *mp;
14205   int ret;
14206
14207   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
14208
14209   /* send */
14210   S (mp);
14211
14212   /* wait for reply */
14213   W (ret);
14214   return ret;
14215 }
14216
14217 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
14218
14219 static int
14220 api_show_one_map_request_mode (vat_main_t * vam)
14221 {
14222   vl_api_show_one_map_request_mode_t *mp;
14223   int ret;
14224
14225   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
14226
14227   /* send */
14228   S (mp);
14229
14230   /* wait for reply */
14231   W (ret);
14232   return ret;
14233 }
14234
14235 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
14236
14237 static int
14238 api_one_map_request_mode (vat_main_t * vam)
14239 {
14240   unformat_input_t *input = vam->input;
14241   vl_api_one_map_request_mode_t *mp;
14242   u8 mode = 0;
14243   int ret;
14244
14245   /* Parse args required to build the message */
14246   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14247     {
14248       if (unformat (input, "dst-only"))
14249         mode = 0;
14250       else if (unformat (input, "src-dst"))
14251         mode = 1;
14252       else
14253         {
14254           errmsg ("parse error '%U'", format_unformat_error, input);
14255           return -99;
14256         }
14257     }
14258
14259   M (ONE_MAP_REQUEST_MODE, mp);
14260
14261   mp->mode = mode;
14262
14263   /* send */
14264   S (mp);
14265
14266   /* wait for reply */
14267   W (ret);
14268   return ret;
14269 }
14270
14271 #define api_lisp_map_request_mode api_one_map_request_mode
14272
14273 /**
14274  * Enable/disable ONE proxy ITR.
14275  *
14276  * @param vam vpp API test context
14277  * @return return code
14278  */
14279 static int
14280 api_one_pitr_set_locator_set (vat_main_t * vam)
14281 {
14282   u8 ls_name_set = 0;
14283   unformat_input_t *input = vam->input;
14284   vl_api_one_pitr_set_locator_set_t *mp;
14285   u8 is_add = 1;
14286   u8 *ls_name = 0;
14287   int ret;
14288
14289   /* Parse args required to build the message */
14290   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14291     {
14292       if (unformat (input, "del"))
14293         is_add = 0;
14294       else if (unformat (input, "locator-set %s", &ls_name))
14295         ls_name_set = 1;
14296       else
14297         {
14298           errmsg ("parse error '%U'", format_unformat_error, input);
14299           return -99;
14300         }
14301     }
14302
14303   if (!ls_name_set)
14304     {
14305       errmsg ("locator-set name not set!");
14306       return -99;
14307     }
14308
14309   M (ONE_PITR_SET_LOCATOR_SET, mp);
14310
14311   mp->is_add = is_add;
14312   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
14313   vec_free (ls_name);
14314
14315   /* send */
14316   S (mp);
14317
14318   /* wait for reply */
14319   W (ret);
14320   return ret;
14321 }
14322
14323 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
14324
14325 static int
14326 api_show_one_pitr (vat_main_t * vam)
14327 {
14328   vl_api_show_one_pitr_t *mp;
14329   int ret;
14330
14331   if (!vam->json_output)
14332     {
14333       print (vam->ofp, "%=20s", "lisp status:");
14334     }
14335
14336   M (SHOW_ONE_PITR, mp);
14337   /* send it... */
14338   S (mp);
14339
14340   /* Wait for a reply... */
14341   W (ret);
14342   return ret;
14343 }
14344
14345 #define api_show_lisp_pitr api_show_one_pitr
14346
14347 static int
14348 api_one_use_petr (vat_main_t * vam)
14349 {
14350   unformat_input_t *input = vam->input;
14351   vl_api_one_use_petr_t *mp;
14352   u8 is_add = 0;
14353   ip_address_t ip;
14354   int ret;
14355
14356   memset (&ip, 0, sizeof (ip));
14357
14358   /* Parse args required to build the message */
14359   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14360     {
14361       if (unformat (input, "disable"))
14362         is_add = 0;
14363       else
14364         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
14365         {
14366           is_add = 1;
14367           ip_addr_version (&ip) = IP4;
14368         }
14369       else
14370         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
14371         {
14372           is_add = 1;
14373           ip_addr_version (&ip) = IP6;
14374         }
14375       else
14376         {
14377           errmsg ("parse error '%U'", format_unformat_error, input);
14378           return -99;
14379         }
14380     }
14381
14382   M (ONE_USE_PETR, mp);
14383
14384   mp->is_add = is_add;
14385   if (is_add)
14386     {
14387       mp->is_ip4 = ip_addr_version (&ip) == IP4 ? 1 : 0;
14388       if (mp->is_ip4)
14389         clib_memcpy (mp->address, &ip, 4);
14390       else
14391         clib_memcpy (mp->address, &ip, 16);
14392     }
14393
14394   /* send */
14395   S (mp);
14396
14397   /* wait for reply */
14398   W (ret);
14399   return ret;
14400 }
14401
14402 #define api_lisp_use_petr api_one_use_petr
14403
14404 static int
14405 api_show_one_use_petr (vat_main_t * vam)
14406 {
14407   vl_api_show_one_use_petr_t *mp;
14408   int ret;
14409
14410   if (!vam->json_output)
14411     {
14412       print (vam->ofp, "%=20s", "Proxy-ETR status:");
14413     }
14414
14415   M (SHOW_ONE_USE_PETR, mp);
14416   /* send it... */
14417   S (mp);
14418
14419   /* Wait for a reply... */
14420   W (ret);
14421   return ret;
14422 }
14423
14424 #define api_show_lisp_use_petr api_show_one_use_petr
14425
14426 /**
14427  * Add/delete mapping between vni and vrf
14428  */
14429 static int
14430 api_one_eid_table_add_del_map (vat_main_t * vam)
14431 {
14432   unformat_input_t *input = vam->input;
14433   vl_api_one_eid_table_add_del_map_t *mp;
14434   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
14435   u32 vni, vrf, bd_index;
14436   int ret;
14437
14438   /* Parse args required to build the message */
14439   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14440     {
14441       if (unformat (input, "del"))
14442         is_add = 0;
14443       else if (unformat (input, "vrf %d", &vrf))
14444         vrf_set = 1;
14445       else if (unformat (input, "bd_index %d", &bd_index))
14446         bd_index_set = 1;
14447       else if (unformat (input, "vni %d", &vni))
14448         vni_set = 1;
14449       else
14450         break;
14451     }
14452
14453   if (!vni_set || (!vrf_set && !bd_index_set))
14454     {
14455       errmsg ("missing arguments!");
14456       return -99;
14457     }
14458
14459   if (vrf_set && bd_index_set)
14460     {
14461       errmsg ("error: both vrf and bd entered!");
14462       return -99;
14463     }
14464
14465   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
14466
14467   mp->is_add = is_add;
14468   mp->vni = htonl (vni);
14469   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
14470   mp->is_l2 = bd_index_set;
14471
14472   /* send */
14473   S (mp);
14474
14475   /* wait for reply */
14476   W (ret);
14477   return ret;
14478 }
14479
14480 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
14481
14482 uword
14483 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
14484 {
14485   u32 *action = va_arg (*args, u32 *);
14486   u8 *s = 0;
14487
14488   if (unformat (input, "%s", &s))
14489     {
14490       if (!strcmp ((char *) s, "no-action"))
14491         action[0] = 0;
14492       else if (!strcmp ((char *) s, "natively-forward"))
14493         action[0] = 1;
14494       else if (!strcmp ((char *) s, "send-map-request"))
14495         action[0] = 2;
14496       else if (!strcmp ((char *) s, "drop"))
14497         action[0] = 3;
14498       else
14499         {
14500           clib_warning ("invalid action: '%s'", s);
14501           action[0] = 3;
14502         }
14503     }
14504   else
14505     return 0;
14506
14507   vec_free (s);
14508   return 1;
14509 }
14510
14511 /**
14512  * Add/del remote mapping to/from ONE control plane
14513  *
14514  * @param vam vpp API test context
14515  * @return return code
14516  */
14517 static int
14518 api_one_add_del_remote_mapping (vat_main_t * vam)
14519 {
14520   unformat_input_t *input = vam->input;
14521   vl_api_one_add_del_remote_mapping_t *mp;
14522   u32 vni = 0;
14523   lisp_eid_vat_t _eid, *eid = &_eid;
14524   lisp_eid_vat_t _seid, *seid = &_seid;
14525   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
14526   u32 action = ~0, p, w, data_len;
14527   ip4_address_t rloc4;
14528   ip6_address_t rloc6;
14529   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
14530   int ret;
14531
14532   memset (&rloc, 0, sizeof (rloc));
14533
14534   /* Parse args required to build the message */
14535   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14536     {
14537       if (unformat (input, "del-all"))
14538         {
14539           del_all = 1;
14540         }
14541       else if (unformat (input, "del"))
14542         {
14543           is_add = 0;
14544         }
14545       else if (unformat (input, "add"))
14546         {
14547           is_add = 1;
14548         }
14549       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
14550         {
14551           eid_set = 1;
14552         }
14553       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
14554         {
14555           seid_set = 1;
14556         }
14557       else if (unformat (input, "vni %d", &vni))
14558         {
14559           ;
14560         }
14561       else if (unformat (input, "p %d w %d", &p, &w))
14562         {
14563           if (!curr_rloc)
14564             {
14565               errmsg ("No RLOC configured for setting priority/weight!");
14566               return -99;
14567             }
14568           curr_rloc->priority = p;
14569           curr_rloc->weight = w;
14570         }
14571       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
14572         {
14573           rloc.is_ip4 = 1;
14574           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
14575           vec_add1 (rlocs, rloc);
14576           curr_rloc = &rlocs[vec_len (rlocs) - 1];
14577         }
14578       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
14579         {
14580           rloc.is_ip4 = 0;
14581           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
14582           vec_add1 (rlocs, rloc);
14583           curr_rloc = &rlocs[vec_len (rlocs) - 1];
14584         }
14585       else if (unformat (input, "action %U",
14586                          unformat_negative_mapping_action, &action))
14587         {
14588           ;
14589         }
14590       else
14591         {
14592           clib_warning ("parse error '%U'", format_unformat_error, input);
14593           return -99;
14594         }
14595     }
14596
14597   if (0 == eid_set)
14598     {
14599       errmsg ("missing params!");
14600       return -99;
14601     }
14602
14603   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
14604     {
14605       errmsg ("no action set for negative map-reply!");
14606       return -99;
14607     }
14608
14609   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
14610
14611   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
14612   mp->is_add = is_add;
14613   mp->vni = htonl (vni);
14614   mp->action = (u8) action;
14615   mp->is_src_dst = seid_set;
14616   mp->eid_len = eid->len;
14617   mp->seid_len = seid->len;
14618   mp->del_all = del_all;
14619   mp->eid_type = eid->type;
14620   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
14621   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
14622
14623   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
14624   clib_memcpy (mp->rlocs, rlocs, data_len);
14625   vec_free (rlocs);
14626
14627   /* send it... */
14628   S (mp);
14629
14630   /* Wait for a reply... */
14631   W (ret);
14632   return ret;
14633 }
14634
14635 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
14636
14637 /**
14638  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
14639  * forwarding entries in data-plane accordingly.
14640  *
14641  * @param vam vpp API test context
14642  * @return return code
14643  */
14644 static int
14645 api_one_add_del_adjacency (vat_main_t * vam)
14646 {
14647   unformat_input_t *input = vam->input;
14648   vl_api_one_add_del_adjacency_t *mp;
14649   u32 vni = 0;
14650   ip4_address_t leid4, reid4;
14651   ip6_address_t leid6, reid6;
14652   u8 reid_mac[6] = { 0 };
14653   u8 leid_mac[6] = { 0 };
14654   u8 reid_type, leid_type;
14655   u32 leid_len = 0, reid_len = 0, len;
14656   u8 is_add = 1;
14657   int ret;
14658
14659   leid_type = reid_type = (u8) ~ 0;
14660
14661   /* Parse args required to build the message */
14662   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14663     {
14664       if (unformat (input, "del"))
14665         {
14666           is_add = 0;
14667         }
14668       else if (unformat (input, "add"))
14669         {
14670           is_add = 1;
14671         }
14672       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
14673                          &reid4, &len))
14674         {
14675           reid_type = 0;        /* ipv4 */
14676           reid_len = len;
14677         }
14678       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
14679                          &reid6, &len))
14680         {
14681           reid_type = 1;        /* ipv6 */
14682           reid_len = len;
14683         }
14684       else if (unformat (input, "reid %U", unformat_ethernet_address,
14685                          reid_mac))
14686         {
14687           reid_type = 2;        /* mac */
14688         }
14689       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
14690                          &leid4, &len))
14691         {
14692           leid_type = 0;        /* ipv4 */
14693           leid_len = len;
14694         }
14695       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
14696                          &leid6, &len))
14697         {
14698           leid_type = 1;        /* ipv6 */
14699           leid_len = len;
14700         }
14701       else if (unformat (input, "leid %U", unformat_ethernet_address,
14702                          leid_mac))
14703         {
14704           leid_type = 2;        /* mac */
14705         }
14706       else if (unformat (input, "vni %d", &vni))
14707         {
14708           ;
14709         }
14710       else
14711         {
14712           errmsg ("parse error '%U'", format_unformat_error, input);
14713           return -99;
14714         }
14715     }
14716
14717   if ((u8) ~ 0 == reid_type)
14718     {
14719       errmsg ("missing params!");
14720       return -99;
14721     }
14722
14723   if (leid_type != reid_type)
14724     {
14725       errmsg ("remote and local EIDs are of different types!");
14726       return -99;
14727     }
14728
14729   M (ONE_ADD_DEL_ADJACENCY, mp);
14730   mp->is_add = is_add;
14731   mp->vni = htonl (vni);
14732   mp->leid_len = leid_len;
14733   mp->reid_len = reid_len;
14734   mp->eid_type = reid_type;
14735
14736   switch (mp->eid_type)
14737     {
14738     case 0:
14739       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
14740       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
14741       break;
14742     case 1:
14743       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
14744       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
14745       break;
14746     case 2:
14747       clib_memcpy (mp->leid, leid_mac, 6);
14748       clib_memcpy (mp->reid, reid_mac, 6);
14749       break;
14750     default:
14751       errmsg ("unknown EID type %d!", mp->eid_type);
14752       return 0;
14753     }
14754
14755   /* send it... */
14756   S (mp);
14757
14758   /* Wait for a reply... */
14759   W (ret);
14760   return ret;
14761 }
14762
14763 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
14764
14765 uword
14766 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
14767 {
14768   u32 *mode = va_arg (*args, u32 *);
14769
14770   if (unformat (input, "lisp"))
14771     *mode = 0;
14772   else if (unformat (input, "vxlan"))
14773     *mode = 1;
14774   else
14775     return 0;
14776
14777   return 1;
14778 }
14779
14780 static int
14781 api_gpe_get_encap_mode (vat_main_t * vam)
14782 {
14783   vl_api_gpe_get_encap_mode_t *mp;
14784   int ret;
14785
14786   /* Construct the API message */
14787   M (GPE_GET_ENCAP_MODE, mp);
14788
14789   /* send it... */
14790   S (mp);
14791
14792   /* Wait for a reply... */
14793   W (ret);
14794   return ret;
14795 }
14796
14797 static int
14798 api_gpe_set_encap_mode (vat_main_t * vam)
14799 {
14800   unformat_input_t *input = vam->input;
14801   vl_api_gpe_set_encap_mode_t *mp;
14802   int ret;
14803   u32 mode = 0;
14804
14805   /* Parse args required to build the message */
14806   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14807     {
14808       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
14809         ;
14810       else
14811         break;
14812     }
14813
14814   /* Construct the API message */
14815   M (GPE_SET_ENCAP_MODE, mp);
14816
14817   mp->mode = mode;
14818
14819   /* send it... */
14820   S (mp);
14821
14822   /* Wait for a reply... */
14823   W (ret);
14824   return ret;
14825 }
14826
14827 static int
14828 api_lisp_gpe_add_del_iface (vat_main_t * vam)
14829 {
14830   unformat_input_t *input = vam->input;
14831   vl_api_gpe_add_del_iface_t *mp;
14832   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
14833   u32 dp_table = 0, vni = 0;
14834   int ret;
14835
14836   /* Parse args required to build the message */
14837   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14838     {
14839       if (unformat (input, "up"))
14840         {
14841           action_set = 1;
14842           is_add = 1;
14843         }
14844       else if (unformat (input, "down"))
14845         {
14846           action_set = 1;
14847           is_add = 0;
14848         }
14849       else if (unformat (input, "table_id %d", &dp_table))
14850         {
14851           dp_table_set = 1;
14852         }
14853       else if (unformat (input, "bd_id %d", &dp_table))
14854         {
14855           dp_table_set = 1;
14856           is_l2 = 1;
14857         }
14858       else if (unformat (input, "vni %d", &vni))
14859         {
14860           vni_set = 1;
14861         }
14862       else
14863         break;
14864     }
14865
14866   if (action_set == 0)
14867     {
14868       errmsg ("Action not set");
14869       return -99;
14870     }
14871   if (dp_table_set == 0 || vni_set == 0)
14872     {
14873       errmsg ("vni and dp_table must be set");
14874       return -99;
14875     }
14876
14877   /* Construct the API message */
14878   M (GPE_ADD_DEL_IFACE, mp);
14879
14880   mp->is_add = is_add;
14881   mp->dp_table = dp_table;
14882   mp->is_l2 = is_l2;
14883   mp->vni = vni;
14884
14885   /* send it... */
14886   S (mp);
14887
14888   /* Wait for a reply... */
14889   W (ret);
14890   return ret;
14891 }
14892
14893 /**
14894  * Add/del map request itr rlocs from ONE control plane and updates
14895  *
14896  * @param vam vpp API test context
14897  * @return return code
14898  */
14899 static int
14900 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
14901 {
14902   unformat_input_t *input = vam->input;
14903   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
14904   u8 *locator_set_name = 0;
14905   u8 locator_set_name_set = 0;
14906   u8 is_add = 1;
14907   int ret;
14908
14909   /* Parse args required to build the message */
14910   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14911     {
14912       if (unformat (input, "del"))
14913         {
14914           is_add = 0;
14915         }
14916       else if (unformat (input, "%_%v%_", &locator_set_name))
14917         {
14918           locator_set_name_set = 1;
14919         }
14920       else
14921         {
14922           clib_warning ("parse error '%U'", format_unformat_error, input);
14923           return -99;
14924         }
14925     }
14926
14927   if (is_add && !locator_set_name_set)
14928     {
14929       errmsg ("itr-rloc is not set!");
14930       return -99;
14931     }
14932
14933   if (is_add && vec_len (locator_set_name) > 64)
14934     {
14935       errmsg ("itr-rloc locator-set name too long");
14936       vec_free (locator_set_name);
14937       return -99;
14938     }
14939
14940   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
14941   mp->is_add = is_add;
14942   if (is_add)
14943     {
14944       clib_memcpy (mp->locator_set_name, locator_set_name,
14945                    vec_len (locator_set_name));
14946     }
14947   else
14948     {
14949       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
14950     }
14951   vec_free (locator_set_name);
14952
14953   /* send it... */
14954   S (mp);
14955
14956   /* Wait for a reply... */
14957   W (ret);
14958   return ret;
14959 }
14960
14961 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
14962
14963 static int
14964 api_one_locator_dump (vat_main_t * vam)
14965 {
14966   unformat_input_t *input = vam->input;
14967   vl_api_one_locator_dump_t *mp;
14968   vl_api_control_ping_t *mp_ping;
14969   u8 is_index_set = 0, is_name_set = 0;
14970   u8 *ls_name = 0;
14971   u32 ls_index = ~0;
14972   int ret;
14973
14974   /* Parse args required to build the message */
14975   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14976     {
14977       if (unformat (input, "ls_name %_%v%_", &ls_name))
14978         {
14979           is_name_set = 1;
14980         }
14981       else if (unformat (input, "ls_index %d", &ls_index))
14982         {
14983           is_index_set = 1;
14984         }
14985       else
14986         {
14987           errmsg ("parse error '%U'", format_unformat_error, input);
14988           return -99;
14989         }
14990     }
14991
14992   if (!is_index_set && !is_name_set)
14993     {
14994       errmsg ("error: expected one of index or name!");
14995       return -99;
14996     }
14997
14998   if (is_index_set && is_name_set)
14999     {
15000       errmsg ("error: only one param expected!");
15001       return -99;
15002     }
15003
15004   if (vec_len (ls_name) > 62)
15005     {
15006       errmsg ("error: locator set name too long!");
15007       return -99;
15008     }
15009
15010   if (!vam->json_output)
15011     {
15012       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
15013     }
15014
15015   M (ONE_LOCATOR_DUMP, mp);
15016   mp->is_index_set = is_index_set;
15017
15018   if (is_index_set)
15019     mp->ls_index = clib_host_to_net_u32 (ls_index);
15020   else
15021     {
15022       vec_add1 (ls_name, 0);
15023       strncpy ((char *) mp->ls_name, (char *) ls_name,
15024                sizeof (mp->ls_name) - 1);
15025     }
15026
15027   /* send it... */
15028   S (mp);
15029
15030   /* Use a control ping for synchronization */
15031   M (CONTROL_PING, mp_ping);
15032   S (mp_ping);
15033
15034   /* Wait for a reply... */
15035   W (ret);
15036   return ret;
15037 }
15038
15039 #define api_lisp_locator_dump api_one_locator_dump
15040
15041 static int
15042 api_one_locator_set_dump (vat_main_t * vam)
15043 {
15044   vl_api_one_locator_set_dump_t *mp;
15045   vl_api_control_ping_t *mp_ping;
15046   unformat_input_t *input = vam->input;
15047   u8 filter = 0;
15048   int ret;
15049
15050   /* Parse args required to build the message */
15051   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15052     {
15053       if (unformat (input, "local"))
15054         {
15055           filter = 1;
15056         }
15057       else if (unformat (input, "remote"))
15058         {
15059           filter = 2;
15060         }
15061       else
15062         {
15063           errmsg ("parse error '%U'", format_unformat_error, input);
15064           return -99;
15065         }
15066     }
15067
15068   if (!vam->json_output)
15069     {
15070       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
15071     }
15072
15073   M (ONE_LOCATOR_SET_DUMP, mp);
15074
15075   mp->filter = filter;
15076
15077   /* send it... */
15078   S (mp);
15079
15080   /* Use a control ping for synchronization */
15081   M (CONTROL_PING, mp_ping);
15082   S (mp_ping);
15083
15084   /* Wait for a reply... */
15085   W (ret);
15086   return ret;
15087 }
15088
15089 #define api_lisp_locator_set_dump api_one_locator_set_dump
15090
15091 static int
15092 api_one_eid_table_map_dump (vat_main_t * vam)
15093 {
15094   u8 is_l2 = 0;
15095   u8 mode_set = 0;
15096   unformat_input_t *input = vam->input;
15097   vl_api_one_eid_table_map_dump_t *mp;
15098   vl_api_control_ping_t *mp_ping;
15099   int ret;
15100
15101   /* Parse args required to build the message */
15102   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15103     {
15104       if (unformat (input, "l2"))
15105         {
15106           is_l2 = 1;
15107           mode_set = 1;
15108         }
15109       else if (unformat (input, "l3"))
15110         {
15111           is_l2 = 0;
15112           mode_set = 1;
15113         }
15114       else
15115         {
15116           errmsg ("parse error '%U'", format_unformat_error, input);
15117           return -99;
15118         }
15119     }
15120
15121   if (!mode_set)
15122     {
15123       errmsg ("expected one of 'l2' or 'l3' parameter!");
15124       return -99;
15125     }
15126
15127   if (!vam->json_output)
15128     {
15129       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
15130     }
15131
15132   M (ONE_EID_TABLE_MAP_DUMP, mp);
15133   mp->is_l2 = is_l2;
15134
15135   /* send it... */
15136   S (mp);
15137
15138   /* Use a control ping for synchronization */
15139   M (CONTROL_PING, mp_ping);
15140   S (mp_ping);
15141
15142   /* Wait for a reply... */
15143   W (ret);
15144   return ret;
15145 }
15146
15147 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
15148
15149 static int
15150 api_one_eid_table_vni_dump (vat_main_t * vam)
15151 {
15152   vl_api_one_eid_table_vni_dump_t *mp;
15153   vl_api_control_ping_t *mp_ping;
15154   int ret;
15155
15156   if (!vam->json_output)
15157     {
15158       print (vam->ofp, "VNI");
15159     }
15160
15161   M (ONE_EID_TABLE_VNI_DUMP, mp);
15162
15163   /* send it... */
15164   S (mp);
15165
15166   /* Use a control ping for synchronization */
15167   M (CONTROL_PING, mp_ping);
15168   S (mp_ping);
15169
15170   /* Wait for a reply... */
15171   W (ret);
15172   return ret;
15173 }
15174
15175 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
15176
15177 static int
15178 api_one_eid_table_dump (vat_main_t * vam)
15179 {
15180   unformat_input_t *i = vam->input;
15181   vl_api_one_eid_table_dump_t *mp;
15182   vl_api_control_ping_t *mp_ping;
15183   struct in_addr ip4;
15184   struct in6_addr ip6;
15185   u8 mac[6];
15186   u8 eid_type = ~0, eid_set = 0;
15187   u32 prefix_length = ~0, t, vni = 0;
15188   u8 filter = 0;
15189   int ret;
15190
15191   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15192     {
15193       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
15194         {
15195           eid_set = 1;
15196           eid_type = 0;
15197           prefix_length = t;
15198         }
15199       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
15200         {
15201           eid_set = 1;
15202           eid_type = 1;
15203           prefix_length = t;
15204         }
15205       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
15206         {
15207           eid_set = 1;
15208           eid_type = 2;
15209         }
15210       else if (unformat (i, "vni %d", &t))
15211         {
15212           vni = t;
15213         }
15214       else if (unformat (i, "local"))
15215         {
15216           filter = 1;
15217         }
15218       else if (unformat (i, "remote"))
15219         {
15220           filter = 2;
15221         }
15222       else
15223         {
15224           errmsg ("parse error '%U'", format_unformat_error, i);
15225           return -99;
15226         }
15227     }
15228
15229   if (!vam->json_output)
15230     {
15231       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
15232              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
15233     }
15234
15235   M (ONE_EID_TABLE_DUMP, mp);
15236
15237   mp->filter = filter;
15238   if (eid_set)
15239     {
15240       mp->eid_set = 1;
15241       mp->vni = htonl (vni);
15242       mp->eid_type = eid_type;
15243       switch (eid_type)
15244         {
15245         case 0:
15246           mp->prefix_length = prefix_length;
15247           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
15248           break;
15249         case 1:
15250           mp->prefix_length = prefix_length;
15251           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
15252           break;
15253         case 2:
15254           clib_memcpy (mp->eid, mac, sizeof (mac));
15255           break;
15256         default:
15257           errmsg ("unknown EID type %d!", eid_type);
15258           return -99;
15259         }
15260     }
15261
15262   /* send it... */
15263   S (mp);
15264
15265   /* Use a control ping for synchronization */
15266   M (CONTROL_PING, mp_ping);
15267   S (mp_ping);
15268
15269   /* Wait for a reply... */
15270   W (ret);
15271   return ret;
15272 }
15273
15274 #define api_lisp_eid_table_dump api_one_eid_table_dump
15275
15276 static int
15277 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
15278 {
15279   unformat_input_t *i = vam->input;
15280   vl_api_gpe_fwd_entries_get_t *mp;
15281   u8 vni_set = 0;
15282   u32 vni = ~0;
15283   int ret;
15284
15285   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15286     {
15287       if (unformat (i, "vni %d", &vni))
15288         {
15289           vni_set = 1;
15290         }
15291       else
15292         {
15293           errmsg ("parse error '%U'", format_unformat_error, i);
15294           return -99;
15295         }
15296     }
15297
15298   if (!vni_set)
15299     {
15300       errmsg ("vni not set!");
15301       return -99;
15302     }
15303
15304   if (!vam->json_output)
15305     {
15306       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
15307              "leid", "reid");
15308     }
15309
15310   M (GPE_FWD_ENTRIES_GET, mp);
15311   mp->vni = clib_host_to_net_u32 (vni);
15312
15313   /* send it... */
15314   S (mp);
15315
15316   /* Wait for a reply... */
15317   W (ret);
15318   return ret;
15319 }
15320
15321 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
15322 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
15323 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
15324 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
15325
15326 static int
15327 api_one_adjacencies_get (vat_main_t * vam)
15328 {
15329   unformat_input_t *i = vam->input;
15330   vl_api_one_adjacencies_get_t *mp;
15331   u8 vni_set = 0;
15332   u32 vni = ~0;
15333   int ret;
15334
15335   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15336     {
15337       if (unformat (i, "vni %d", &vni))
15338         {
15339           vni_set = 1;
15340         }
15341       else
15342         {
15343           errmsg ("parse error '%U'", format_unformat_error, i);
15344           return -99;
15345         }
15346     }
15347
15348   if (!vni_set)
15349     {
15350       errmsg ("vni not set!");
15351       return -99;
15352     }
15353
15354   if (!vam->json_output)
15355     {
15356       print (vam->ofp, "%s %40s", "leid", "reid");
15357     }
15358
15359   M (ONE_ADJACENCIES_GET, mp);
15360   mp->vni = clib_host_to_net_u32 (vni);
15361
15362   /* send it... */
15363   S (mp);
15364
15365   /* Wait for a reply... */
15366   W (ret);
15367   return ret;
15368 }
15369
15370 #define api_lisp_adjacencies_get api_one_adjacencies_get
15371
15372 static int
15373 api_one_map_server_dump (vat_main_t * vam)
15374 {
15375   vl_api_one_map_server_dump_t *mp;
15376   vl_api_control_ping_t *mp_ping;
15377   int ret;
15378
15379   if (!vam->json_output)
15380     {
15381       print (vam->ofp, "%=20s", "Map server");
15382     }
15383
15384   M (ONE_MAP_SERVER_DUMP, mp);
15385   /* send it... */
15386   S (mp);
15387
15388   /* Use a control ping for synchronization */
15389   M (CONTROL_PING, mp_ping);
15390   S (mp_ping);
15391
15392   /* Wait for a reply... */
15393   W (ret);
15394   return ret;
15395 }
15396
15397 #define api_lisp_map_server_dump api_one_map_server_dump
15398
15399 static int
15400 api_one_map_resolver_dump (vat_main_t * vam)
15401 {
15402   vl_api_one_map_resolver_dump_t *mp;
15403   vl_api_control_ping_t *mp_ping;
15404   int ret;
15405
15406   if (!vam->json_output)
15407     {
15408       print (vam->ofp, "%=20s", "Map resolver");
15409     }
15410
15411   M (ONE_MAP_RESOLVER_DUMP, mp);
15412   /* send it... */
15413   S (mp);
15414
15415   /* Use a control ping for synchronization */
15416   M (CONTROL_PING, mp_ping);
15417   S (mp_ping);
15418
15419   /* Wait for a reply... */
15420   W (ret);
15421   return ret;
15422 }
15423
15424 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
15425
15426 static int
15427 api_show_one_status (vat_main_t * vam)
15428 {
15429   vl_api_show_one_status_t *mp;
15430   int ret;
15431
15432   if (!vam->json_output)
15433     {
15434       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
15435     }
15436
15437   M (SHOW_ONE_STATUS, mp);
15438   /* send it... */
15439   S (mp);
15440   /* Wait for a reply... */
15441   W (ret);
15442   return ret;
15443 }
15444
15445 #define api_show_lisp_status api_show_one_status
15446
15447 static int
15448 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
15449 {
15450   vl_api_gpe_fwd_entry_path_dump_t *mp;
15451   vl_api_control_ping_t *mp_ping;
15452   unformat_input_t *i = vam->input;
15453   u32 fwd_entry_index = ~0;
15454   int ret;
15455
15456   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15457     {
15458       if (unformat (i, "index %d", &fwd_entry_index))
15459         ;
15460       else
15461         break;
15462     }
15463
15464   if (~0 == fwd_entry_index)
15465     {
15466       errmsg ("no index specified!");
15467       return -99;
15468     }
15469
15470   if (!vam->json_output)
15471     {
15472       print (vam->ofp, "first line");
15473     }
15474
15475   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
15476
15477   /* send it... */
15478   S (mp);
15479   /* Use a control ping for synchronization */
15480   M (CONTROL_PING, mp_ping);
15481   S (mp_ping);
15482
15483   /* Wait for a reply... */
15484   W (ret);
15485   return ret;
15486 }
15487
15488 static int
15489 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
15490 {
15491   vl_api_one_get_map_request_itr_rlocs_t *mp;
15492   int ret;
15493
15494   if (!vam->json_output)
15495     {
15496       print (vam->ofp, "%=20s", "itr-rlocs:");
15497     }
15498
15499   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
15500   /* send it... */
15501   S (mp);
15502   /* Wait for a reply... */
15503   W (ret);
15504   return ret;
15505 }
15506
15507 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
15508
15509 static int
15510 api_af_packet_create (vat_main_t * vam)
15511 {
15512   unformat_input_t *i = vam->input;
15513   vl_api_af_packet_create_t *mp;
15514   u8 *host_if_name = 0;
15515   u8 hw_addr[6];
15516   u8 random_hw_addr = 1;
15517   int ret;
15518
15519   memset (hw_addr, 0, sizeof (hw_addr));
15520
15521   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15522     {
15523       if (unformat (i, "name %s", &host_if_name))
15524         vec_add1 (host_if_name, 0);
15525       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
15526         random_hw_addr = 0;
15527       else
15528         break;
15529     }
15530
15531   if (!vec_len (host_if_name))
15532     {
15533       errmsg ("host-interface name must be specified");
15534       return -99;
15535     }
15536
15537   if (vec_len (host_if_name) > 64)
15538     {
15539       errmsg ("host-interface name too long");
15540       return -99;
15541     }
15542
15543   M (AF_PACKET_CREATE, mp);
15544
15545   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
15546   clib_memcpy (mp->hw_addr, hw_addr, 6);
15547   mp->use_random_hw_addr = random_hw_addr;
15548   vec_free (host_if_name);
15549
15550   S (mp);
15551
15552   /* *INDENT-OFF* */
15553   W2 (ret,
15554       ({
15555         if (ret == 0)
15556           fprintf (vam->ofp ? vam->ofp : stderr,
15557                    " new sw_if_index = %d\n", vam->sw_if_index);
15558       }));
15559   /* *INDENT-ON* */
15560   return ret;
15561 }
15562
15563 static int
15564 api_af_packet_delete (vat_main_t * vam)
15565 {
15566   unformat_input_t *i = vam->input;
15567   vl_api_af_packet_delete_t *mp;
15568   u8 *host_if_name = 0;
15569   int ret;
15570
15571   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15572     {
15573       if (unformat (i, "name %s", &host_if_name))
15574         vec_add1 (host_if_name, 0);
15575       else
15576         break;
15577     }
15578
15579   if (!vec_len (host_if_name))
15580     {
15581       errmsg ("host-interface name must be specified");
15582       return -99;
15583     }
15584
15585   if (vec_len (host_if_name) > 64)
15586     {
15587       errmsg ("host-interface name too long");
15588       return -99;
15589     }
15590
15591   M (AF_PACKET_DELETE, mp);
15592
15593   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
15594   vec_free (host_if_name);
15595
15596   S (mp);
15597   W (ret);
15598   return ret;
15599 }
15600
15601 static int
15602 api_policer_add_del (vat_main_t * vam)
15603 {
15604   unformat_input_t *i = vam->input;
15605   vl_api_policer_add_del_t *mp;
15606   u8 is_add = 1;
15607   u8 *name = 0;
15608   u32 cir = 0;
15609   u32 eir = 0;
15610   u64 cb = 0;
15611   u64 eb = 0;
15612   u8 rate_type = 0;
15613   u8 round_type = 0;
15614   u8 type = 0;
15615   u8 color_aware = 0;
15616   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
15617   int ret;
15618
15619   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
15620   conform_action.dscp = 0;
15621   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
15622   exceed_action.dscp = 0;
15623   violate_action.action_type = SSE2_QOS_ACTION_DROP;
15624   violate_action.dscp = 0;
15625
15626   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15627     {
15628       if (unformat (i, "del"))
15629         is_add = 0;
15630       else if (unformat (i, "name %s", &name))
15631         vec_add1 (name, 0);
15632       else if (unformat (i, "cir %u", &cir))
15633         ;
15634       else if (unformat (i, "eir %u", &eir))
15635         ;
15636       else if (unformat (i, "cb %u", &cb))
15637         ;
15638       else if (unformat (i, "eb %u", &eb))
15639         ;
15640       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
15641                          &rate_type))
15642         ;
15643       else if (unformat (i, "round_type %U", unformat_policer_round_type,
15644                          &round_type))
15645         ;
15646       else if (unformat (i, "type %U", unformat_policer_type, &type))
15647         ;
15648       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
15649                          &conform_action))
15650         ;
15651       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
15652                          &exceed_action))
15653         ;
15654       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
15655                          &violate_action))
15656         ;
15657       else if (unformat (i, "color-aware"))
15658         color_aware = 1;
15659       else
15660         break;
15661     }
15662
15663   if (!vec_len (name))
15664     {
15665       errmsg ("policer name must be specified");
15666       return -99;
15667     }
15668
15669   if (vec_len (name) > 64)
15670     {
15671       errmsg ("policer name too long");
15672       return -99;
15673     }
15674
15675   M (POLICER_ADD_DEL, mp);
15676
15677   clib_memcpy (mp->name, name, vec_len (name));
15678   vec_free (name);
15679   mp->is_add = is_add;
15680   mp->cir = cir;
15681   mp->eir = eir;
15682   mp->cb = cb;
15683   mp->eb = eb;
15684   mp->rate_type = rate_type;
15685   mp->round_type = round_type;
15686   mp->type = type;
15687   mp->conform_action_type = conform_action.action_type;
15688   mp->conform_dscp = conform_action.dscp;
15689   mp->exceed_action_type = exceed_action.action_type;
15690   mp->exceed_dscp = exceed_action.dscp;
15691   mp->violate_action_type = violate_action.action_type;
15692   mp->violate_dscp = violate_action.dscp;
15693   mp->color_aware = color_aware;
15694
15695   S (mp);
15696   W (ret);
15697   return ret;
15698 }
15699
15700 static int
15701 api_policer_dump (vat_main_t * vam)
15702 {
15703   unformat_input_t *i = vam->input;
15704   vl_api_policer_dump_t *mp;
15705   vl_api_control_ping_t *mp_ping;
15706   u8 *match_name = 0;
15707   u8 match_name_valid = 0;
15708   int ret;
15709
15710   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15711     {
15712       if (unformat (i, "name %s", &match_name))
15713         {
15714           vec_add1 (match_name, 0);
15715           match_name_valid = 1;
15716         }
15717       else
15718         break;
15719     }
15720
15721   M (POLICER_DUMP, mp);
15722   mp->match_name_valid = match_name_valid;
15723   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
15724   vec_free (match_name);
15725   /* send it... */
15726   S (mp);
15727
15728   /* Use a control ping for synchronization */
15729   M (CONTROL_PING, mp_ping);
15730   S (mp_ping);
15731
15732   /* Wait for a reply... */
15733   W (ret);
15734   return ret;
15735 }
15736
15737 static int
15738 api_policer_classify_set_interface (vat_main_t * vam)
15739 {
15740   unformat_input_t *i = vam->input;
15741   vl_api_policer_classify_set_interface_t *mp;
15742   u32 sw_if_index;
15743   int sw_if_index_set;
15744   u32 ip4_table_index = ~0;
15745   u32 ip6_table_index = ~0;
15746   u32 l2_table_index = ~0;
15747   u8 is_add = 1;
15748   int ret;
15749
15750   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15751     {
15752       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15753         sw_if_index_set = 1;
15754       else if (unformat (i, "sw_if_index %d", &sw_if_index))
15755         sw_if_index_set = 1;
15756       else if (unformat (i, "del"))
15757         is_add = 0;
15758       else if (unformat (i, "ip4-table %d", &ip4_table_index))
15759         ;
15760       else if (unformat (i, "ip6-table %d", &ip6_table_index))
15761         ;
15762       else if (unformat (i, "l2-table %d", &l2_table_index))
15763         ;
15764       else
15765         {
15766           clib_warning ("parse error '%U'", format_unformat_error, i);
15767           return -99;
15768         }
15769     }
15770
15771   if (sw_if_index_set == 0)
15772     {
15773       errmsg ("missing interface name or sw_if_index");
15774       return -99;
15775     }
15776
15777   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
15778
15779   mp->sw_if_index = ntohl (sw_if_index);
15780   mp->ip4_table_index = ntohl (ip4_table_index);
15781   mp->ip6_table_index = ntohl (ip6_table_index);
15782   mp->l2_table_index = ntohl (l2_table_index);
15783   mp->is_add = is_add;
15784
15785   S (mp);
15786   W (ret);
15787   return ret;
15788 }
15789
15790 static int
15791 api_policer_classify_dump (vat_main_t * vam)
15792 {
15793   unformat_input_t *i = vam->input;
15794   vl_api_policer_classify_dump_t *mp;
15795   vl_api_control_ping_t *mp_ping;
15796   u8 type = POLICER_CLASSIFY_N_TABLES;
15797   int ret;
15798
15799   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
15800     ;
15801   else
15802     {
15803       errmsg ("classify table type must be specified");
15804       return -99;
15805     }
15806
15807   if (!vam->json_output)
15808     {
15809       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
15810     }
15811
15812   M (POLICER_CLASSIFY_DUMP, mp);
15813   mp->type = type;
15814   /* send it... */
15815   S (mp);
15816
15817   /* Use a control ping for synchronization */
15818   M (CONTROL_PING, mp_ping);
15819   S (mp_ping);
15820
15821   /* Wait for a reply... */
15822   W (ret);
15823   return ret;
15824 }
15825
15826 static int
15827 api_netmap_create (vat_main_t * vam)
15828 {
15829   unformat_input_t *i = vam->input;
15830   vl_api_netmap_create_t *mp;
15831   u8 *if_name = 0;
15832   u8 hw_addr[6];
15833   u8 random_hw_addr = 1;
15834   u8 is_pipe = 0;
15835   u8 is_master = 0;
15836   int ret;
15837
15838   memset (hw_addr, 0, sizeof (hw_addr));
15839
15840   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15841     {
15842       if (unformat (i, "name %s", &if_name))
15843         vec_add1 (if_name, 0);
15844       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
15845         random_hw_addr = 0;
15846       else if (unformat (i, "pipe"))
15847         is_pipe = 1;
15848       else if (unformat (i, "master"))
15849         is_master = 1;
15850       else if (unformat (i, "slave"))
15851         is_master = 0;
15852       else
15853         break;
15854     }
15855
15856   if (!vec_len (if_name))
15857     {
15858       errmsg ("interface name must be specified");
15859       return -99;
15860     }
15861
15862   if (vec_len (if_name) > 64)
15863     {
15864       errmsg ("interface name too long");
15865       return -99;
15866     }
15867
15868   M (NETMAP_CREATE, mp);
15869
15870   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
15871   clib_memcpy (mp->hw_addr, hw_addr, 6);
15872   mp->use_random_hw_addr = random_hw_addr;
15873   mp->is_pipe = is_pipe;
15874   mp->is_master = is_master;
15875   vec_free (if_name);
15876
15877   S (mp);
15878   W (ret);
15879   return ret;
15880 }
15881
15882 static int
15883 api_netmap_delete (vat_main_t * vam)
15884 {
15885   unformat_input_t *i = vam->input;
15886   vl_api_netmap_delete_t *mp;
15887   u8 *if_name = 0;
15888   int ret;
15889
15890   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15891     {
15892       if (unformat (i, "name %s", &if_name))
15893         vec_add1 (if_name, 0);
15894       else
15895         break;
15896     }
15897
15898   if (!vec_len (if_name))
15899     {
15900       errmsg ("interface name must be specified");
15901       return -99;
15902     }
15903
15904   if (vec_len (if_name) > 64)
15905     {
15906       errmsg ("interface name too long");
15907       return -99;
15908     }
15909
15910   M (NETMAP_DELETE, mp);
15911
15912   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
15913   vec_free (if_name);
15914
15915   S (mp);
15916   W (ret);
15917   return ret;
15918 }
15919
15920 static void vl_api_mpls_tunnel_details_t_handler
15921   (vl_api_mpls_tunnel_details_t * mp)
15922 {
15923   vat_main_t *vam = &vat_main;
15924   i32 len = mp->mt_next_hop_n_labels;
15925   i32 i;
15926
15927   print (vam->ofp, "[%d]: via %U %d labels ",
15928          mp->tunnel_index,
15929          format_ip4_address, mp->mt_next_hop,
15930          ntohl (mp->mt_next_hop_sw_if_index));
15931   for (i = 0; i < len; i++)
15932     {
15933       print (vam->ofp, "%u ", ntohl (mp->mt_next_hop_out_labels[i]));
15934     }
15935   print (vam->ofp, "");
15936 }
15937
15938 static void vl_api_mpls_tunnel_details_t_handler_json
15939   (vl_api_mpls_tunnel_details_t * mp)
15940 {
15941   vat_main_t *vam = &vat_main;
15942   vat_json_node_t *node = NULL;
15943   struct in_addr ip4;
15944   i32 i;
15945   i32 len = mp->mt_next_hop_n_labels;
15946
15947   if (VAT_JSON_ARRAY != vam->json_tree.type)
15948     {
15949       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15950       vat_json_init_array (&vam->json_tree);
15951     }
15952   node = vat_json_array_add (&vam->json_tree);
15953
15954   vat_json_init_object (node);
15955   vat_json_object_add_uint (node, "tunnel_index", ntohl (mp->tunnel_index));
15956   clib_memcpy (&ip4, &(mp->mt_next_hop), sizeof (ip4));
15957   vat_json_object_add_ip4 (node, "next_hop", ip4);
15958   vat_json_object_add_uint (node, "next_hop_sw_if_index",
15959                             ntohl (mp->mt_next_hop_sw_if_index));
15960   vat_json_object_add_uint (node, "l2_only", ntohl (mp->mt_l2_only));
15961   vat_json_object_add_uint (node, "label_count", len);
15962   for (i = 0; i < len; i++)
15963     {
15964       vat_json_object_add_uint (node, "label",
15965                                 ntohl (mp->mt_next_hop_out_labels[i]));
15966     }
15967 }
15968
15969 static int
15970 api_mpls_tunnel_dump (vat_main_t * vam)
15971 {
15972   vl_api_mpls_tunnel_dump_t *mp;
15973   vl_api_control_ping_t *mp_ping;
15974   i32 index = -1;
15975   int ret;
15976
15977   /* Parse args required to build the message */
15978   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
15979     {
15980       if (!unformat (vam->input, "tunnel_index %d", &index))
15981         {
15982           index = -1;
15983           break;
15984         }
15985     }
15986
15987   print (vam->ofp, "  tunnel_index %d", index);
15988
15989   M (MPLS_TUNNEL_DUMP, mp);
15990   mp->tunnel_index = htonl (index);
15991   S (mp);
15992
15993   /* Use a control ping for synchronization */
15994   M (CONTROL_PING, mp_ping);
15995   S (mp_ping);
15996
15997   W (ret);
15998   return ret;
15999 }
16000
16001 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
16002 #define vl_api_mpls_fib_details_t_print vl_noop_handler
16003
16004 static void
16005 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
16006 {
16007   vat_main_t *vam = &vat_main;
16008   int count = ntohl (mp->count);
16009   vl_api_fib_path2_t *fp;
16010   int i;
16011
16012   print (vam->ofp,
16013          "table-id %d, label %u, ess_bit %u",
16014          ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
16015   fp = mp->path;
16016   for (i = 0; i < count; i++)
16017     {
16018       if (fp->afi == IP46_TYPE_IP6)
16019         print (vam->ofp,
16020                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16021                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16022                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16023                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16024                format_ip6_address, fp->next_hop);
16025       else if (fp->afi == IP46_TYPE_IP4)
16026         print (vam->ofp,
16027                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16028                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16029                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16030                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16031                format_ip4_address, fp->next_hop);
16032       fp++;
16033     }
16034 }
16035
16036 static void vl_api_mpls_fib_details_t_handler_json
16037   (vl_api_mpls_fib_details_t * mp)
16038 {
16039   vat_main_t *vam = &vat_main;
16040   int count = ntohl (mp->count);
16041   vat_json_node_t *node = NULL;
16042   struct in_addr ip4;
16043   struct in6_addr ip6;
16044   vl_api_fib_path2_t *fp;
16045   int i;
16046
16047   if (VAT_JSON_ARRAY != vam->json_tree.type)
16048     {
16049       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16050       vat_json_init_array (&vam->json_tree);
16051     }
16052   node = vat_json_array_add (&vam->json_tree);
16053
16054   vat_json_init_object (node);
16055   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
16056   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
16057   vat_json_object_add_uint (node, "label", ntohl (mp->label));
16058   vat_json_object_add_uint (node, "path_count", count);
16059   fp = mp->path;
16060   for (i = 0; i < count; i++)
16061     {
16062       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
16063       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
16064       vat_json_object_add_uint (node, "is_local", fp->is_local);
16065       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
16066       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
16067       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
16068       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
16069       if (fp->afi == IP46_TYPE_IP4)
16070         {
16071           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
16072           vat_json_object_add_ip4 (node, "next_hop", ip4);
16073         }
16074       else if (fp->afi == IP46_TYPE_IP6)
16075         {
16076           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
16077           vat_json_object_add_ip6 (node, "next_hop", ip6);
16078         }
16079     }
16080 }
16081
16082 static int
16083 api_mpls_fib_dump (vat_main_t * vam)
16084 {
16085   vl_api_mpls_fib_dump_t *mp;
16086   vl_api_control_ping_t *mp_ping;
16087   int ret;
16088
16089   M (MPLS_FIB_DUMP, mp);
16090   S (mp);
16091
16092   /* Use a control ping for synchronization */
16093   M (CONTROL_PING, mp_ping);
16094   S (mp_ping);
16095
16096   W (ret);
16097   return ret;
16098 }
16099
16100 #define vl_api_ip_fib_details_t_endian vl_noop_handler
16101 #define vl_api_ip_fib_details_t_print vl_noop_handler
16102
16103 static void
16104 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
16105 {
16106   vat_main_t *vam = &vat_main;
16107   int count = ntohl (mp->count);
16108   vl_api_fib_path_t *fp;
16109   int i;
16110
16111   print (vam->ofp,
16112          "table-id %d, prefix %U/%d",
16113          ntohl (mp->table_id), format_ip4_address, mp->address,
16114          mp->address_length);
16115   fp = mp->path;
16116   for (i = 0; i < count; i++)
16117     {
16118       if (fp->afi == IP46_TYPE_IP6)
16119         print (vam->ofp,
16120                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16121                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16122                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16123                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16124                format_ip6_address, fp->next_hop);
16125       else if (fp->afi == IP46_TYPE_IP4)
16126         print (vam->ofp,
16127                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16128                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16129                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16130                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16131                format_ip4_address, fp->next_hop);
16132       fp++;
16133     }
16134 }
16135
16136 static void vl_api_ip_fib_details_t_handler_json
16137   (vl_api_ip_fib_details_t * mp)
16138 {
16139   vat_main_t *vam = &vat_main;
16140   int count = ntohl (mp->count);
16141   vat_json_node_t *node = NULL;
16142   struct in_addr ip4;
16143   struct in6_addr ip6;
16144   vl_api_fib_path_t *fp;
16145   int i;
16146
16147   if (VAT_JSON_ARRAY != vam->json_tree.type)
16148     {
16149       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16150       vat_json_init_array (&vam->json_tree);
16151     }
16152   node = vat_json_array_add (&vam->json_tree);
16153
16154   vat_json_init_object (node);
16155   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
16156   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
16157   vat_json_object_add_ip4 (node, "prefix", ip4);
16158   vat_json_object_add_uint (node, "mask_length", mp->address_length);
16159   vat_json_object_add_uint (node, "path_count", count);
16160   fp = mp->path;
16161   for (i = 0; i < count; i++)
16162     {
16163       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
16164       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
16165       vat_json_object_add_uint (node, "is_local", fp->is_local);
16166       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
16167       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
16168       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
16169       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
16170       if (fp->afi == IP46_TYPE_IP4)
16171         {
16172           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
16173           vat_json_object_add_ip4 (node, "next_hop", ip4);
16174         }
16175       else if (fp->afi == IP46_TYPE_IP6)
16176         {
16177           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
16178           vat_json_object_add_ip6 (node, "next_hop", ip6);
16179         }
16180     }
16181 }
16182
16183 static int
16184 api_ip_fib_dump (vat_main_t * vam)
16185 {
16186   vl_api_ip_fib_dump_t *mp;
16187   vl_api_control_ping_t *mp_ping;
16188   int ret;
16189
16190   M (IP_FIB_DUMP, mp);
16191   S (mp);
16192
16193   /* Use a control ping for synchronization */
16194   M (CONTROL_PING, mp_ping);
16195   S (mp_ping);
16196
16197   W (ret);
16198   return ret;
16199 }
16200
16201 static int
16202 api_ip_mfib_dump (vat_main_t * vam)
16203 {
16204   vl_api_ip_mfib_dump_t *mp;
16205   vl_api_control_ping_t *mp_ping;
16206   int ret;
16207
16208   M (IP_MFIB_DUMP, mp);
16209   S (mp);
16210
16211   /* Use a control ping for synchronization */
16212   M (CONTROL_PING, mp_ping);
16213   S (mp_ping);
16214
16215   W (ret);
16216   return ret;
16217 }
16218
16219 static void vl_api_ip_neighbor_details_t_handler
16220   (vl_api_ip_neighbor_details_t * mp)
16221 {
16222   vat_main_t *vam = &vat_main;
16223
16224   print (vam->ofp, "%c %U %U",
16225          (mp->is_static) ? 'S' : 'D',
16226          format_ethernet_address, &mp->mac_address,
16227          (mp->is_ipv6) ? format_ip6_address : format_ip4_address,
16228          &mp->ip_address);
16229 }
16230
16231 static void vl_api_ip_neighbor_details_t_handler_json
16232   (vl_api_ip_neighbor_details_t * mp)
16233 {
16234
16235   vat_main_t *vam = &vat_main;
16236   vat_json_node_t *node;
16237   struct in_addr ip4;
16238   struct in6_addr ip6;
16239
16240   if (VAT_JSON_ARRAY != vam->json_tree.type)
16241     {
16242       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16243       vat_json_init_array (&vam->json_tree);
16244     }
16245   node = vat_json_array_add (&vam->json_tree);
16246
16247   vat_json_init_object (node);
16248   vat_json_object_add_string_copy (node, "flag",
16249                                    (mp->is_static) ? (u8 *) "static" : (u8 *)
16250                                    "dynamic");
16251
16252   vat_json_object_add_string_copy (node, "link_layer",
16253                                    format (0, "%U", format_ethernet_address,
16254                                            &mp->mac_address));
16255
16256   if (mp->is_ipv6)
16257     {
16258       clib_memcpy (&ip6, &mp->ip_address, sizeof (ip6));
16259       vat_json_object_add_ip6 (node, "ip_address", ip6);
16260     }
16261   else
16262     {
16263       clib_memcpy (&ip4, &mp->ip_address, sizeof (ip4));
16264       vat_json_object_add_ip4 (node, "ip_address", ip4);
16265     }
16266 }
16267
16268 static int
16269 api_ip_neighbor_dump (vat_main_t * vam)
16270 {
16271   unformat_input_t *i = vam->input;
16272   vl_api_ip_neighbor_dump_t *mp;
16273   vl_api_control_ping_t *mp_ping;
16274   u8 is_ipv6 = 0;
16275   u32 sw_if_index = ~0;
16276   int ret;
16277
16278   /* Parse args required to build the message */
16279   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16280     {
16281       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16282         ;
16283       else if (unformat (i, "sw_if_index %d", &sw_if_index))
16284         ;
16285       else if (unformat (i, "ip6"))
16286         is_ipv6 = 1;
16287       else
16288         break;
16289     }
16290
16291   if (sw_if_index == ~0)
16292     {
16293       errmsg ("missing interface name or sw_if_index");
16294       return -99;
16295     }
16296
16297   M (IP_NEIGHBOR_DUMP, mp);
16298   mp->is_ipv6 = (u8) is_ipv6;
16299   mp->sw_if_index = ntohl (sw_if_index);
16300   S (mp);
16301
16302   /* Use a control ping for synchronization */
16303   M (CONTROL_PING, mp_ping);
16304   S (mp_ping);
16305
16306   W (ret);
16307   return ret;
16308 }
16309
16310 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
16311 #define vl_api_ip6_fib_details_t_print vl_noop_handler
16312
16313 static void
16314 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
16315 {
16316   vat_main_t *vam = &vat_main;
16317   int count = ntohl (mp->count);
16318   vl_api_fib_path_t *fp;
16319   int i;
16320
16321   print (vam->ofp,
16322          "table-id %d, prefix %U/%d",
16323          ntohl (mp->table_id), format_ip6_address, mp->address,
16324          mp->address_length);
16325   fp = mp->path;
16326   for (i = 0; i < count; i++)
16327     {
16328       if (fp->afi == IP46_TYPE_IP6)
16329         print (vam->ofp,
16330                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16331                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16332                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16333                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16334                format_ip6_address, fp->next_hop);
16335       else if (fp->afi == IP46_TYPE_IP4)
16336         print (vam->ofp,
16337                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16338                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16339                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16340                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16341                format_ip4_address, fp->next_hop);
16342       fp++;
16343     }
16344 }
16345
16346 static void vl_api_ip6_fib_details_t_handler_json
16347   (vl_api_ip6_fib_details_t * mp)
16348 {
16349   vat_main_t *vam = &vat_main;
16350   int count = ntohl (mp->count);
16351   vat_json_node_t *node = NULL;
16352   struct in_addr ip4;
16353   struct in6_addr ip6;
16354   vl_api_fib_path_t *fp;
16355   int i;
16356
16357   if (VAT_JSON_ARRAY != vam->json_tree.type)
16358     {
16359       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16360       vat_json_init_array (&vam->json_tree);
16361     }
16362   node = vat_json_array_add (&vam->json_tree);
16363
16364   vat_json_init_object (node);
16365   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
16366   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
16367   vat_json_object_add_ip6 (node, "prefix", ip6);
16368   vat_json_object_add_uint (node, "mask_length", mp->address_length);
16369   vat_json_object_add_uint (node, "path_count", count);
16370   fp = mp->path;
16371   for (i = 0; i < count; i++)
16372     {
16373       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
16374       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
16375       vat_json_object_add_uint (node, "is_local", fp->is_local);
16376       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
16377       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
16378       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
16379       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
16380       if (fp->afi == IP46_TYPE_IP4)
16381         {
16382           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
16383           vat_json_object_add_ip4 (node, "next_hop", ip4);
16384         }
16385       else if (fp->afi == IP46_TYPE_IP6)
16386         {
16387           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
16388           vat_json_object_add_ip6 (node, "next_hop", ip6);
16389         }
16390     }
16391 }
16392
16393 static int
16394 api_ip6_fib_dump (vat_main_t * vam)
16395 {
16396   vl_api_ip6_fib_dump_t *mp;
16397   vl_api_control_ping_t *mp_ping;
16398   int ret;
16399
16400   M (IP6_FIB_DUMP, mp);
16401   S (mp);
16402
16403   /* Use a control ping for synchronization */
16404   M (CONTROL_PING, mp_ping);
16405   S (mp_ping);
16406
16407   W (ret);
16408   return ret;
16409 }
16410
16411 static int
16412 api_ip6_mfib_dump (vat_main_t * vam)
16413 {
16414   vl_api_ip6_mfib_dump_t *mp;
16415   vl_api_control_ping_t *mp_ping;
16416   int ret;
16417
16418   M (IP6_MFIB_DUMP, mp);
16419   S (mp);
16420
16421   /* Use a control ping for synchronization */
16422   M (CONTROL_PING, mp_ping);
16423   S (mp_ping);
16424
16425   W (ret);
16426   return ret;
16427 }
16428
16429 int
16430 api_classify_table_ids (vat_main_t * vam)
16431 {
16432   vl_api_classify_table_ids_t *mp;
16433   int ret;
16434
16435   /* Construct the API message */
16436   M (CLASSIFY_TABLE_IDS, mp);
16437   mp->context = 0;
16438
16439   S (mp);
16440   W (ret);
16441   return ret;
16442 }
16443
16444 int
16445 api_classify_table_by_interface (vat_main_t * vam)
16446 {
16447   unformat_input_t *input = vam->input;
16448   vl_api_classify_table_by_interface_t *mp;
16449
16450   u32 sw_if_index = ~0;
16451   int ret;
16452   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16453     {
16454       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16455         ;
16456       else if (unformat (input, "sw_if_index %d", &sw_if_index))
16457         ;
16458       else
16459         break;
16460     }
16461   if (sw_if_index == ~0)
16462     {
16463       errmsg ("missing interface name or sw_if_index");
16464       return -99;
16465     }
16466
16467   /* Construct the API message */
16468   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
16469   mp->context = 0;
16470   mp->sw_if_index = ntohl (sw_if_index);
16471
16472   S (mp);
16473   W (ret);
16474   return ret;
16475 }
16476
16477 int
16478 api_classify_table_info (vat_main_t * vam)
16479 {
16480   unformat_input_t *input = vam->input;
16481   vl_api_classify_table_info_t *mp;
16482
16483   u32 table_id = ~0;
16484   int ret;
16485   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16486     {
16487       if (unformat (input, "table_id %d", &table_id))
16488         ;
16489       else
16490         break;
16491     }
16492   if (table_id == ~0)
16493     {
16494       errmsg ("missing table id");
16495       return -99;
16496     }
16497
16498   /* Construct the API message */
16499   M (CLASSIFY_TABLE_INFO, mp);
16500   mp->context = 0;
16501   mp->table_id = ntohl (table_id);
16502
16503   S (mp);
16504   W (ret);
16505   return ret;
16506 }
16507
16508 int
16509 api_classify_session_dump (vat_main_t * vam)
16510 {
16511   unformat_input_t *input = vam->input;
16512   vl_api_classify_session_dump_t *mp;
16513   vl_api_control_ping_t *mp_ping;
16514
16515   u32 table_id = ~0;
16516   int ret;
16517   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16518     {
16519       if (unformat (input, "table_id %d", &table_id))
16520         ;
16521       else
16522         break;
16523     }
16524   if (table_id == ~0)
16525     {
16526       errmsg ("missing table id");
16527       return -99;
16528     }
16529
16530   /* Construct the API message */
16531   M (CLASSIFY_SESSION_DUMP, mp);
16532   mp->context = 0;
16533   mp->table_id = ntohl (table_id);
16534   S (mp);
16535
16536   /* Use a control ping for synchronization */
16537   M (CONTROL_PING, mp_ping);
16538   S (mp_ping);
16539
16540   W (ret);
16541   return ret;
16542 }
16543
16544 static void
16545 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
16546 {
16547   vat_main_t *vam = &vat_main;
16548
16549   print (vam->ofp, "collector_address %U, collector_port %d, "
16550          "src_address %U, vrf_id %d, path_mtu %u, "
16551          "template_interval %u, udp_checksum %d",
16552          format_ip4_address, mp->collector_address,
16553          ntohs (mp->collector_port),
16554          format_ip4_address, mp->src_address,
16555          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
16556          ntohl (mp->template_interval), mp->udp_checksum);
16557
16558   vam->retval = 0;
16559   vam->result_ready = 1;
16560 }
16561
16562 static void
16563   vl_api_ipfix_exporter_details_t_handler_json
16564   (vl_api_ipfix_exporter_details_t * mp)
16565 {
16566   vat_main_t *vam = &vat_main;
16567   vat_json_node_t node;
16568   struct in_addr collector_address;
16569   struct in_addr src_address;
16570
16571   vat_json_init_object (&node);
16572   clib_memcpy (&collector_address, &mp->collector_address,
16573                sizeof (collector_address));
16574   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
16575   vat_json_object_add_uint (&node, "collector_port",
16576                             ntohs (mp->collector_port));
16577   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
16578   vat_json_object_add_ip4 (&node, "src_address", src_address);
16579   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
16580   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
16581   vat_json_object_add_uint (&node, "template_interval",
16582                             ntohl (mp->template_interval));
16583   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
16584
16585   vat_json_print (vam->ofp, &node);
16586   vat_json_free (&node);
16587   vam->retval = 0;
16588   vam->result_ready = 1;
16589 }
16590
16591 int
16592 api_ipfix_exporter_dump (vat_main_t * vam)
16593 {
16594   vl_api_ipfix_exporter_dump_t *mp;
16595   int ret;
16596
16597   /* Construct the API message */
16598   M (IPFIX_EXPORTER_DUMP, mp);
16599   mp->context = 0;
16600
16601   S (mp);
16602   W (ret);
16603   return ret;
16604 }
16605
16606 static int
16607 api_ipfix_classify_stream_dump (vat_main_t * vam)
16608 {
16609   vl_api_ipfix_classify_stream_dump_t *mp;
16610   int ret;
16611
16612   /* Construct the API message */
16613   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
16614   mp->context = 0;
16615
16616   S (mp);
16617   W (ret);
16618   return ret;
16619   /* NOTREACHED */
16620   return 0;
16621 }
16622
16623 static void
16624   vl_api_ipfix_classify_stream_details_t_handler
16625   (vl_api_ipfix_classify_stream_details_t * mp)
16626 {
16627   vat_main_t *vam = &vat_main;
16628   print (vam->ofp, "domain_id %d, src_port %d",
16629          ntohl (mp->domain_id), ntohs (mp->src_port));
16630   vam->retval = 0;
16631   vam->result_ready = 1;
16632 }
16633
16634 static void
16635   vl_api_ipfix_classify_stream_details_t_handler_json
16636   (vl_api_ipfix_classify_stream_details_t * mp)
16637 {
16638   vat_main_t *vam = &vat_main;
16639   vat_json_node_t node;
16640
16641   vat_json_init_object (&node);
16642   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
16643   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
16644
16645   vat_json_print (vam->ofp, &node);
16646   vat_json_free (&node);
16647   vam->retval = 0;
16648   vam->result_ready = 1;
16649 }
16650
16651 static int
16652 api_ipfix_classify_table_dump (vat_main_t * vam)
16653 {
16654   vl_api_ipfix_classify_table_dump_t *mp;
16655   vl_api_control_ping_t *mp_ping;
16656   int ret;
16657
16658   if (!vam->json_output)
16659     {
16660       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
16661              "transport_protocol");
16662     }
16663
16664   /* Construct the API message */
16665   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
16666
16667   /* send it... */
16668   S (mp);
16669
16670   /* Use a control ping for synchronization */
16671   M (CONTROL_PING, mp_ping);
16672   S (mp_ping);
16673
16674   W (ret);
16675   return ret;
16676 }
16677
16678 static void
16679   vl_api_ipfix_classify_table_details_t_handler
16680   (vl_api_ipfix_classify_table_details_t * mp)
16681 {
16682   vat_main_t *vam = &vat_main;
16683   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
16684          mp->transport_protocol);
16685 }
16686
16687 static void
16688   vl_api_ipfix_classify_table_details_t_handler_json
16689   (vl_api_ipfix_classify_table_details_t * mp)
16690 {
16691   vat_json_node_t *node = NULL;
16692   vat_main_t *vam = &vat_main;
16693
16694   if (VAT_JSON_ARRAY != vam->json_tree.type)
16695     {
16696       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16697       vat_json_init_array (&vam->json_tree);
16698     }
16699
16700   node = vat_json_array_add (&vam->json_tree);
16701   vat_json_init_object (node);
16702
16703   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
16704   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
16705   vat_json_object_add_uint (node, "transport_protocol",
16706                             mp->transport_protocol);
16707 }
16708
16709 static int
16710 api_sw_interface_span_enable_disable (vat_main_t * vam)
16711 {
16712   unformat_input_t *i = vam->input;
16713   vl_api_sw_interface_span_enable_disable_t *mp;
16714   u32 src_sw_if_index = ~0;
16715   u32 dst_sw_if_index = ~0;
16716   u8 state = 3;
16717   int ret;
16718
16719   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16720     {
16721       if (unformat
16722           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
16723         ;
16724       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
16725         ;
16726       else
16727         if (unformat
16728             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
16729         ;
16730       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
16731         ;
16732       else if (unformat (i, "disable"))
16733         state = 0;
16734       else if (unformat (i, "rx"))
16735         state = 1;
16736       else if (unformat (i, "tx"))
16737         state = 2;
16738       else if (unformat (i, "both"))
16739         state = 3;
16740       else
16741         break;
16742     }
16743
16744   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
16745
16746   mp->sw_if_index_from = htonl (src_sw_if_index);
16747   mp->sw_if_index_to = htonl (dst_sw_if_index);
16748   mp->state = state;
16749
16750   S (mp);
16751   W (ret);
16752   return ret;
16753 }
16754
16755 static void
16756 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
16757                                             * mp)
16758 {
16759   vat_main_t *vam = &vat_main;
16760   u8 *sw_if_from_name = 0;
16761   u8 *sw_if_to_name = 0;
16762   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
16763   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
16764   char *states[] = { "none", "rx", "tx", "both" };
16765   hash_pair_t *p;
16766
16767   /* *INDENT-OFF* */
16768   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
16769   ({
16770     if ((u32) p->value[0] == sw_if_index_from)
16771       {
16772         sw_if_from_name = (u8 *)(p->key);
16773         if (sw_if_to_name)
16774           break;
16775       }
16776     if ((u32) p->value[0] == sw_if_index_to)
16777       {
16778         sw_if_to_name = (u8 *)(p->key);
16779         if (sw_if_from_name)
16780           break;
16781       }
16782   }));
16783   /* *INDENT-ON* */
16784   print (vam->ofp, "%20s => %20s (%s)",
16785          sw_if_from_name, sw_if_to_name, states[mp->state]);
16786 }
16787
16788 static void
16789   vl_api_sw_interface_span_details_t_handler_json
16790   (vl_api_sw_interface_span_details_t * mp)
16791 {
16792   vat_main_t *vam = &vat_main;
16793   vat_json_node_t *node = NULL;
16794   u8 *sw_if_from_name = 0;
16795   u8 *sw_if_to_name = 0;
16796   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
16797   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
16798   hash_pair_t *p;
16799
16800   /* *INDENT-OFF* */
16801   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
16802   ({
16803     if ((u32) p->value[0] == sw_if_index_from)
16804       {
16805         sw_if_from_name = (u8 *)(p->key);
16806         if (sw_if_to_name)
16807           break;
16808       }
16809     if ((u32) p->value[0] == sw_if_index_to)
16810       {
16811         sw_if_to_name = (u8 *)(p->key);
16812         if (sw_if_from_name)
16813           break;
16814       }
16815   }));
16816   /* *INDENT-ON* */
16817
16818   if (VAT_JSON_ARRAY != vam->json_tree.type)
16819     {
16820       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16821       vat_json_init_array (&vam->json_tree);
16822     }
16823   node = vat_json_array_add (&vam->json_tree);
16824
16825   vat_json_init_object (node);
16826   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
16827   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
16828   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
16829   if (0 != sw_if_to_name)
16830     {
16831       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
16832     }
16833   vat_json_object_add_uint (node, "state", mp->state);
16834 }
16835
16836 static int
16837 api_sw_interface_span_dump (vat_main_t * vam)
16838 {
16839   vl_api_sw_interface_span_dump_t *mp;
16840   vl_api_control_ping_t *mp_ping;
16841   int ret;
16842
16843   M (SW_INTERFACE_SPAN_DUMP, mp);
16844   S (mp);
16845
16846   /* Use a control ping for synchronization */
16847   M (CONTROL_PING, mp_ping);
16848   S (mp_ping);
16849
16850   W (ret);
16851   return ret;
16852 }
16853
16854 int
16855 api_pg_create_interface (vat_main_t * vam)
16856 {
16857   unformat_input_t *input = vam->input;
16858   vl_api_pg_create_interface_t *mp;
16859
16860   u32 if_id = ~0;
16861   int ret;
16862   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16863     {
16864       if (unformat (input, "if_id %d", &if_id))
16865         ;
16866       else
16867         break;
16868     }
16869   if (if_id == ~0)
16870     {
16871       errmsg ("missing pg interface index");
16872       return -99;
16873     }
16874
16875   /* Construct the API message */
16876   M (PG_CREATE_INTERFACE, mp);
16877   mp->context = 0;
16878   mp->interface_id = ntohl (if_id);
16879
16880   S (mp);
16881   W (ret);
16882   return ret;
16883 }
16884
16885 int
16886 api_pg_capture (vat_main_t * vam)
16887 {
16888   unformat_input_t *input = vam->input;
16889   vl_api_pg_capture_t *mp;
16890
16891   u32 if_id = ~0;
16892   u8 enable = 1;
16893   u32 count = 1;
16894   u8 pcap_file_set = 0;
16895   u8 *pcap_file = 0;
16896   int ret;
16897   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16898     {
16899       if (unformat (input, "if_id %d", &if_id))
16900         ;
16901       else if (unformat (input, "pcap %s", &pcap_file))
16902         pcap_file_set = 1;
16903       else if (unformat (input, "count %d", &count))
16904         ;
16905       else if (unformat (input, "disable"))
16906         enable = 0;
16907       else
16908         break;
16909     }
16910   if (if_id == ~0)
16911     {
16912       errmsg ("missing pg interface index");
16913       return -99;
16914     }
16915   if (pcap_file_set > 0)
16916     {
16917       if (vec_len (pcap_file) > 255)
16918         {
16919           errmsg ("pcap file name is too long");
16920           return -99;
16921         }
16922     }
16923
16924   u32 name_len = vec_len (pcap_file);
16925   /* Construct the API message */
16926   M (PG_CAPTURE, mp);
16927   mp->context = 0;
16928   mp->interface_id = ntohl (if_id);
16929   mp->is_enabled = enable;
16930   mp->count = ntohl (count);
16931   mp->pcap_name_length = ntohl (name_len);
16932   if (pcap_file_set != 0)
16933     {
16934       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
16935     }
16936   vec_free (pcap_file);
16937
16938   S (mp);
16939   W (ret);
16940   return ret;
16941 }
16942
16943 int
16944 api_pg_enable_disable (vat_main_t * vam)
16945 {
16946   unformat_input_t *input = vam->input;
16947   vl_api_pg_enable_disable_t *mp;
16948
16949   u8 enable = 1;
16950   u8 stream_name_set = 0;
16951   u8 *stream_name = 0;
16952   int ret;
16953   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16954     {
16955       if (unformat (input, "stream %s", &stream_name))
16956         stream_name_set = 1;
16957       else if (unformat (input, "disable"))
16958         enable = 0;
16959       else
16960         break;
16961     }
16962
16963   if (stream_name_set > 0)
16964     {
16965       if (vec_len (stream_name) > 255)
16966         {
16967           errmsg ("stream name too long");
16968           return -99;
16969         }
16970     }
16971
16972   u32 name_len = vec_len (stream_name);
16973   /* Construct the API message */
16974   M (PG_ENABLE_DISABLE, mp);
16975   mp->context = 0;
16976   mp->is_enabled = enable;
16977   if (stream_name_set != 0)
16978     {
16979       mp->stream_name_length = ntohl (name_len);
16980       clib_memcpy (mp->stream_name, stream_name, name_len);
16981     }
16982   vec_free (stream_name);
16983
16984   S (mp);
16985   W (ret);
16986   return ret;
16987 }
16988
16989 int
16990 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
16991 {
16992   unformat_input_t *input = vam->input;
16993   vl_api_ip_source_and_port_range_check_add_del_t *mp;
16994
16995   u16 *low_ports = 0;
16996   u16 *high_ports = 0;
16997   u16 this_low;
16998   u16 this_hi;
16999   ip4_address_t ip4_addr;
17000   ip6_address_t ip6_addr;
17001   u32 length;
17002   u32 tmp, tmp2;
17003   u8 prefix_set = 0;
17004   u32 vrf_id = ~0;
17005   u8 is_add = 1;
17006   u8 is_ipv6 = 0;
17007   int ret;
17008
17009   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17010     {
17011       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
17012         {
17013           prefix_set = 1;
17014         }
17015       else
17016         if (unformat
17017             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
17018         {
17019           prefix_set = 1;
17020           is_ipv6 = 1;
17021         }
17022       else if (unformat (input, "vrf %d", &vrf_id))
17023         ;
17024       else if (unformat (input, "del"))
17025         is_add = 0;
17026       else if (unformat (input, "port %d", &tmp))
17027         {
17028           if (tmp == 0 || tmp > 65535)
17029             {
17030               errmsg ("port %d out of range", tmp);
17031               return -99;
17032             }
17033           this_low = tmp;
17034           this_hi = this_low + 1;
17035           vec_add1 (low_ports, this_low);
17036           vec_add1 (high_ports, this_hi);
17037         }
17038       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
17039         {
17040           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
17041             {
17042               errmsg ("incorrect range parameters");
17043               return -99;
17044             }
17045           this_low = tmp;
17046           /* Note: in debug CLI +1 is added to high before
17047              passing to real fn that does "the work"
17048              (ip_source_and_port_range_check_add_del).
17049              This fn is a wrapper around the binary API fn a
17050              control plane will call, which expects this increment
17051              to have occurred. Hence letting the binary API control
17052              plane fn do the increment for consistency between VAT
17053              and other control planes.
17054            */
17055           this_hi = tmp2;
17056           vec_add1 (low_ports, this_low);
17057           vec_add1 (high_ports, this_hi);
17058         }
17059       else
17060         break;
17061     }
17062
17063   if (prefix_set == 0)
17064     {
17065       errmsg ("<address>/<mask> not specified");
17066       return -99;
17067     }
17068
17069   if (vrf_id == ~0)
17070     {
17071       errmsg ("VRF ID required, not specified");
17072       return -99;
17073     }
17074
17075   if (vrf_id == 0)
17076     {
17077       errmsg
17078         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
17079       return -99;
17080     }
17081
17082   if (vec_len (low_ports) == 0)
17083     {
17084       errmsg ("At least one port or port range required");
17085       return -99;
17086     }
17087
17088   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
17089
17090   mp->is_add = is_add;
17091
17092   if (is_ipv6)
17093     {
17094       mp->is_ipv6 = 1;
17095       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
17096     }
17097   else
17098     {
17099       mp->is_ipv6 = 0;
17100       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
17101     }
17102
17103   mp->mask_length = length;
17104   mp->number_of_ranges = vec_len (low_ports);
17105
17106   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
17107   vec_free (low_ports);
17108
17109   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
17110   vec_free (high_ports);
17111
17112   mp->vrf_id = ntohl (vrf_id);
17113
17114   S (mp);
17115   W (ret);
17116   return ret;
17117 }
17118
17119 int
17120 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
17121 {
17122   unformat_input_t *input = vam->input;
17123   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
17124   u32 sw_if_index = ~0;
17125   int vrf_set = 0;
17126   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
17127   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
17128   u8 is_add = 1;
17129   int ret;
17130
17131   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17132     {
17133       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17134         ;
17135       else if (unformat (input, "sw_if_index %d", &sw_if_index))
17136         ;
17137       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
17138         vrf_set = 1;
17139       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
17140         vrf_set = 1;
17141       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
17142         vrf_set = 1;
17143       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
17144         vrf_set = 1;
17145       else if (unformat (input, "del"))
17146         is_add = 0;
17147       else
17148         break;
17149     }
17150
17151   if (sw_if_index == ~0)
17152     {
17153       errmsg ("Interface required but not specified");
17154       return -99;
17155     }
17156
17157   if (vrf_set == 0)
17158     {
17159       errmsg ("VRF ID required but not specified");
17160       return -99;
17161     }
17162
17163   if (tcp_out_vrf_id == 0
17164       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
17165     {
17166       errmsg
17167         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
17168       return -99;
17169     }
17170
17171   /* Construct the API message */
17172   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
17173
17174   mp->sw_if_index = ntohl (sw_if_index);
17175   mp->is_add = is_add;
17176   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
17177   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
17178   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
17179   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
17180
17181   /* send it... */
17182   S (mp);
17183
17184   /* Wait for a reply... */
17185   W (ret);
17186   return ret;
17187 }
17188
17189 static int
17190 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
17191 {
17192   unformat_input_t *i = vam->input;
17193   vl_api_ipsec_gre_add_del_tunnel_t *mp;
17194   u32 local_sa_id = 0;
17195   u32 remote_sa_id = 0;
17196   ip4_address_t src_address;
17197   ip4_address_t dst_address;
17198   u8 is_add = 1;
17199   int ret;
17200
17201   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17202     {
17203       if (unformat (i, "local_sa %d", &local_sa_id))
17204         ;
17205       else if (unformat (i, "remote_sa %d", &remote_sa_id))
17206         ;
17207       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
17208         ;
17209       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
17210         ;
17211       else if (unformat (i, "del"))
17212         is_add = 0;
17213       else
17214         {
17215           clib_warning ("parse error '%U'", format_unformat_error, i);
17216           return -99;
17217         }
17218     }
17219
17220   M (IPSEC_GRE_ADD_DEL_TUNNEL, mp);
17221
17222   mp->local_sa_id = ntohl (local_sa_id);
17223   mp->remote_sa_id = ntohl (remote_sa_id);
17224   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
17225   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
17226   mp->is_add = is_add;
17227
17228   S (mp);
17229   W (ret);
17230   return ret;
17231 }
17232
17233 static int
17234 api_punt (vat_main_t * vam)
17235 {
17236   unformat_input_t *i = vam->input;
17237   vl_api_punt_t *mp;
17238   u32 ipv = ~0;
17239   u32 protocol = ~0;
17240   u32 port = ~0;
17241   int is_add = 1;
17242   int ret;
17243
17244   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17245     {
17246       if (unformat (i, "ip %d", &ipv))
17247         ;
17248       else if (unformat (i, "protocol %d", &protocol))
17249         ;
17250       else if (unformat (i, "port %d", &port))
17251         ;
17252       else if (unformat (i, "del"))
17253         is_add = 0;
17254       else
17255         {
17256           clib_warning ("parse error '%U'", format_unformat_error, i);
17257           return -99;
17258         }
17259     }
17260
17261   M (PUNT, mp);
17262
17263   mp->is_add = (u8) is_add;
17264   mp->ipv = (u8) ipv;
17265   mp->l4_protocol = (u8) protocol;
17266   mp->l4_port = htons ((u16) port);
17267
17268   S (mp);
17269   W (ret);
17270   return ret;
17271 }
17272
17273 static void vl_api_ipsec_gre_tunnel_details_t_handler
17274   (vl_api_ipsec_gre_tunnel_details_t * mp)
17275 {
17276   vat_main_t *vam = &vat_main;
17277
17278   print (vam->ofp, "%11d%15U%15U%14d%14d",
17279          ntohl (mp->sw_if_index),
17280          format_ip4_address, &mp->src_address,
17281          format_ip4_address, &mp->dst_address,
17282          ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
17283 }
17284
17285 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
17286   (vl_api_ipsec_gre_tunnel_details_t * mp)
17287 {
17288   vat_main_t *vam = &vat_main;
17289   vat_json_node_t *node = NULL;
17290   struct in_addr ip4;
17291
17292   if (VAT_JSON_ARRAY != vam->json_tree.type)
17293     {
17294       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17295       vat_json_init_array (&vam->json_tree);
17296     }
17297   node = vat_json_array_add (&vam->json_tree);
17298
17299   vat_json_init_object (node);
17300   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
17301   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
17302   vat_json_object_add_ip4 (node, "src_address", ip4);
17303   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
17304   vat_json_object_add_ip4 (node, "dst_address", ip4);
17305   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
17306   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
17307 }
17308
17309 static int
17310 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
17311 {
17312   unformat_input_t *i = vam->input;
17313   vl_api_ipsec_gre_tunnel_dump_t *mp;
17314   vl_api_control_ping_t *mp_ping;
17315   u32 sw_if_index;
17316   u8 sw_if_index_set = 0;
17317   int ret;
17318
17319   /* Parse args required to build the message */
17320   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17321     {
17322       if (unformat (i, "sw_if_index %d", &sw_if_index))
17323         sw_if_index_set = 1;
17324       else
17325         break;
17326     }
17327
17328   if (sw_if_index_set == 0)
17329     {
17330       sw_if_index = ~0;
17331     }
17332
17333   if (!vam->json_output)
17334     {
17335       print (vam->ofp, "%11s%15s%15s%14s%14s",
17336              "sw_if_index", "src_address", "dst_address",
17337              "local_sa_id", "remote_sa_id");
17338     }
17339
17340   /* Get list of gre-tunnel interfaces */
17341   M (IPSEC_GRE_TUNNEL_DUMP, mp);
17342
17343   mp->sw_if_index = htonl (sw_if_index);
17344
17345   S (mp);
17346
17347   /* Use a control ping for synchronization */
17348   M (CONTROL_PING, mp_ping);
17349   S (mp_ping);
17350
17351   W (ret);
17352   return ret;
17353 }
17354
17355 static int
17356 api_delete_subif (vat_main_t * vam)
17357 {
17358   unformat_input_t *i = vam->input;
17359   vl_api_delete_subif_t *mp;
17360   u32 sw_if_index = ~0;
17361   int ret;
17362
17363   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17364     {
17365       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17366         ;
17367       if (unformat (i, "sw_if_index %d", &sw_if_index))
17368         ;
17369       else
17370         break;
17371     }
17372
17373   if (sw_if_index == ~0)
17374     {
17375       errmsg ("missing sw_if_index");
17376       return -99;
17377     }
17378
17379   /* Construct the API message */
17380   M (DELETE_SUBIF, mp);
17381   mp->sw_if_index = ntohl (sw_if_index);
17382
17383   S (mp);
17384   W (ret);
17385   return ret;
17386 }
17387
17388 #define foreach_pbb_vtr_op      \
17389 _("disable",  L2_VTR_DISABLED)  \
17390 _("pop",  L2_VTR_POP_2)         \
17391 _("push",  L2_VTR_PUSH_2)
17392
17393 static int
17394 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
17395 {
17396   unformat_input_t *i = vam->input;
17397   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
17398   u32 sw_if_index = ~0, vtr_op = ~0;
17399   u16 outer_tag = ~0;
17400   u8 dmac[6], smac[6];
17401   u8 dmac_set = 0, smac_set = 0;
17402   u16 vlanid = 0;
17403   u32 sid = ~0;
17404   u32 tmp;
17405   int ret;
17406
17407   /* Shut up coverity */
17408   memset (dmac, 0, sizeof (dmac));
17409   memset (smac, 0, sizeof (smac));
17410
17411   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17412     {
17413       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17414         ;
17415       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17416         ;
17417       else if (unformat (i, "vtr_op %d", &vtr_op))
17418         ;
17419 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
17420       foreach_pbb_vtr_op
17421 #undef _
17422         else if (unformat (i, "translate_pbb_stag"))
17423         {
17424           if (unformat (i, "%d", &tmp))
17425             {
17426               vtr_op = L2_VTR_TRANSLATE_2_1;
17427               outer_tag = tmp;
17428             }
17429           else
17430             {
17431               errmsg
17432                 ("translate_pbb_stag operation requires outer tag definition");
17433               return -99;
17434             }
17435         }
17436       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
17437         dmac_set++;
17438       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
17439         smac_set++;
17440       else if (unformat (i, "sid %d", &sid))
17441         ;
17442       else if (unformat (i, "vlanid %d", &tmp))
17443         vlanid = tmp;
17444       else
17445         {
17446           clib_warning ("parse error '%U'", format_unformat_error, i);
17447           return -99;
17448         }
17449     }
17450
17451   if ((sw_if_index == ~0) || (vtr_op == ~0))
17452     {
17453       errmsg ("missing sw_if_index or vtr operation");
17454       return -99;
17455     }
17456   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
17457       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
17458     {
17459       errmsg
17460         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
17461       return -99;
17462     }
17463
17464   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
17465   mp->sw_if_index = ntohl (sw_if_index);
17466   mp->vtr_op = ntohl (vtr_op);
17467   mp->outer_tag = ntohs (outer_tag);
17468   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
17469   clib_memcpy (mp->b_smac, smac, sizeof (smac));
17470   mp->b_vlanid = ntohs (vlanid);
17471   mp->i_sid = ntohl (sid);
17472
17473   S (mp);
17474   W (ret);
17475   return ret;
17476 }
17477
17478 static int
17479 api_flow_classify_set_interface (vat_main_t * vam)
17480 {
17481   unformat_input_t *i = vam->input;
17482   vl_api_flow_classify_set_interface_t *mp;
17483   u32 sw_if_index;
17484   int sw_if_index_set;
17485   u32 ip4_table_index = ~0;
17486   u32 ip6_table_index = ~0;
17487   u8 is_add = 1;
17488   int ret;
17489
17490   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17491     {
17492       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17493         sw_if_index_set = 1;
17494       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17495         sw_if_index_set = 1;
17496       else if (unformat (i, "del"))
17497         is_add = 0;
17498       else if (unformat (i, "ip4-table %d", &ip4_table_index))
17499         ;
17500       else if (unformat (i, "ip6-table %d", &ip6_table_index))
17501         ;
17502       else
17503         {
17504           clib_warning ("parse error '%U'", format_unformat_error, i);
17505           return -99;
17506         }
17507     }
17508
17509   if (sw_if_index_set == 0)
17510     {
17511       errmsg ("missing interface name or sw_if_index");
17512       return -99;
17513     }
17514
17515   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
17516
17517   mp->sw_if_index = ntohl (sw_if_index);
17518   mp->ip4_table_index = ntohl (ip4_table_index);
17519   mp->ip6_table_index = ntohl (ip6_table_index);
17520   mp->is_add = is_add;
17521
17522   S (mp);
17523   W (ret);
17524   return ret;
17525 }
17526
17527 static int
17528 api_flow_classify_dump (vat_main_t * vam)
17529 {
17530   unformat_input_t *i = vam->input;
17531   vl_api_flow_classify_dump_t *mp;
17532   vl_api_control_ping_t *mp_ping;
17533   u8 type = FLOW_CLASSIFY_N_TABLES;
17534   int ret;
17535
17536   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
17537     ;
17538   else
17539     {
17540       errmsg ("classify table type must be specified");
17541       return -99;
17542     }
17543
17544   if (!vam->json_output)
17545     {
17546       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
17547     }
17548
17549   M (FLOW_CLASSIFY_DUMP, mp);
17550   mp->type = type;
17551   /* send it... */
17552   S (mp);
17553
17554   /* Use a control ping for synchronization */
17555   M (CONTROL_PING, mp_ping);
17556   S (mp_ping);
17557
17558   /* Wait for a reply... */
17559   W (ret);
17560   return ret;
17561 }
17562
17563 static int
17564 api_feature_enable_disable (vat_main_t * vam)
17565 {
17566   unformat_input_t *i = vam->input;
17567   vl_api_feature_enable_disable_t *mp;
17568   u8 *arc_name = 0;
17569   u8 *feature_name = 0;
17570   u32 sw_if_index = ~0;
17571   u8 enable = 1;
17572   int ret;
17573
17574   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17575     {
17576       if (unformat (i, "arc_name %s", &arc_name))
17577         ;
17578       else if (unformat (i, "feature_name %s", &feature_name))
17579         ;
17580       else
17581         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17582         ;
17583       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17584         ;
17585       else if (unformat (i, "disable"))
17586         enable = 0;
17587       else
17588         break;
17589     }
17590
17591   if (arc_name == 0)
17592     {
17593       errmsg ("missing arc name");
17594       return -99;
17595     }
17596   if (vec_len (arc_name) > 63)
17597     {
17598       errmsg ("arc name too long");
17599     }
17600
17601   if (feature_name == 0)
17602     {
17603       errmsg ("missing feature name");
17604       return -99;
17605     }
17606   if (vec_len (feature_name) > 63)
17607     {
17608       errmsg ("feature name too long");
17609     }
17610
17611   if (sw_if_index == ~0)
17612     {
17613       errmsg ("missing interface name or sw_if_index");
17614       return -99;
17615     }
17616
17617   /* Construct the API message */
17618   M (FEATURE_ENABLE_DISABLE, mp);
17619   mp->sw_if_index = ntohl (sw_if_index);
17620   mp->enable = enable;
17621   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
17622   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
17623   vec_free (arc_name);
17624   vec_free (feature_name);
17625
17626   S (mp);
17627   W (ret);
17628   return ret;
17629 }
17630
17631 static int
17632 api_sw_interface_tag_add_del (vat_main_t * vam)
17633 {
17634   unformat_input_t *i = vam->input;
17635   vl_api_sw_interface_tag_add_del_t *mp;
17636   u32 sw_if_index = ~0;
17637   u8 *tag = 0;
17638   u8 enable = 1;
17639   int ret;
17640
17641   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17642     {
17643       if (unformat (i, "tag %s", &tag))
17644         ;
17645       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17646         ;
17647       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17648         ;
17649       else if (unformat (i, "del"))
17650         enable = 0;
17651       else
17652         break;
17653     }
17654
17655   if (sw_if_index == ~0)
17656     {
17657       errmsg ("missing interface name or sw_if_index");
17658       return -99;
17659     }
17660
17661   if (enable && (tag == 0))
17662     {
17663       errmsg ("no tag specified");
17664       return -99;
17665     }
17666
17667   /* Construct the API message */
17668   M (SW_INTERFACE_TAG_ADD_DEL, mp);
17669   mp->sw_if_index = ntohl (sw_if_index);
17670   mp->is_add = enable;
17671   if (enable)
17672     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
17673   vec_free (tag);
17674
17675   S (mp);
17676   W (ret);
17677   return ret;
17678 }
17679
17680 static void vl_api_l2_xconnect_details_t_handler
17681   (vl_api_l2_xconnect_details_t * mp)
17682 {
17683   vat_main_t *vam = &vat_main;
17684
17685   print (vam->ofp, "%15d%15d",
17686          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
17687 }
17688
17689 static void vl_api_l2_xconnect_details_t_handler_json
17690   (vl_api_l2_xconnect_details_t * mp)
17691 {
17692   vat_main_t *vam = &vat_main;
17693   vat_json_node_t *node = NULL;
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, "rx_sw_if_index",
17704                             ntohl (mp->rx_sw_if_index));
17705   vat_json_object_add_uint (node, "tx_sw_if_index",
17706                             ntohl (mp->tx_sw_if_index));
17707 }
17708
17709 static int
17710 api_l2_xconnect_dump (vat_main_t * vam)
17711 {
17712   vl_api_l2_xconnect_dump_t *mp;
17713   vl_api_control_ping_t *mp_ping;
17714   int ret;
17715
17716   if (!vam->json_output)
17717     {
17718       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
17719     }
17720
17721   M (L2_XCONNECT_DUMP, mp);
17722
17723   S (mp);
17724
17725   /* Use a control ping for synchronization */
17726   M (CONTROL_PING, mp_ping);
17727   S (mp_ping);
17728
17729   W (ret);
17730   return ret;
17731 }
17732
17733 static int
17734 api_sw_interface_set_mtu (vat_main_t * vam)
17735 {
17736   unformat_input_t *i = vam->input;
17737   vl_api_sw_interface_set_mtu_t *mp;
17738   u32 sw_if_index = ~0;
17739   u32 mtu = 0;
17740   int ret;
17741
17742   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17743     {
17744       if (unformat (i, "mtu %d", &mtu))
17745         ;
17746       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17747         ;
17748       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17749         ;
17750       else
17751         break;
17752     }
17753
17754   if (sw_if_index == ~0)
17755     {
17756       errmsg ("missing interface name or sw_if_index");
17757       return -99;
17758     }
17759
17760   if (mtu == 0)
17761     {
17762       errmsg ("no mtu specified");
17763       return -99;
17764     }
17765
17766   /* Construct the API message */
17767   M (SW_INTERFACE_SET_MTU, mp);
17768   mp->sw_if_index = ntohl (sw_if_index);
17769   mp->mtu = ntohs ((u16) mtu);
17770
17771   S (mp);
17772   W (ret);
17773   return ret;
17774 }
17775
17776
17777 static int
17778 q_or_quit (vat_main_t * vam)
17779 {
17780 #if VPP_API_TEST_BUILTIN == 0
17781   longjmp (vam->jump_buf, 1);
17782 #endif
17783   return 0;                     /* not so much */
17784 }
17785
17786 static int
17787 q (vat_main_t * vam)
17788 {
17789   return q_or_quit (vam);
17790 }
17791
17792 static int
17793 quit (vat_main_t * vam)
17794 {
17795   return q_or_quit (vam);
17796 }
17797
17798 static int
17799 comment (vat_main_t * vam)
17800 {
17801   return 0;
17802 }
17803
17804 static int
17805 cmd_cmp (void *a1, void *a2)
17806 {
17807   u8 **c1 = a1;
17808   u8 **c2 = a2;
17809
17810   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
17811 }
17812
17813 static int
17814 help (vat_main_t * vam)
17815 {
17816   u8 **cmds = 0;
17817   u8 *name = 0;
17818   hash_pair_t *p;
17819   unformat_input_t *i = vam->input;
17820   int j;
17821
17822   if (unformat (i, "%s", &name))
17823     {
17824       uword *hs;
17825
17826       vec_add1 (name, 0);
17827
17828       hs = hash_get_mem (vam->help_by_name, name);
17829       if (hs)
17830         print (vam->ofp, "usage: %s %s", name, hs[0]);
17831       else
17832         print (vam->ofp, "No such msg / command '%s'", name);
17833       vec_free (name);
17834       return 0;
17835     }
17836
17837   print (vam->ofp, "Help is available for the following:");
17838
17839     /* *INDENT-OFF* */
17840     hash_foreach_pair (p, vam->function_by_name,
17841     ({
17842       vec_add1 (cmds, (u8 *)(p->key));
17843     }));
17844     /* *INDENT-ON* */
17845
17846   vec_sort_with_function (cmds, cmd_cmp);
17847
17848   for (j = 0; j < vec_len (cmds); j++)
17849     print (vam->ofp, "%s", cmds[j]);
17850
17851   vec_free (cmds);
17852   return 0;
17853 }
17854
17855 static int
17856 set (vat_main_t * vam)
17857 {
17858   u8 *name = 0, *value = 0;
17859   unformat_input_t *i = vam->input;
17860
17861   if (unformat (i, "%s", &name))
17862     {
17863       /* The input buffer is a vector, not a string. */
17864       value = vec_dup (i->buffer);
17865       vec_delete (value, i->index, 0);
17866       /* Almost certainly has a trailing newline */
17867       if (value[vec_len (value) - 1] == '\n')
17868         value[vec_len (value) - 1] = 0;
17869       /* Make sure it's a proper string, one way or the other */
17870       vec_add1 (value, 0);
17871       (void) clib_macro_set_value (&vam->macro_main,
17872                                    (char *) name, (char *) value);
17873     }
17874   else
17875     errmsg ("usage: set <name> <value>");
17876
17877   vec_free (name);
17878   vec_free (value);
17879   return 0;
17880 }
17881
17882 static int
17883 unset (vat_main_t * vam)
17884 {
17885   u8 *name = 0;
17886
17887   if (unformat (vam->input, "%s", &name))
17888     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
17889       errmsg ("unset: %s wasn't set", name);
17890   vec_free (name);
17891   return 0;
17892 }
17893
17894 typedef struct
17895 {
17896   u8 *name;
17897   u8 *value;
17898 } macro_sort_t;
17899
17900
17901 static int
17902 macro_sort_cmp (void *a1, void *a2)
17903 {
17904   macro_sort_t *s1 = a1;
17905   macro_sort_t *s2 = a2;
17906
17907   return strcmp ((char *) (s1->name), (char *) (s2->name));
17908 }
17909
17910 static int
17911 dump_macro_table (vat_main_t * vam)
17912 {
17913   macro_sort_t *sort_me = 0, *sm;
17914   int i;
17915   hash_pair_t *p;
17916
17917     /* *INDENT-OFF* */
17918     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
17919     ({
17920       vec_add2 (sort_me, sm, 1);
17921       sm->name = (u8 *)(p->key);
17922       sm->value = (u8 *) (p->value[0]);
17923     }));
17924     /* *INDENT-ON* */
17925
17926   vec_sort_with_function (sort_me, macro_sort_cmp);
17927
17928   if (vec_len (sort_me))
17929     print (vam->ofp, "%-15s%s", "Name", "Value");
17930   else
17931     print (vam->ofp, "The macro table is empty...");
17932
17933   for (i = 0; i < vec_len (sort_me); i++)
17934     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
17935   return 0;
17936 }
17937
17938 static int
17939 dump_node_table (vat_main_t * vam)
17940 {
17941   int i, j;
17942   vlib_node_t *node, *next_node;
17943
17944   if (vec_len (vam->graph_nodes) == 0)
17945     {
17946       print (vam->ofp, "Node table empty, issue get_node_graph...");
17947       return 0;
17948     }
17949
17950   for (i = 0; i < vec_len (vam->graph_nodes); i++)
17951     {
17952       node = vam->graph_nodes[i];
17953       print (vam->ofp, "[%d] %s", i, node->name);
17954       for (j = 0; j < vec_len (node->next_nodes); j++)
17955         {
17956           if (node->next_nodes[j] != ~0)
17957             {
17958               next_node = vam->graph_nodes[node->next_nodes[j]];
17959               print (vam->ofp, "  [%d] %s", j, next_node->name);
17960             }
17961         }
17962     }
17963   return 0;
17964 }
17965
17966 static int
17967 value_sort_cmp (void *a1, void *a2)
17968 {
17969   name_sort_t *n1 = a1;
17970   name_sort_t *n2 = a2;
17971
17972   if (n1->value < n2->value)
17973     return -1;
17974   if (n1->value > n2->value)
17975     return 1;
17976   return 0;
17977 }
17978
17979
17980 static int
17981 dump_msg_api_table (vat_main_t * vam)
17982 {
17983   api_main_t *am = &api_main;
17984   name_sort_t *nses = 0, *ns;
17985   hash_pair_t *hp;
17986   int i;
17987
17988   /* *INDENT-OFF* */
17989   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
17990   ({
17991     vec_add2 (nses, ns, 1);
17992     ns->name = (u8 *)(hp->key);
17993     ns->value = (u32) hp->value[0];
17994   }));
17995   /* *INDENT-ON* */
17996
17997   vec_sort_with_function (nses, value_sort_cmp);
17998
17999   for (i = 0; i < vec_len (nses); i++)
18000     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
18001   vec_free (nses);
18002   return 0;
18003 }
18004
18005 static int
18006 get_msg_id (vat_main_t * vam)
18007 {
18008   u8 *name_and_crc;
18009   u32 message_index;
18010
18011   if (unformat (vam->input, "%s", &name_and_crc))
18012     {
18013       message_index = vl_api_get_msg_index (name_and_crc);
18014       if (message_index == ~0)
18015         {
18016           print (vam->ofp, " '%s' not found", name_and_crc);
18017           return 0;
18018         }
18019       print (vam->ofp, " '%s' has message index %d",
18020              name_and_crc, message_index);
18021       return 0;
18022     }
18023   errmsg ("name_and_crc required...");
18024   return 0;
18025 }
18026
18027 static int
18028 search_node_table (vat_main_t * vam)
18029 {
18030   unformat_input_t *line_input = vam->input;
18031   u8 *node_to_find;
18032   int j;
18033   vlib_node_t *node, *next_node;
18034   uword *p;
18035
18036   if (vam->graph_node_index_by_name == 0)
18037     {
18038       print (vam->ofp, "Node table empty, issue get_node_graph...");
18039       return 0;
18040     }
18041
18042   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
18043     {
18044       if (unformat (line_input, "%s", &node_to_find))
18045         {
18046           vec_add1 (node_to_find, 0);
18047           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
18048           if (p == 0)
18049             {
18050               print (vam->ofp, "%s not found...", node_to_find);
18051               goto out;
18052             }
18053           node = vam->graph_nodes[p[0]];
18054           print (vam->ofp, "[%d] %s", p[0], node->name);
18055           for (j = 0; j < vec_len (node->next_nodes); j++)
18056             {
18057               if (node->next_nodes[j] != ~0)
18058                 {
18059                   next_node = vam->graph_nodes[node->next_nodes[j]];
18060                   print (vam->ofp, "  [%d] %s", j, next_node->name);
18061                 }
18062             }
18063         }
18064
18065       else
18066         {
18067           clib_warning ("parse error '%U'", format_unformat_error,
18068                         line_input);
18069           return -99;
18070         }
18071
18072     out:
18073       vec_free (node_to_find);
18074
18075     }
18076
18077   return 0;
18078 }
18079
18080
18081 static int
18082 script (vat_main_t * vam)
18083 {
18084 #if (VPP_API_TEST_BUILTIN==0)
18085   u8 *s = 0;
18086   char *save_current_file;
18087   unformat_input_t save_input;
18088   jmp_buf save_jump_buf;
18089   u32 save_line_number;
18090
18091   FILE *new_fp, *save_ifp;
18092
18093   if (unformat (vam->input, "%s", &s))
18094     {
18095       new_fp = fopen ((char *) s, "r");
18096       if (new_fp == 0)
18097         {
18098           errmsg ("Couldn't open script file %s", s);
18099           vec_free (s);
18100           return -99;
18101         }
18102     }
18103   else
18104     {
18105       errmsg ("Missing script name");
18106       return -99;
18107     }
18108
18109   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
18110   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
18111   save_ifp = vam->ifp;
18112   save_line_number = vam->input_line_number;
18113   save_current_file = (char *) vam->current_file;
18114
18115   vam->input_line_number = 0;
18116   vam->ifp = new_fp;
18117   vam->current_file = s;
18118   do_one_file (vam);
18119
18120   clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
18121   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
18122   vam->ifp = save_ifp;
18123   vam->input_line_number = save_line_number;
18124   vam->current_file = (u8 *) save_current_file;
18125   vec_free (s);
18126
18127   return 0;
18128 #else
18129   clib_warning ("use the exec command...");
18130   return -99;
18131 #endif
18132 }
18133
18134 static int
18135 echo (vat_main_t * vam)
18136 {
18137   print (vam->ofp, "%v", vam->input->buffer);
18138   return 0;
18139 }
18140
18141 /* List of API message constructors, CLI names map to api_xxx */
18142 #define foreach_vpe_api_msg                                             \
18143 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
18144 _(sw_interface_dump,"")                                                 \
18145 _(sw_interface_set_flags,                                               \
18146   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
18147 _(sw_interface_add_del_address,                                         \
18148   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
18149 _(sw_interface_set_table,                                               \
18150   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
18151 _(sw_interface_set_mpls_enable,                                         \
18152   "<intfc> | sw_if_index [disable | dis]")                              \
18153 _(sw_interface_set_vpath,                                               \
18154   "<intfc> | sw_if_index <id> enable | disable")                        \
18155 _(sw_interface_set_vxlan_bypass,                                        \
18156   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
18157 _(sw_interface_set_l2_xconnect,                                         \
18158   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
18159   "enable | disable")                                                   \
18160 _(sw_interface_set_l2_bridge,                                           \
18161   "<intfc> | sw_if_index <id> bd_id <bridge-domain-id>\n"               \
18162   "[shg <split-horizon-group>] [bvi]\n"                                 \
18163   "enable | disable")                                                   \
18164 _(bridge_domain_add_del,                                                \
18165   "bd_id <bridge-domain-id> [flood 1|0] [uu-flood 1|0] [forward 1|0] [learn 1|0] [arp-term 1|0] [del]\n") \
18166 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
18167 _(l2fib_add_del,                                                        \
18168   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
18169 _(l2_flags,                                                             \
18170   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood]\n") \
18171 _(bridge_flags,                                                         \
18172   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
18173 _(tap_connect,                                                          \
18174   "tapname <name> mac <mac-addr> | random-mac [tag <string>]")          \
18175 _(tap_modify,                                                           \
18176   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
18177 _(tap_delete,                                                           \
18178   "<vpp-if-name> | sw_if_index <id>")                                   \
18179 _(sw_interface_tap_dump, "")                                            \
18180 _(ip_add_del_route,                                                     \
18181   "<addr>/<mask> via <addr> [table-id <n>]\n"                           \
18182   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
18183   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
18184   "[multipath] [count <n>]")                                            \
18185 _(ip_mroute_add_del,                                                    \
18186   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
18187   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
18188 _(mpls_route_add_del,                                                   \
18189   "<label> <eos> via <addr> [table-id <n>]\n"                           \
18190   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
18191   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
18192   "[multipath] [count <n>]")                                            \
18193 _(mpls_ip_bind_unbind,                                                  \
18194   "<label> <addr/len>")                                                 \
18195 _(mpls_tunnel_add_del,                                                  \
18196   " via <addr> [table-id <n>]\n"                                        \
18197   "sw_if_index <id>] [l2]  [del]")                                      \
18198 _(proxy_arp_add_del,                                                    \
18199   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
18200 _(proxy_arp_intfc_enable_disable,                                       \
18201   "<intfc> | sw_if_index <id> enable | disable")                        \
18202 _(sw_interface_set_unnumbered,                                          \
18203   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
18204 _(ip_neighbor_add_del,                                                  \
18205   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
18206   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
18207 _(reset_vrf, "vrf <id> [ipv6]")                                         \
18208 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
18209 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
18210   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
18211   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
18212   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
18213 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
18214 _(reset_fib, "vrf <n> [ipv6]")                                          \
18215 _(dhcp_proxy_config,                                                    \
18216   "svr <v46-address> src <v46-address>\n"                               \
18217    "rx_vrf_id <nn> server_vrf_id <nn>  [del]")                          \
18218 _(dhcp_proxy_set_vss,                                                   \
18219   "tbl_id <n> fib_id <n> oui <n> [ipv6] [del]")                         \
18220 _(dhcp_proxy_dump, "ip6")                                               \
18221 _(dhcp_client_config,                                                   \
18222   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
18223 _(set_ip_flow_hash,                                                     \
18224   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
18225 _(sw_interface_ip6_enable_disable,                                      \
18226   "<intfc> | sw_if_index <id> enable | disable")                        \
18227 _(sw_interface_ip6_set_link_local_address,                              \
18228   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
18229 _(ip6nd_proxy_add_del,                                                  \
18230   "<intfc> | sw_if_index <id> <ip6-address>")                           \
18231 _(ip6nd_proxy_dump, "")                                                 \
18232 _(sw_interface_ip6nd_ra_prefix,                                         \
18233   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
18234   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
18235   "[nolink] [isno]")                                                    \
18236 _(sw_interface_ip6nd_ra_config,                                         \
18237   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
18238   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
18239   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
18240 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
18241 _(l2_patch_add_del,                                                     \
18242   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
18243   "enable | disable")                                                   \
18244 _(sr_localsid_add_del,                                                  \
18245   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
18246   "fib-table <num> (end.psp) sw_if_index <num>")                        \
18247 _(classify_add_del_table,                                               \
18248   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
18249   " [del] [del-chain] mask <mask-value>\n"                              \
18250   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
18251   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
18252 _(classify_add_del_session,                                             \
18253   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
18254   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
18255   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
18256   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
18257 _(classify_set_interface_ip_table,                                      \
18258   "<intfc> | sw_if_index <nn> table <nn>")                              \
18259 _(classify_set_interface_l2_tables,                                     \
18260   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
18261   "  [other-table <nn>]")                                               \
18262 _(get_node_index, "node <node-name")                                    \
18263 _(add_node_next, "node <node-name> next <next-node-name>")              \
18264 _(l2tpv3_create_tunnel,                                                 \
18265   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
18266   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
18267   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
18268 _(l2tpv3_set_tunnel_cookies,                                            \
18269   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
18270   "[new_remote_cookie <nn>]\n")                                         \
18271 _(l2tpv3_interface_enable_disable,                                      \
18272   "<intfc> | sw_if_index <nn> enable | disable")                        \
18273 _(l2tpv3_set_lookup_key,                                                \
18274   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
18275 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
18276 _(vxlan_add_del_tunnel,                                                 \
18277   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
18278   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
18279   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
18280 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
18281 _(gre_add_del_tunnel,                                                   \
18282   "src <ip4-addr> dst <ip4-addr> [outer-fib-id <nn>] [teb] [del]\n")    \
18283 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
18284 _(l2_fib_clear_table, "")                                               \
18285 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
18286 _(l2_interface_vlan_tag_rewrite,                                        \
18287   "<intfc> | sw_if_index <nn> \n"                                       \
18288   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
18289   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
18290 _(create_vhost_user_if,                                                 \
18291         "socket <filename> [server] [renumber <dev_instance>] "         \
18292         "[mac <mac_address>]")                                          \
18293 _(modify_vhost_user_if,                                                 \
18294         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
18295         "[server] [renumber <dev_instance>]")                           \
18296 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
18297 _(sw_interface_vhost_user_dump, "")                                     \
18298 _(show_version, "")                                                     \
18299 _(vxlan_gpe_add_del_tunnel,                                             \
18300   "local <addr> remote <addr> vni <nn>\n"                               \
18301     "[encap-vrf-id <nn>] [decap-vrf-id <nn>] [next-ip4][next-ip6]"      \
18302   "[next-ethernet] [next-nsh]\n")                                       \
18303 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
18304 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
18305 _(interface_name_renumber,                                              \
18306   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
18307 _(input_acl_set_interface,                                              \
18308   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
18309   "  [l2-table <nn>] [del]")                                            \
18310 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
18311 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
18312 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
18313 _(ip_dump, "ipv4 | ipv6")                                               \
18314 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
18315 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
18316   "  spid_id <n> ")                                                     \
18317 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
18318   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
18319   "  integ_alg <alg> integ_key <hex>")                                  \
18320 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
18321   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
18322   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
18323   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
18324 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
18325 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
18326 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
18327   "(auth_data 0x<data> | auth_data <data>)")                            \
18328 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
18329   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
18330 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
18331   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
18332   "(local|remote)")                                                     \
18333 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
18334 _(ikev2_set_responder, "<profile_name> interface <interface> address <addr>") \
18335 _(ikev2_set_ike_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
18336 _(ikev2_set_esp_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
18337 _(ikev2_set_sa_lifetime, "<profile_name> <seconds> <jitter> <handover> <max bytes>") \
18338 _(ikev2_initiate_sa_init, "<profile_name>")                             \
18339 _(ikev2_initiate_del_ike_sa, "<ispi>")                                  \
18340 _(ikev2_initiate_del_child_sa, "<ispi>")                                \
18341 _(ikev2_initiate_rekey_child_sa, "<ispi>")                              \
18342 _(delete_loopback,"sw_if_index <nn>")                                   \
18343 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
18344 _(map_add_domain,                                                       \
18345   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
18346   "ip6-src <ip6addr> "                                                  \
18347   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
18348 _(map_del_domain, "index <n>")                                          \
18349 _(map_add_del_rule,                                                     \
18350   "index <n> psid <n> dst <ip6addr> [del]")                             \
18351 _(map_domain_dump, "")                                                  \
18352 _(map_rule_dump, "index <map-domain>")                                  \
18353 _(want_interface_events,  "enable|disable")                             \
18354 _(want_stats,"enable|disable")                                          \
18355 _(get_first_msg_id, "client <name>")                                    \
18356 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
18357 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
18358   "fib-id <nn> [ip4][ip6][default]")                                    \
18359 _(get_node_graph, " ")                                                  \
18360 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
18361 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
18362 _(ioam_disable, "")                                                     \
18363 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
18364                             " sw_if_index <sw_if_index> p <priority> "  \
18365                             "w <weight>] [del]")                        \
18366 _(one_add_del_locator, "locator-set <locator_name> "                    \
18367                         "iface <intf> | sw_if_index <sw_if_index> "     \
18368                         "p <priority> w <weight> [del]")                \
18369 _(one_add_del_local_eid,"vni <vni> eid "                                \
18370                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
18371                          "locator-set <locator_name> [del]"             \
18372                          "[key-id sha1|sha256 secret-key <secret-key>]")\
18373 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
18374 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
18375 _(one_enable_disable, "enable|disable")                                 \
18376 _(one_map_register_enable_disable, "enable|disable")                    \
18377 _(one_rloc_probe_enable_disable, "enable|disable")                      \
18378 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
18379                                "[seid <seid>] "                         \
18380                                "rloc <locator> p <prio> "               \
18381                                "w <weight> [rloc <loc> ... ] "          \
18382                                "action <action> [del-all]")             \
18383 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
18384                           "<local-eid>")                                \
18385 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
18386 _(one_use_petr, "ip-address> | disable")                                \
18387 _(one_map_request_mode, "src-dst|dst-only")                             \
18388 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
18389 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
18390 _(one_locator_set_dump, "[local | remote]")                             \
18391 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
18392 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
18393                        "[local] | [remote]")                            \
18394 _(one_eid_table_vni_dump, "")                                           \
18395 _(one_eid_table_map_dump, "l2|l3")                                      \
18396 _(one_map_resolver_dump, "")                                            \
18397 _(one_map_server_dump, "")                                              \
18398 _(one_adjacencies_get, "vni <vni>")                                     \
18399 _(show_one_rloc_probe_state, "")                                        \
18400 _(show_one_map_register_state, "")                                      \
18401 _(show_one_status, "")                                                  \
18402 _(one_get_map_request_itr_rlocs, "")                                    \
18403 _(show_one_pitr, "")                                                    \
18404 _(show_one_use_petr, "")                                                \
18405 _(show_one_map_request_mode, "")                                        \
18406 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
18407                             " sw_if_index <sw_if_index> p <priority> "  \
18408                             "w <weight>] [del]")                        \
18409 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
18410                         "iface <intf> | sw_if_index <sw_if_index> "     \
18411                         "p <priority> w <weight> [del]")                \
18412 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
18413                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
18414                          "locator-set <locator_name> [del]"             \
18415                          "[key-id sha1|sha256 secret-key <secret-key>]") \
18416 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
18417 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
18418 _(lisp_enable_disable, "enable|disable")                                \
18419 _(lisp_map_register_enable_disable, "enable|disable")                   \
18420 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
18421 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
18422                                "[seid <seid>] "                         \
18423                                "rloc <locator> p <prio> "               \
18424                                "w <weight> [rloc <loc> ... ] "          \
18425                                "action <action> [del-all]")             \
18426 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
18427                           "<local-eid>")                                \
18428 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
18429 _(lisp_use_petr, "<ip-address> | disable")                              \
18430 _(lisp_map_request_mode, "src-dst|dst-only")                            \
18431 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
18432 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
18433 _(lisp_locator_set_dump, "[local | remote]")                            \
18434 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
18435 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
18436                        "[local] | [remote]")                            \
18437 _(lisp_eid_table_vni_dump, "")                                          \
18438 _(lisp_eid_table_map_dump, "l2|l3")                                     \
18439 _(lisp_map_resolver_dump, "")                                           \
18440 _(lisp_map_server_dump, "")                                             \
18441 _(lisp_adjacencies_get, "vni <vni>")                                    \
18442 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
18443 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
18444 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
18445 _(gpe_get_encap_mode, "")                                               \
18446 _(lisp_gpe_add_del_iface, "up|down")                                    \
18447 _(lisp_gpe_enable_disable, "enable|disable")                            \
18448 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
18449   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
18450 _(show_lisp_rloc_probe_state, "")                                       \
18451 _(show_lisp_map_register_state, "")                                     \
18452 _(show_lisp_status, "")                                                 \
18453 _(lisp_get_map_request_itr_rlocs, "")                                   \
18454 _(show_lisp_pitr, "")                                                   \
18455 _(show_lisp_use_petr, "")                                               \
18456 _(show_lisp_map_request_mode, "")                                       \
18457 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
18458 _(af_packet_delete, "name <host interface name>")                       \
18459 _(policer_add_del, "name <policer name> <params> [del]")                \
18460 _(policer_dump, "[name <policer name>]")                                \
18461 _(policer_classify_set_interface,                                       \
18462   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
18463   "  [l2-table <nn>] [del]")                                            \
18464 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
18465 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
18466     "[master|slave]")                                                   \
18467 _(netmap_delete, "name <interface name>")                               \
18468 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
18469 _(mpls_fib_dump, "")                                                    \
18470 _(classify_table_ids, "")                                               \
18471 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
18472 _(classify_table_info, "table_id <nn>")                                 \
18473 _(classify_session_dump, "table_id <nn>")                               \
18474 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
18475     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
18476     "[template_interval <nn>] [udp_checksum]")                          \
18477 _(ipfix_exporter_dump, "")                                              \
18478 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
18479 _(ipfix_classify_stream_dump, "")                                       \
18480 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
18481 _(ipfix_classify_table_dump, "")                                        \
18482 _(sw_interface_span_enable_disable, "[src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
18483 _(sw_interface_span_dump, "")                                           \
18484 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
18485 _(pg_create_interface, "if_id <nn>")                                    \
18486 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
18487 _(pg_enable_disable, "[stream <id>] disable")                           \
18488 _(ip_source_and_port_range_check_add_del,                               \
18489   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
18490 _(ip_source_and_port_range_check_interface_add_del,                     \
18491   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
18492   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
18493 _(ipsec_gre_add_del_tunnel,                                             \
18494   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
18495 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
18496 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
18497 _(l2_interface_pbb_tag_rewrite,                                         \
18498   "<intfc> | sw_if_index <nn> \n"                                       \
18499   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
18500   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
18501 _(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
18502 _(flow_classify_set_interface,                                          \
18503   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
18504 _(flow_classify_dump, "type [ip4|ip6]")                                 \
18505 _(ip_fib_dump, "")                                                      \
18506 _(ip_mfib_dump, "")                                                     \
18507 _(ip6_fib_dump, "")                                                     \
18508 _(ip6_mfib_dump, "")                                                    \
18509 _(feature_enable_disable, "arc_name <arc_name> "                        \
18510   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
18511 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
18512 "[disable]")                                                            \
18513 _(l2_xconnect_dump, "")                                                 \
18514 _(sw_interface_set_mtu, "<intfc> | sw_if_index <nn> mtu <nn>")        \
18515 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
18516 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")
18517
18518 /* List of command functions, CLI names map directly to functions */
18519 #define foreach_cli_function                                    \
18520 _(comment, "usage: comment <ignore-rest-of-line>")              \
18521 _(dump_interface_table, "usage: dump_interface_table")          \
18522 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
18523 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
18524 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
18525 _(dump_stats_table, "usage: dump_stats_table")                  \
18526 _(dump_macro_table, "usage: dump_macro_table ")                 \
18527 _(dump_node_table, "usage: dump_node_table")                    \
18528 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
18529 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
18530 _(echo, "usage: echo <message>")                                \
18531 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
18532 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
18533 _(help, "usage: help")                                          \
18534 _(q, "usage: quit")                                             \
18535 _(quit, "usage: quit")                                          \
18536 _(search_node_table, "usage: search_node_table <name>...")      \
18537 _(set, "usage: set <variable-name> <value>")                    \
18538 _(script, "usage: script <file-name>")                          \
18539 _(unset, "usage: unset <variable-name>")
18540
18541 #define _(N,n)                                  \
18542     static void vl_api_##n##_t_handler_uni      \
18543     (vl_api_##n##_t * mp)                       \
18544     {                                           \
18545         vat_main_t * vam = &vat_main;           \
18546         if (vam->json_output) {                 \
18547             vl_api_##n##_t_handler_json(mp);    \
18548         } else {                                \
18549             vl_api_##n##_t_handler(mp);         \
18550         }                                       \
18551     }
18552 foreach_vpe_api_reply_msg;
18553 #if VPP_API_TEST_BUILTIN == 0
18554 foreach_standalone_reply_msg;
18555 #endif
18556 #undef _
18557
18558 void
18559 vat_api_hookup (vat_main_t * vam)
18560 {
18561 #define _(N,n)                                                  \
18562     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
18563                            vl_api_##n##_t_handler_uni,          \
18564                            vl_noop_handler,                     \
18565                            vl_api_##n##_t_endian,               \
18566                            vl_api_##n##_t_print,                \
18567                            sizeof(vl_api_##n##_t), 1);
18568   foreach_vpe_api_reply_msg;
18569 #if VPP_API_TEST_BUILTIN == 0
18570   foreach_standalone_reply_msg;
18571 #endif
18572 #undef _
18573
18574 #if (VPP_API_TEST_BUILTIN==0)
18575   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
18576
18577   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
18578
18579   vam->function_by_name = hash_create_string (0, sizeof (uword));
18580
18581   vam->help_by_name = hash_create_string (0, sizeof (uword));
18582 #endif
18583
18584   /* API messages we can send */
18585 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
18586   foreach_vpe_api_msg;
18587 #undef _
18588
18589   /* Help strings */
18590 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
18591   foreach_vpe_api_msg;
18592 #undef _
18593
18594   /* CLI functions */
18595 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
18596   foreach_cli_function;
18597 #undef _
18598
18599   /* Help strings */
18600 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
18601   foreach_cli_function;
18602 #undef _
18603 }
18604
18605 #if VPP_API_TEST_BUILTIN
18606 static clib_error_t *
18607 vat_api_hookup_shim (vlib_main_t * vm)
18608 {
18609   vat_api_hookup (&vat_main);
18610   return 0;
18611 }
18612
18613 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
18614 #endif
18615
18616 /*
18617  * fd.io coding-style-patch-verification: ON
18618  *
18619  * Local Variables:
18620  * eval: (c-set-style "gnu")
18621  * End:
18622  */