VPP crash on creating vxlan gpe interface. VPP-875
[vpp.git] / src / vat / api_format.c
1 /*
2  *------------------------------------------------------------------
3  * api_format.c
4  *
5  * Copyright (c) 2014-2016 Cisco and/or its affiliates.
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at:
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *------------------------------------------------------------------
18  */
19
20 #include <vat/vat.h>
21 #include <vlibapi/api.h>
22 #include <vlibmemory/api.h>
23 #include <vlibsocket/api.h>
24 #include <vnet/ip/ip.h>
25 #include <vnet/l2/l2_input.h>
26 #include <vnet/l2tp/l2tp.h>
27 #include <vnet/vxlan/vxlan.h>
28 #include <vnet/gre/gre.h>
29 #include <vnet/vxlan-gpe/vxlan_gpe.h>
30 #include <vnet/lisp-gpe/lisp_gpe.h>
31
32 #include <vpp/api/vpe_msg_enum.h>
33 #include <vnet/l2/l2_classify.h>
34 #include <vnet/l2/l2_vtr.h>
35 #include <vnet/classify/input_acl.h>
36 #include <vnet/classify/policer_classify.h>
37 #include <vnet/classify/flow_classify.h>
38 #include <vnet/mpls/mpls.h>
39 #include <vnet/ipsec/ipsec.h>
40 #include <vnet/ipsec/ikev2.h>
41 #include <inttypes.h>
42 #include <vnet/map/map.h>
43 #include <vnet/cop/cop.h>
44 #include <vnet/ip/ip6_hop_by_hop.h>
45 #include <vnet/ip/ip_source_and_port_range_check.h>
46 #include <vnet/policer/xlate.h>
47 #include <vnet/span/span.h>
48 #include <vnet/policer/policer.h>
49 #include <vnet/policer/police.h>
50 #include <vnet/mfib/mfib_types.h>
51
52 #include "vat/json_format.h"
53
54 #include <inttypes.h>
55 #include <sys/stat.h>
56
57 #define vl_typedefs             /* define message structures */
58 #include <vpp/api/vpe_all_api_h.h>
59 #undef vl_typedefs
60
61 /* declare message handlers for each api */
62
63 #define vl_endianfun            /* define message structures */
64 #include <vpp/api/vpe_all_api_h.h>
65 #undef vl_endianfun
66
67 /* instantiate all the print functions we know about */
68 #define vl_print(handle, ...)
69 #define vl_printfun
70 #include <vpp/api/vpe_all_api_h.h>
71 #undef vl_printfun
72
73 #define __plugin_msg_base 0
74 #include <vlibapi/vat_helper_macros.h>
75
76 f64
77 vat_time_now (vat_main_t * vam)
78 {
79 #if VPP_API_TEST_BUILTIN
80   return vlib_time_now (vam->vlib_main);
81 #else
82   return clib_time_now (&vam->clib_time);
83 #endif
84 }
85
86 void
87 errmsg (char *fmt, ...)
88 {
89   vat_main_t *vam = &vat_main;
90   va_list va;
91   u8 *s;
92
93   va_start (va, fmt);
94   s = va_format (0, fmt, &va);
95   va_end (va);
96
97   vec_add1 (s, 0);
98
99 #if VPP_API_TEST_BUILTIN
100   vlib_cli_output (vam->vlib_main, (char *) s);
101 #else
102   {
103     if (vam->ifp != stdin)
104       fformat (vam->ofp, "%s(%d): \n", vam->current_file,
105                vam->input_line_number);
106     fformat (vam->ofp, (char *) s);
107     fflush (vam->ofp);
108   }
109 #endif
110
111   vec_free (s);
112 }
113
114 #if VPP_API_TEST_BUILTIN == 0
115 static uword
116 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
117 {
118   vat_main_t *vam = va_arg (*args, vat_main_t *);
119   u32 *result = va_arg (*args, u32 *);
120   u8 *if_name;
121   uword *p;
122
123   if (!unformat (input, "%s", &if_name))
124     return 0;
125
126   p = hash_get_mem (vam->sw_if_index_by_interface_name, if_name);
127   if (p == 0)
128     return 0;
129   *result = p[0];
130   return 1;
131 }
132
133 /* Parse an IP4 address %d.%d.%d.%d. */
134 uword
135 unformat_ip4_address (unformat_input_t * input, va_list * args)
136 {
137   u8 *result = va_arg (*args, u8 *);
138   unsigned a[4];
139
140   if (!unformat (input, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]))
141     return 0;
142
143   if (a[0] >= 256 || a[1] >= 256 || a[2] >= 256 || a[3] >= 256)
144     return 0;
145
146   result[0] = a[0];
147   result[1] = a[1];
148   result[2] = a[2];
149   result[3] = a[3];
150
151   return 1;
152 }
153
154 uword
155 unformat_ethernet_address (unformat_input_t * input, va_list * args)
156 {
157   u8 *result = va_arg (*args, u8 *);
158   u32 i, a[6];
159
160   if (!unformat (input, "%_%x:%x:%x:%x:%x:%x%_",
161                  &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]))
162     return 0;
163
164   /* Check range. */
165   for (i = 0; i < 6; i++)
166     if (a[i] >= (1 << 8))
167       return 0;
168
169   for (i = 0; i < 6; i++)
170     result[i] = a[i];
171
172   return 1;
173 }
174
175 /* Returns ethernet type as an int in host byte order. */
176 uword
177 unformat_ethernet_type_host_byte_order (unformat_input_t * input,
178                                         va_list * args)
179 {
180   u16 *result = va_arg (*args, u16 *);
181   int type;
182
183   /* Numeric type. */
184   if (unformat (input, "0x%x", &type) || unformat (input, "%d", &type))
185     {
186       if (type >= (1 << 16))
187         return 0;
188       *result = type;
189       return 1;
190     }
191   return 0;
192 }
193
194 /* Parse an IP6 address. */
195 uword
196 unformat_ip6_address (unformat_input_t * input, va_list * args)
197 {
198   ip6_address_t *result = va_arg (*args, ip6_address_t *);
199   u16 hex_quads[8];
200   uword hex_quad, n_hex_quads, hex_digit, n_hex_digits;
201   uword c, n_colon, double_colon_index;
202
203   n_hex_quads = hex_quad = n_hex_digits = n_colon = 0;
204   double_colon_index = ARRAY_LEN (hex_quads);
205   while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
206     {
207       hex_digit = 16;
208       if (c >= '0' && c <= '9')
209         hex_digit = c - '0';
210       else if (c >= 'a' && c <= 'f')
211         hex_digit = c + 10 - 'a';
212       else if (c >= 'A' && c <= 'F')
213         hex_digit = c + 10 - 'A';
214       else if (c == ':' && n_colon < 2)
215         n_colon++;
216       else
217         {
218           unformat_put_input (input);
219           break;
220         }
221
222       /* Too many hex quads. */
223       if (n_hex_quads >= ARRAY_LEN (hex_quads))
224         return 0;
225
226       if (hex_digit < 16)
227         {
228           hex_quad = (hex_quad << 4) | hex_digit;
229
230           /* Hex quad must fit in 16 bits. */
231           if (n_hex_digits >= 4)
232             return 0;
233
234           n_colon = 0;
235           n_hex_digits++;
236         }
237
238       /* Save position of :: */
239       if (n_colon == 2)
240         {
241           /* More than one :: ? */
242           if (double_colon_index < ARRAY_LEN (hex_quads))
243             return 0;
244           double_colon_index = n_hex_quads;
245         }
246
247       if (n_colon > 0 && n_hex_digits > 0)
248         {
249           hex_quads[n_hex_quads++] = hex_quad;
250           hex_quad = 0;
251           n_hex_digits = 0;
252         }
253     }
254
255   if (n_hex_digits > 0)
256     hex_quads[n_hex_quads++] = hex_quad;
257
258   {
259     word i;
260
261     /* Expand :: to appropriate number of zero hex quads. */
262     if (double_colon_index < ARRAY_LEN (hex_quads))
263       {
264         word n_zero = ARRAY_LEN (hex_quads) - n_hex_quads;
265
266         for (i = n_hex_quads - 1; i >= (signed) double_colon_index; i--)
267           hex_quads[n_zero + i] = hex_quads[i];
268
269         for (i = 0; i < n_zero; i++)
270           hex_quads[double_colon_index + i] = 0;
271
272         n_hex_quads = ARRAY_LEN (hex_quads);
273       }
274
275     /* Too few hex quads given. */
276     if (n_hex_quads < ARRAY_LEN (hex_quads))
277       return 0;
278
279     for (i = 0; i < ARRAY_LEN (hex_quads); i++)
280       result->as_u16[i] = clib_host_to_net_u16 (hex_quads[i]);
281
282     return 1;
283   }
284 }
285
286 uword
287 unformat_ipsec_policy_action (unformat_input_t * input, va_list * args)
288 {
289   u32 *r = va_arg (*args, u32 *);
290
291   if (0);
292 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f;
293   foreach_ipsec_policy_action
294 #undef _
295     else
296     return 0;
297   return 1;
298 }
299
300 uword
301 unformat_ipsec_crypto_alg (unformat_input_t * input, va_list * args)
302 {
303   u32 *r = va_arg (*args, u32 *);
304
305   if (0);
306 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_CRYPTO_ALG_##f;
307   foreach_ipsec_crypto_alg
308 #undef _
309     else
310     return 0;
311   return 1;
312 }
313
314 u8 *
315 format_ipsec_crypto_alg (u8 * s, va_list * args)
316 {
317   u32 i = va_arg (*args, u32);
318   u8 *t = 0;
319
320   switch (i)
321     {
322 #define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break;
323       foreach_ipsec_crypto_alg
324 #undef _
325     default:
326       return format (s, "unknown");
327     }
328   return format (s, "%s", t);
329 }
330
331 uword
332 unformat_ipsec_integ_alg (unformat_input_t * input, va_list * args)
333 {
334   u32 *r = va_arg (*args, u32 *);
335
336   if (0);
337 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_INTEG_ALG_##f;
338   foreach_ipsec_integ_alg
339 #undef _
340     else
341     return 0;
342   return 1;
343 }
344
345 u8 *
346 format_ipsec_integ_alg (u8 * s, va_list * args)
347 {
348   u32 i = va_arg (*args, u32);
349   u8 *t = 0;
350
351   switch (i)
352     {
353 #define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
354       foreach_ipsec_integ_alg
355 #undef _
356     default:
357       return format (s, "unknown");
358     }
359   return format (s, "%s", t);
360 }
361
362 uword
363 unformat_ikev2_auth_method (unformat_input_t * input, va_list * args)
364 {
365   u32 *r = va_arg (*args, u32 *);
366
367   if (0);
368 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_AUTH_METHOD_##f;
369   foreach_ikev2_auth_method
370 #undef _
371     else
372     return 0;
373   return 1;
374 }
375
376 uword
377 unformat_ikev2_id_type (unformat_input_t * input, va_list * args)
378 {
379   u32 *r = va_arg (*args, u32 *);
380
381   if (0);
382 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_ID_TYPE_##f;
383   foreach_ikev2_id_type
384 #undef _
385     else
386     return 0;
387   return 1;
388 }
389 #else /* VPP_API_TEST_BUILTIN == 1 */
390 static uword
391 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
392 {
393   vat_main_t *vam __attribute__ ((unused)) = va_arg (*args, vat_main_t *);
394   vnet_main_t *vnm = vnet_get_main ();
395   u32 *result = va_arg (*args, u32 *);
396   u32 sw_if_index;
397
398   if (!unformat (input, "%U", unformat_vnet_sw_interface, vnm, &sw_if_index))
399     return 0;
400
401   *result = sw_if_index;
402   return 1;
403 }
404 #endif /* VPP_API_TEST_BUILTIN */
405
406 static uword
407 unformat_policer_rate_type (unformat_input_t * input, va_list * args)
408 {
409   u8 *r = va_arg (*args, u8 *);
410
411   if (unformat (input, "kbps"))
412     *r = SSE2_QOS_RATE_KBPS;
413   else if (unformat (input, "pps"))
414     *r = SSE2_QOS_RATE_PPS;
415   else
416     return 0;
417   return 1;
418 }
419
420 static uword
421 unformat_policer_round_type (unformat_input_t * input, va_list * args)
422 {
423   u8 *r = va_arg (*args, u8 *);
424
425   if (unformat (input, "closest"))
426     *r = SSE2_QOS_ROUND_TO_CLOSEST;
427   else if (unformat (input, "up"))
428     *r = SSE2_QOS_ROUND_TO_UP;
429   else if (unformat (input, "down"))
430     *r = SSE2_QOS_ROUND_TO_DOWN;
431   else
432     return 0;
433   return 1;
434 }
435
436 static uword
437 unformat_policer_type (unformat_input_t * input, va_list * args)
438 {
439   u8 *r = va_arg (*args, u8 *);
440
441   if (unformat (input, "1r2c"))
442     *r = SSE2_QOS_POLICER_TYPE_1R2C;
443   else if (unformat (input, "1r3c"))
444     *r = SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697;
445   else if (unformat (input, "2r3c-2698"))
446     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698;
447   else if (unformat (input, "2r3c-4115"))
448     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115;
449   else if (unformat (input, "2r3c-mef5cf1"))
450     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
451   else
452     return 0;
453   return 1;
454 }
455
456 static uword
457 unformat_dscp (unformat_input_t * input, va_list * va)
458 {
459   u8 *r = va_arg (*va, u8 *);
460
461   if (0);
462 #define _(v,f,str) else if (unformat (input, str)) *r = VNET_DSCP_##f;
463   foreach_vnet_dscp
464 #undef _
465     else
466     return 0;
467   return 1;
468 }
469
470 static uword
471 unformat_policer_action_type (unformat_input_t * input, va_list * va)
472 {
473   sse2_qos_pol_action_params_st *a
474     = va_arg (*va, sse2_qos_pol_action_params_st *);
475
476   if (unformat (input, "drop"))
477     a->action_type = SSE2_QOS_ACTION_DROP;
478   else if (unformat (input, "transmit"))
479     a->action_type = SSE2_QOS_ACTION_TRANSMIT;
480   else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp))
481     a->action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
482   else
483     return 0;
484   return 1;
485 }
486
487 static uword
488 unformat_policer_classify_table_type (unformat_input_t * input, va_list * va)
489 {
490   u32 *r = va_arg (*va, u32 *);
491   u32 tid;
492
493   if (unformat (input, "ip4"))
494     tid = POLICER_CLASSIFY_TABLE_IP4;
495   else if (unformat (input, "ip6"))
496     tid = POLICER_CLASSIFY_TABLE_IP6;
497   else if (unformat (input, "l2"))
498     tid = POLICER_CLASSIFY_TABLE_L2;
499   else
500     return 0;
501
502   *r = tid;
503   return 1;
504 }
505
506 static uword
507 unformat_flow_classify_table_type (unformat_input_t * input, va_list * va)
508 {
509   u32 *r = va_arg (*va, u32 *);
510   u32 tid;
511
512   if (unformat (input, "ip4"))
513     tid = FLOW_CLASSIFY_TABLE_IP4;
514   else if (unformat (input, "ip6"))
515     tid = FLOW_CLASSIFY_TABLE_IP6;
516   else
517     return 0;
518
519   *r = tid;
520   return 1;
521 }
522
523 static const char *mfib_flag_names[] = MFIB_ENTRY_NAMES_SHORT;
524 static const char *mfib_flag_long_names[] = MFIB_ENTRY_NAMES_LONG;
525 static const char *mfib_itf_flag_long_names[] = MFIB_ITF_NAMES_LONG;
526 static const char *mfib_itf_flag_names[] = MFIB_ITF_NAMES_SHORT;
527
528 #if (VPP_API_TEST_BUILTIN==0)
529 uword
530 unformat_mfib_itf_flags (unformat_input_t * input, va_list * args)
531 {
532   mfib_itf_flags_t old, *iflags = va_arg (*args, mfib_itf_flags_t *);
533   mfib_itf_attribute_t attr;
534
535   old = *iflags;
536   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
537   {
538     if (unformat (input, mfib_itf_flag_long_names[attr]))
539       *iflags |= (1 << attr);
540   }
541   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
542   {
543     if (unformat (input, mfib_itf_flag_names[attr]))
544       *iflags |= (1 << attr);
545   }
546
547   return (old == *iflags ? 0 : 1);
548 }
549
550 uword
551 unformat_mfib_entry_flags (unformat_input_t * input, va_list * args)
552 {
553   mfib_entry_flags_t old, *eflags = va_arg (*args, mfib_entry_flags_t *);
554   mfib_entry_attribute_t attr;
555
556   old = *eflags;
557   FOR_EACH_MFIB_ATTRIBUTE (attr)
558   {
559     if (unformat (input, mfib_flag_long_names[attr]))
560       *eflags |= (1 << attr);
561   }
562   FOR_EACH_MFIB_ATTRIBUTE (attr)
563   {
564     if (unformat (input, mfib_flag_names[attr]))
565       *eflags |= (1 << attr);
566   }
567
568   return (old == *eflags ? 0 : 1);
569 }
570
571 u8 *
572 format_ip4_address (u8 * s, va_list * args)
573 {
574   u8 *a = va_arg (*args, u8 *);
575   return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
576 }
577
578 u8 *
579 format_ip6_address (u8 * s, va_list * args)
580 {
581   ip6_address_t *a = va_arg (*args, ip6_address_t *);
582   u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
583
584   i_max_n_zero = ARRAY_LEN (a->as_u16);
585   max_n_zeros = 0;
586   i_first_zero = i_max_n_zero;
587   n_zeros = 0;
588   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
589     {
590       u32 is_zero = a->as_u16[i] == 0;
591       if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
592         {
593           i_first_zero = i;
594           n_zeros = 0;
595         }
596       n_zeros += is_zero;
597       if ((!is_zero && n_zeros > max_n_zeros)
598           || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
599         {
600           i_max_n_zero = i_first_zero;
601           max_n_zeros = n_zeros;
602           i_first_zero = ARRAY_LEN (a->as_u16);
603           n_zeros = 0;
604         }
605     }
606
607   last_double_colon = 0;
608   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
609     {
610       if (i == i_max_n_zero && max_n_zeros > 1)
611         {
612           s = format (s, "::");
613           i += max_n_zeros - 1;
614           last_double_colon = 1;
615         }
616       else
617         {
618           s = format (s, "%s%x",
619                       (last_double_colon || i == 0) ? "" : ":",
620                       clib_net_to_host_u16 (a->as_u16[i]));
621           last_double_colon = 0;
622         }
623     }
624
625   return s;
626 }
627
628 /* Format an IP46 address. */
629 u8 *
630 format_ip46_address (u8 * s, va_list * args)
631 {
632   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
633   ip46_type_t type = va_arg (*args, ip46_type_t);
634   int is_ip4 = 1;
635
636   switch (type)
637     {
638     case IP46_TYPE_ANY:
639       is_ip4 = ip46_address_is_ip4 (ip46);
640       break;
641     case IP46_TYPE_IP4:
642       is_ip4 = 1;
643       break;
644     case IP46_TYPE_IP6:
645       is_ip4 = 0;
646       break;
647     }
648
649   return is_ip4 ?
650     format (s, "%U", format_ip4_address, &ip46->ip4) :
651     format (s, "%U", format_ip6_address, &ip46->ip6);
652 }
653
654 u8 *
655 format_ethernet_address (u8 * s, va_list * args)
656 {
657   u8 *a = va_arg (*args, u8 *);
658
659   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
660                  a[0], a[1], a[2], a[3], a[4], a[5]);
661 }
662 #endif
663
664 static void
665 increment_v4_address (ip4_address_t * a)
666 {
667   u32 v;
668
669   v = ntohl (a->as_u32) + 1;
670   a->as_u32 = ntohl (v);
671 }
672
673 static void
674 increment_v6_address (ip6_address_t * a)
675 {
676   u64 v0, v1;
677
678   v0 = clib_net_to_host_u64 (a->as_u64[0]);
679   v1 = clib_net_to_host_u64 (a->as_u64[1]);
680
681   v1 += 1;
682   if (v1 == 0)
683     v0 += 1;
684   a->as_u64[0] = clib_net_to_host_u64 (v0);
685   a->as_u64[1] = clib_net_to_host_u64 (v1);
686 }
687
688 static void
689 increment_mac_address (u64 * mac)
690 {
691   u64 tmp = *mac;
692
693   tmp = clib_net_to_host_u64 (tmp);
694   tmp += 1 << 16;               /* skip unused (least significant) octets */
695   tmp = clib_host_to_net_u64 (tmp);
696   *mac = tmp;
697 }
698
699 static void vl_api_create_loopback_reply_t_handler
700   (vl_api_create_loopback_reply_t * mp)
701 {
702   vat_main_t *vam = &vat_main;
703   i32 retval = ntohl (mp->retval);
704
705   vam->retval = retval;
706   vam->regenerate_interface_table = 1;
707   vam->sw_if_index = ntohl (mp->sw_if_index);
708   vam->result_ready = 1;
709 }
710
711 static void vl_api_create_loopback_reply_t_handler_json
712   (vl_api_create_loopback_reply_t * mp)
713 {
714   vat_main_t *vam = &vat_main;
715   vat_json_node_t node;
716
717   vat_json_init_object (&node);
718   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
719   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
720
721   vat_json_print (vam->ofp, &node);
722   vat_json_free (&node);
723   vam->retval = ntohl (mp->retval);
724   vam->result_ready = 1;
725 }
726
727 static void vl_api_create_loopback_instance_reply_t_handler
728   (vl_api_create_loopback_instance_reply_t * mp)
729 {
730   vat_main_t *vam = &vat_main;
731   i32 retval = ntohl (mp->retval);
732
733   vam->retval = retval;
734   vam->regenerate_interface_table = 1;
735   vam->sw_if_index = ntohl (mp->sw_if_index);
736   vam->result_ready = 1;
737 }
738
739 static void vl_api_create_loopback_instance_reply_t_handler_json
740   (vl_api_create_loopback_instance_reply_t * mp)
741 {
742   vat_main_t *vam = &vat_main;
743   vat_json_node_t node;
744
745   vat_json_init_object (&node);
746   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
747   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
748
749   vat_json_print (vam->ofp, &node);
750   vat_json_free (&node);
751   vam->retval = ntohl (mp->retval);
752   vam->result_ready = 1;
753 }
754
755 static void vl_api_af_packet_create_reply_t_handler
756   (vl_api_af_packet_create_reply_t * mp)
757 {
758   vat_main_t *vam = &vat_main;
759   i32 retval = ntohl (mp->retval);
760
761   vam->retval = retval;
762   vam->regenerate_interface_table = 1;
763   vam->sw_if_index = ntohl (mp->sw_if_index);
764   vam->result_ready = 1;
765 }
766
767 static void vl_api_af_packet_create_reply_t_handler_json
768   (vl_api_af_packet_create_reply_t * mp)
769 {
770   vat_main_t *vam = &vat_main;
771   vat_json_node_t node;
772
773   vat_json_init_object (&node);
774   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
775   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
776
777   vat_json_print (vam->ofp, &node);
778   vat_json_free (&node);
779
780   vam->retval = ntohl (mp->retval);
781   vam->result_ready = 1;
782 }
783
784 static void vl_api_create_vlan_subif_reply_t_handler
785   (vl_api_create_vlan_subif_reply_t * mp)
786 {
787   vat_main_t *vam = &vat_main;
788   i32 retval = ntohl (mp->retval);
789
790   vam->retval = retval;
791   vam->regenerate_interface_table = 1;
792   vam->sw_if_index = ntohl (mp->sw_if_index);
793   vam->result_ready = 1;
794 }
795
796 static void vl_api_create_vlan_subif_reply_t_handler_json
797   (vl_api_create_vlan_subif_reply_t * mp)
798 {
799   vat_main_t *vam = &vat_main;
800   vat_json_node_t node;
801
802   vat_json_init_object (&node);
803   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
804   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
805
806   vat_json_print (vam->ofp, &node);
807   vat_json_free (&node);
808
809   vam->retval = ntohl (mp->retval);
810   vam->result_ready = 1;
811 }
812
813 static void vl_api_create_subif_reply_t_handler
814   (vl_api_create_subif_reply_t * mp)
815 {
816   vat_main_t *vam = &vat_main;
817   i32 retval = ntohl (mp->retval);
818
819   vam->retval = retval;
820   vam->regenerate_interface_table = 1;
821   vam->sw_if_index = ntohl (mp->sw_if_index);
822   vam->result_ready = 1;
823 }
824
825 static void vl_api_create_subif_reply_t_handler_json
826   (vl_api_create_subif_reply_t * mp)
827 {
828   vat_main_t *vam = &vat_main;
829   vat_json_node_t node;
830
831   vat_json_init_object (&node);
832   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
833   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
834
835   vat_json_print (vam->ofp, &node);
836   vat_json_free (&node);
837
838   vam->retval = ntohl (mp->retval);
839   vam->result_ready = 1;
840 }
841
842 static void vl_api_interface_name_renumber_reply_t_handler
843   (vl_api_interface_name_renumber_reply_t * mp)
844 {
845   vat_main_t *vam = &vat_main;
846   i32 retval = ntohl (mp->retval);
847
848   vam->retval = retval;
849   vam->regenerate_interface_table = 1;
850   vam->result_ready = 1;
851 }
852
853 static void vl_api_interface_name_renumber_reply_t_handler_json
854   (vl_api_interface_name_renumber_reply_t * mp)
855 {
856   vat_main_t *vam = &vat_main;
857   vat_json_node_t node;
858
859   vat_json_init_object (&node);
860   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
861
862   vat_json_print (vam->ofp, &node);
863   vat_json_free (&node);
864
865   vam->retval = ntohl (mp->retval);
866   vam->result_ready = 1;
867 }
868
869 /*
870  * Special-case: build the interface table, maintain
871  * the next loopback sw_if_index vbl.
872  */
873 static void vl_api_sw_interface_details_t_handler
874   (vl_api_sw_interface_details_t * mp)
875 {
876   vat_main_t *vam = &vat_main;
877   u8 *s = format (0, "%s%c", mp->interface_name, 0);
878
879   hash_set_mem (vam->sw_if_index_by_interface_name, s,
880                 ntohl (mp->sw_if_index));
881
882   /* In sub interface case, fill the sub interface table entry */
883   if (mp->sw_if_index != mp->sup_sw_if_index)
884     {
885       sw_interface_subif_t *sub = NULL;
886
887       vec_add2 (vam->sw_if_subif_table, sub, 1);
888
889       vec_validate (sub->interface_name, strlen ((char *) s) + 1);
890       strncpy ((char *) sub->interface_name, (char *) s,
891                vec_len (sub->interface_name));
892       sub->sw_if_index = ntohl (mp->sw_if_index);
893       sub->sub_id = ntohl (mp->sub_id);
894
895       sub->sub_dot1ad = mp->sub_dot1ad;
896       sub->sub_number_of_tags = mp->sub_number_of_tags;
897       sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
898       sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
899       sub->sub_exact_match = mp->sub_exact_match;
900       sub->sub_default = mp->sub_default;
901       sub->sub_outer_vlan_id_any = mp->sub_outer_vlan_id_any;
902       sub->sub_inner_vlan_id_any = mp->sub_inner_vlan_id_any;
903
904       /* vlan tag rewrite */
905       sub->vtr_op = ntohl (mp->vtr_op);
906       sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
907       sub->vtr_tag1 = ntohl (mp->vtr_tag1);
908       sub->vtr_tag2 = ntohl (mp->vtr_tag2);
909     }
910 }
911
912 static void vl_api_sw_interface_details_t_handler_json
913   (vl_api_sw_interface_details_t * mp)
914 {
915   vat_main_t *vam = &vat_main;
916   vat_json_node_t *node = NULL;
917
918   if (VAT_JSON_ARRAY != vam->json_tree.type)
919     {
920       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
921       vat_json_init_array (&vam->json_tree);
922     }
923   node = vat_json_array_add (&vam->json_tree);
924
925   vat_json_init_object (node);
926   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
927   vat_json_object_add_uint (node, "sup_sw_if_index",
928                             ntohl (mp->sup_sw_if_index));
929   vat_json_object_add_uint (node, "l2_address_length",
930                             ntohl (mp->l2_address_length));
931   vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
932                              sizeof (mp->l2_address));
933   vat_json_object_add_string_copy (node, "interface_name",
934                                    mp->interface_name);
935   vat_json_object_add_uint (node, "admin_up_down", mp->admin_up_down);
936   vat_json_object_add_uint (node, "link_up_down", mp->link_up_down);
937   vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
938   vat_json_object_add_uint (node, "link_speed", mp->link_speed);
939   vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
940   vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
941   vat_json_object_add_uint (node, "sub_dot1ad", mp->sub_dot1ad);
942   vat_json_object_add_uint (node, "sub_number_of_tags",
943                             mp->sub_number_of_tags);
944   vat_json_object_add_uint (node, "sub_outer_vlan_id",
945                             ntohs (mp->sub_outer_vlan_id));
946   vat_json_object_add_uint (node, "sub_inner_vlan_id",
947                             ntohs (mp->sub_inner_vlan_id));
948   vat_json_object_add_uint (node, "sub_exact_match", mp->sub_exact_match);
949   vat_json_object_add_uint (node, "sub_default", mp->sub_default);
950   vat_json_object_add_uint (node, "sub_outer_vlan_id_any",
951                             mp->sub_outer_vlan_id_any);
952   vat_json_object_add_uint (node, "sub_inner_vlan_id_any",
953                             mp->sub_inner_vlan_id_any);
954   vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
955   vat_json_object_add_uint (node, "vtr_push_dot1q",
956                             ntohl (mp->vtr_push_dot1q));
957   vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
958   vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
959   if (mp->sub_dot1ah)
960     {
961       vat_json_object_add_string_copy (node, "pbb_vtr_dmac",
962                                        format (0, "%U",
963                                                format_ethernet_address,
964                                                &mp->b_dmac));
965       vat_json_object_add_string_copy (node, "pbb_vtr_smac",
966                                        format (0, "%U",
967                                                format_ethernet_address,
968                                                &mp->b_smac));
969       vat_json_object_add_uint (node, "pbb_vtr_b_vlanid", mp->b_vlanid);
970       vat_json_object_add_uint (node, "pbb_vtr_i_sid", mp->i_sid);
971     }
972 }
973
974 #if VPP_API_TEST_BUILTIN == 0
975 static void vl_api_sw_interface_set_flags_t_handler
976   (vl_api_sw_interface_set_flags_t * mp)
977 {
978   vat_main_t *vam = &vat_main;
979   if (vam->interface_event_display)
980     errmsg ("interface flags: sw_if_index %d %s %s",
981             ntohl (mp->sw_if_index),
982             mp->admin_up_down ? "admin-up" : "admin-down",
983             mp->link_up_down ? "link-up" : "link-down");
984 }
985 #endif
986
987 static void vl_api_sw_interface_set_flags_t_handler_json
988   (vl_api_sw_interface_set_flags_t * mp)
989 {
990   /* JSON output not supported */
991 }
992
993 static void
994 vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
995 {
996   vat_main_t *vam = &vat_main;
997   i32 retval = ntohl (mp->retval);
998
999   vam->retval = retval;
1000   vam->shmem_result = uword_to_pointer (mp->reply_in_shmem, u8 *);
1001   vam->result_ready = 1;
1002 }
1003
1004 static void
1005 vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
1006 {
1007   vat_main_t *vam = &vat_main;
1008   vat_json_node_t node;
1009   api_main_t *am = &api_main;
1010   void *oldheap;
1011   u8 *reply;
1012
1013   vat_json_init_object (&node);
1014   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1015   vat_json_object_add_uint (&node, "reply_in_shmem",
1016                             ntohl (mp->reply_in_shmem));
1017   /* Toss the shared-memory original... */
1018   pthread_mutex_lock (&am->vlib_rp->mutex);
1019   oldheap = svm_push_data_heap (am->vlib_rp);
1020
1021   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
1022   vec_free (reply);
1023
1024   svm_pop_heap (oldheap);
1025   pthread_mutex_unlock (&am->vlib_rp->mutex);
1026
1027   vat_json_print (vam->ofp, &node);
1028   vat_json_free (&node);
1029
1030   vam->retval = ntohl (mp->retval);
1031   vam->result_ready = 1;
1032 }
1033
1034 static void
1035 vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
1036 {
1037   vat_main_t *vam = &vat_main;
1038   i32 retval = ntohl (mp->retval);
1039
1040   vam->retval = retval;
1041   vam->cmd_reply = mp->reply;
1042   vam->result_ready = 1;
1043 }
1044
1045 static void
1046 vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
1047 {
1048   vat_main_t *vam = &vat_main;
1049   vat_json_node_t node;
1050
1051   vat_json_init_object (&node);
1052   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1053   vat_json_object_add_string_copy (&node, "reply", mp->reply);
1054
1055   vat_json_print (vam->ofp, &node);
1056   vat_json_free (&node);
1057
1058   vam->retval = ntohl (mp->retval);
1059   vam->result_ready = 1;
1060 }
1061
1062 static void vl_api_classify_add_del_table_reply_t_handler
1063   (vl_api_classify_add_del_table_reply_t * mp)
1064 {
1065   vat_main_t *vam = &vat_main;
1066   i32 retval = ntohl (mp->retval);
1067   if (vam->async_mode)
1068     {
1069       vam->async_errors += (retval < 0);
1070     }
1071   else
1072     {
1073       vam->retval = retval;
1074       if (retval == 0 &&
1075           ((mp->new_table_index != 0xFFFFFFFF) ||
1076            (mp->skip_n_vectors != 0xFFFFFFFF) ||
1077            (mp->match_n_vectors != 0xFFFFFFFF)))
1078         /*
1079          * Note: this is just barely thread-safe, depends on
1080          * the main thread spinning waiting for an answer...
1081          */
1082         errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d",
1083                 ntohl (mp->new_table_index),
1084                 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
1085       vam->result_ready = 1;
1086     }
1087 }
1088
1089 static void vl_api_classify_add_del_table_reply_t_handler_json
1090   (vl_api_classify_add_del_table_reply_t * mp)
1091 {
1092   vat_main_t *vam = &vat_main;
1093   vat_json_node_t node;
1094
1095   vat_json_init_object (&node);
1096   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1097   vat_json_object_add_uint (&node, "new_table_index",
1098                             ntohl (mp->new_table_index));
1099   vat_json_object_add_uint (&node, "skip_n_vectors",
1100                             ntohl (mp->skip_n_vectors));
1101   vat_json_object_add_uint (&node, "match_n_vectors",
1102                             ntohl (mp->match_n_vectors));
1103
1104   vat_json_print (vam->ofp, &node);
1105   vat_json_free (&node);
1106
1107   vam->retval = ntohl (mp->retval);
1108   vam->result_ready = 1;
1109 }
1110
1111 static void vl_api_get_node_index_reply_t_handler
1112   (vl_api_get_node_index_reply_t * mp)
1113 {
1114   vat_main_t *vam = &vat_main;
1115   i32 retval = ntohl (mp->retval);
1116   if (vam->async_mode)
1117     {
1118       vam->async_errors += (retval < 0);
1119     }
1120   else
1121     {
1122       vam->retval = retval;
1123       if (retval == 0)
1124         errmsg ("node index %d", ntohl (mp->node_index));
1125       vam->result_ready = 1;
1126     }
1127 }
1128
1129 static void vl_api_get_node_index_reply_t_handler_json
1130   (vl_api_get_node_index_reply_t * mp)
1131 {
1132   vat_main_t *vam = &vat_main;
1133   vat_json_node_t node;
1134
1135   vat_json_init_object (&node);
1136   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1137   vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
1138
1139   vat_json_print (vam->ofp, &node);
1140   vat_json_free (&node);
1141
1142   vam->retval = ntohl (mp->retval);
1143   vam->result_ready = 1;
1144 }
1145
1146 static void vl_api_get_next_index_reply_t_handler
1147   (vl_api_get_next_index_reply_t * mp)
1148 {
1149   vat_main_t *vam = &vat_main;
1150   i32 retval = ntohl (mp->retval);
1151   if (vam->async_mode)
1152     {
1153       vam->async_errors += (retval < 0);
1154     }
1155   else
1156     {
1157       vam->retval = retval;
1158       if (retval == 0)
1159         errmsg ("next node index %d", ntohl (mp->next_index));
1160       vam->result_ready = 1;
1161     }
1162 }
1163
1164 static void vl_api_get_next_index_reply_t_handler_json
1165   (vl_api_get_next_index_reply_t * mp)
1166 {
1167   vat_main_t *vam = &vat_main;
1168   vat_json_node_t node;
1169
1170   vat_json_init_object (&node);
1171   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1172   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1173
1174   vat_json_print (vam->ofp, &node);
1175   vat_json_free (&node);
1176
1177   vam->retval = ntohl (mp->retval);
1178   vam->result_ready = 1;
1179 }
1180
1181 static void vl_api_add_node_next_reply_t_handler
1182   (vl_api_add_node_next_reply_t * mp)
1183 {
1184   vat_main_t *vam = &vat_main;
1185   i32 retval = ntohl (mp->retval);
1186   if (vam->async_mode)
1187     {
1188       vam->async_errors += (retval < 0);
1189     }
1190   else
1191     {
1192       vam->retval = retval;
1193       if (retval == 0)
1194         errmsg ("next index %d", ntohl (mp->next_index));
1195       vam->result_ready = 1;
1196     }
1197 }
1198
1199 static void vl_api_add_node_next_reply_t_handler_json
1200   (vl_api_add_node_next_reply_t * mp)
1201 {
1202   vat_main_t *vam = &vat_main;
1203   vat_json_node_t node;
1204
1205   vat_json_init_object (&node);
1206   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1207   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1208
1209   vat_json_print (vam->ofp, &node);
1210   vat_json_free (&node);
1211
1212   vam->retval = ntohl (mp->retval);
1213   vam->result_ready = 1;
1214 }
1215
1216 static void vl_api_show_version_reply_t_handler
1217   (vl_api_show_version_reply_t * mp)
1218 {
1219   vat_main_t *vam = &vat_main;
1220   i32 retval = ntohl (mp->retval);
1221
1222   if (retval >= 0)
1223     {
1224       errmsg ("        program: %s", mp->program);
1225       errmsg ("        version: %s", mp->version);
1226       errmsg ("     build date: %s", mp->build_date);
1227       errmsg ("build directory: %s", mp->build_directory);
1228     }
1229   vam->retval = retval;
1230   vam->result_ready = 1;
1231 }
1232
1233 static void vl_api_show_version_reply_t_handler_json
1234   (vl_api_show_version_reply_t * mp)
1235 {
1236   vat_main_t *vam = &vat_main;
1237   vat_json_node_t node;
1238
1239   vat_json_init_object (&node);
1240   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1241   vat_json_object_add_string_copy (&node, "program", mp->program);
1242   vat_json_object_add_string_copy (&node, "version", mp->version);
1243   vat_json_object_add_string_copy (&node, "build_date", mp->build_date);
1244   vat_json_object_add_string_copy (&node, "build_directory",
1245                                    mp->build_directory);
1246
1247   vat_json_print (vam->ofp, &node);
1248   vat_json_free (&node);
1249
1250   vam->retval = ntohl (mp->retval);
1251   vam->result_ready = 1;
1252 }
1253
1254 static void
1255 vl_api_ip4_arp_event_t_handler (vl_api_ip4_arp_event_t * mp)
1256 {
1257   u32 sw_if_index = ntohl (mp->sw_if_index);
1258   errmsg ("arp %s event: pid %d address %U new mac %U sw_if_index %d\n",
1259           mp->mac_ip ? "mac/ip binding" : "address resolution",
1260           ntohl (mp->pid), format_ip4_address, &mp->address,
1261           format_ethernet_address, mp->new_mac, sw_if_index);
1262 }
1263
1264 static void
1265 vl_api_ip4_arp_event_t_handler_json (vl_api_ip4_arp_event_t * mp)
1266 {
1267   /* JSON output not supported */
1268 }
1269
1270 static void
1271 vl_api_ip6_nd_event_t_handler (vl_api_ip6_nd_event_t * mp)
1272 {
1273   u32 sw_if_index = ntohl (mp->sw_if_index);
1274   errmsg ("ip6 nd %s event: pid %d address %U new mac %U sw_if_index %d\n",
1275           mp->mac_ip ? "mac/ip binding" : "address resolution",
1276           ntohl (mp->pid), format_ip6_address, mp->address,
1277           format_ethernet_address, mp->new_mac, sw_if_index);
1278 }
1279
1280 static void
1281 vl_api_ip6_nd_event_t_handler_json (vl_api_ip6_nd_event_t * mp)
1282 {
1283   /* JSON output not supported */
1284 }
1285
1286 #define vl_api_bridge_domain_details_t_endian vl_noop_handler
1287 #define vl_api_bridge_domain_details_t_print vl_noop_handler
1288
1289 /*
1290  * Special-case: build the bridge domain table, maintain
1291  * the next bd id vbl.
1292  */
1293 static void vl_api_bridge_domain_details_t_handler
1294   (vl_api_bridge_domain_details_t * mp)
1295 {
1296   vat_main_t *vam = &vat_main;
1297   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1298   int i;
1299
1300   print (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-3s",
1301          " ID", "LRN", "FWD", "FLD", "BVI", "#IF");
1302
1303   print (vam->ofp, "%3d %3d %3d %3d %3d %3d",
1304          ntohl (mp->bd_id), mp->learn, mp->forward,
1305          mp->flood, ntohl (mp->bvi_sw_if_index), n_sw_ifs);
1306
1307   if (n_sw_ifs)
1308     {
1309       vl_api_bridge_domain_sw_if_t *sw_ifs;
1310       print (vam->ofp, "\n\n%s %s  %s", "sw_if_index", "SHG",
1311              "Interface Name");
1312
1313       sw_ifs = mp->sw_if_details;
1314       for (i = 0; i < n_sw_ifs; i++)
1315         {
1316           u8 *sw_if_name = 0;
1317           u32 sw_if_index;
1318           hash_pair_t *p;
1319
1320           sw_if_index = ntohl (sw_ifs->sw_if_index);
1321
1322           /* *INDENT-OFF* */
1323           hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1324                              ({
1325                                if ((u32) p->value[0] == sw_if_index)
1326                                  {
1327                                    sw_if_name = (u8 *)(p->key);
1328                                    break;
1329                                  }
1330                              }));
1331           /* *INDENT-ON* */
1332           print (vam->ofp, "%7d     %3d  %s", sw_if_index,
1333                  sw_ifs->shg, sw_if_name ? (char *) sw_if_name :
1334                  "sw_if_index not found!");
1335
1336           sw_ifs++;
1337         }
1338     }
1339 }
1340
1341 static void vl_api_bridge_domain_details_t_handler_json
1342   (vl_api_bridge_domain_details_t * mp)
1343 {
1344   vat_main_t *vam = &vat_main;
1345   vat_json_node_t *node, *array = NULL;
1346   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1347
1348   if (VAT_JSON_ARRAY != vam->json_tree.type)
1349     {
1350       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1351       vat_json_init_array (&vam->json_tree);
1352     }
1353   node = vat_json_array_add (&vam->json_tree);
1354
1355   vat_json_init_object (node);
1356   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1357   vat_json_object_add_uint (node, "flood", mp->flood);
1358   vat_json_object_add_uint (node, "forward", mp->forward);
1359   vat_json_object_add_uint (node, "learn", mp->learn);
1360   vat_json_object_add_uint (node, "bvi_sw_if_index",
1361                             ntohl (mp->bvi_sw_if_index));
1362   vat_json_object_add_uint (node, "n_sw_ifs", n_sw_ifs);
1363   array = vat_json_object_add (node, "sw_if");
1364   vat_json_init_array (array);
1365
1366
1367
1368   if (n_sw_ifs)
1369     {
1370       vl_api_bridge_domain_sw_if_t *sw_ifs;
1371       int i;
1372
1373       sw_ifs = mp->sw_if_details;
1374       for (i = 0; i < n_sw_ifs; i++)
1375         {
1376           node = vat_json_array_add (array);
1377           vat_json_init_object (node);
1378           vat_json_object_add_uint (node, "sw_if_index",
1379                                     ntohl (sw_ifs->sw_if_index));
1380           vat_json_object_add_uint (node, "shg", sw_ifs->shg);
1381           sw_ifs++;
1382         }
1383     }
1384 }
1385
1386 static void vl_api_control_ping_reply_t_handler
1387   (vl_api_control_ping_reply_t * mp)
1388 {
1389   vat_main_t *vam = &vat_main;
1390   i32 retval = ntohl (mp->retval);
1391   if (vam->async_mode)
1392     {
1393       vam->async_errors += (retval < 0);
1394     }
1395   else
1396     {
1397       vam->retval = retval;
1398       vam->result_ready = 1;
1399     }
1400 }
1401
1402 static void vl_api_control_ping_reply_t_handler_json
1403   (vl_api_control_ping_reply_t * mp)
1404 {
1405   vat_main_t *vam = &vat_main;
1406   i32 retval = ntohl (mp->retval);
1407
1408   if (VAT_JSON_NONE != vam->json_tree.type)
1409     {
1410       vat_json_print (vam->ofp, &vam->json_tree);
1411       vat_json_free (&vam->json_tree);
1412       vam->json_tree.type = VAT_JSON_NONE;
1413     }
1414   else
1415     {
1416       /* just print [] */
1417       vat_json_init_array (&vam->json_tree);
1418       vat_json_print (vam->ofp, &vam->json_tree);
1419       vam->json_tree.type = VAT_JSON_NONE;
1420     }
1421
1422   vam->retval = retval;
1423   vam->result_ready = 1;
1424 }
1425
1426 static void
1427   vl_api_bridge_domain_set_mac_age_reply_t_handler
1428   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1429 {
1430   vat_main_t *vam = &vat_main;
1431   i32 retval = ntohl (mp->retval);
1432   if (vam->async_mode)
1433     {
1434       vam->async_errors += (retval < 0);
1435     }
1436   else
1437     {
1438       vam->retval = retval;
1439       vam->result_ready = 1;
1440     }
1441 }
1442
1443 static void vl_api_bridge_domain_set_mac_age_reply_t_handler_json
1444   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1445 {
1446   vat_main_t *vam = &vat_main;
1447   vat_json_node_t node;
1448
1449   vat_json_init_object (&node);
1450   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1451
1452   vat_json_print (vam->ofp, &node);
1453   vat_json_free (&node);
1454
1455   vam->retval = ntohl (mp->retval);
1456   vam->result_ready = 1;
1457 }
1458
1459 static void
1460 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1461 {
1462   vat_main_t *vam = &vat_main;
1463   i32 retval = ntohl (mp->retval);
1464   if (vam->async_mode)
1465     {
1466       vam->async_errors += (retval < 0);
1467     }
1468   else
1469     {
1470       vam->retval = retval;
1471       vam->result_ready = 1;
1472     }
1473 }
1474
1475 static void vl_api_l2_flags_reply_t_handler_json
1476   (vl_api_l2_flags_reply_t * mp)
1477 {
1478   vat_main_t *vam = &vat_main;
1479   vat_json_node_t node;
1480
1481   vat_json_init_object (&node);
1482   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1483   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1484                             ntohl (mp->resulting_feature_bitmap));
1485
1486   vat_json_print (vam->ofp, &node);
1487   vat_json_free (&node);
1488
1489   vam->retval = ntohl (mp->retval);
1490   vam->result_ready = 1;
1491 }
1492
1493 static void vl_api_bridge_flags_reply_t_handler
1494   (vl_api_bridge_flags_reply_t * mp)
1495 {
1496   vat_main_t *vam = &vat_main;
1497   i32 retval = ntohl (mp->retval);
1498   if (vam->async_mode)
1499     {
1500       vam->async_errors += (retval < 0);
1501     }
1502   else
1503     {
1504       vam->retval = retval;
1505       vam->result_ready = 1;
1506     }
1507 }
1508
1509 static void vl_api_bridge_flags_reply_t_handler_json
1510   (vl_api_bridge_flags_reply_t * mp)
1511 {
1512   vat_main_t *vam = &vat_main;
1513   vat_json_node_t node;
1514
1515   vat_json_init_object (&node);
1516   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1517   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1518                             ntohl (mp->resulting_feature_bitmap));
1519
1520   vat_json_print (vam->ofp, &node);
1521   vat_json_free (&node);
1522
1523   vam->retval = ntohl (mp->retval);
1524   vam->result_ready = 1;
1525 }
1526
1527 static void vl_api_tap_connect_reply_t_handler
1528   (vl_api_tap_connect_reply_t * mp)
1529 {
1530   vat_main_t *vam = &vat_main;
1531   i32 retval = ntohl (mp->retval);
1532   if (vam->async_mode)
1533     {
1534       vam->async_errors += (retval < 0);
1535     }
1536   else
1537     {
1538       vam->retval = retval;
1539       vam->sw_if_index = ntohl (mp->sw_if_index);
1540       vam->result_ready = 1;
1541     }
1542
1543 }
1544
1545 static void vl_api_tap_connect_reply_t_handler_json
1546   (vl_api_tap_connect_reply_t * mp)
1547 {
1548   vat_main_t *vam = &vat_main;
1549   vat_json_node_t node;
1550
1551   vat_json_init_object (&node);
1552   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1553   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1554
1555   vat_json_print (vam->ofp, &node);
1556   vat_json_free (&node);
1557
1558   vam->retval = ntohl (mp->retval);
1559   vam->result_ready = 1;
1560
1561 }
1562
1563 static void
1564 vl_api_tap_modify_reply_t_handler (vl_api_tap_modify_reply_t * mp)
1565 {
1566   vat_main_t *vam = &vat_main;
1567   i32 retval = ntohl (mp->retval);
1568   if (vam->async_mode)
1569     {
1570       vam->async_errors += (retval < 0);
1571     }
1572   else
1573     {
1574       vam->retval = retval;
1575       vam->sw_if_index = ntohl (mp->sw_if_index);
1576       vam->result_ready = 1;
1577     }
1578 }
1579
1580 static void vl_api_tap_modify_reply_t_handler_json
1581   (vl_api_tap_modify_reply_t * mp)
1582 {
1583   vat_main_t *vam = &vat_main;
1584   vat_json_node_t node;
1585
1586   vat_json_init_object (&node);
1587   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1588   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1589
1590   vat_json_print (vam->ofp, &node);
1591   vat_json_free (&node);
1592
1593   vam->retval = ntohl (mp->retval);
1594   vam->result_ready = 1;
1595 }
1596
1597 static void
1598 vl_api_tap_delete_reply_t_handler (vl_api_tap_delete_reply_t * mp)
1599 {
1600   vat_main_t *vam = &vat_main;
1601   i32 retval = ntohl (mp->retval);
1602   if (vam->async_mode)
1603     {
1604       vam->async_errors += (retval < 0);
1605     }
1606   else
1607     {
1608       vam->retval = retval;
1609       vam->result_ready = 1;
1610     }
1611 }
1612
1613 static void vl_api_tap_delete_reply_t_handler_json
1614   (vl_api_tap_delete_reply_t * mp)
1615 {
1616   vat_main_t *vam = &vat_main;
1617   vat_json_node_t node;
1618
1619   vat_json_init_object (&node);
1620   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1621
1622   vat_json_print (vam->ofp, &node);
1623   vat_json_free (&node);
1624
1625   vam->retval = ntohl (mp->retval);
1626   vam->result_ready = 1;
1627 }
1628
1629 static void vl_api_mpls_tunnel_add_del_reply_t_handler
1630   (vl_api_mpls_tunnel_add_del_reply_t * mp)
1631 {
1632   vat_main_t *vam = &vat_main;
1633   i32 retval = ntohl (mp->retval);
1634   if (vam->async_mode)
1635     {
1636       vam->async_errors += (retval < 0);
1637     }
1638   else
1639     {
1640       vam->retval = retval;
1641       vam->result_ready = 1;
1642     }
1643 }
1644
1645 static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
1646   (vl_api_mpls_tunnel_add_del_reply_t * mp)
1647 {
1648   vat_main_t *vam = &vat_main;
1649   vat_json_node_t node;
1650
1651   vat_json_init_object (&node);
1652   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1653   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
1654                             ntohl (mp->sw_if_index));
1655
1656   vat_json_print (vam->ofp, &node);
1657   vat_json_free (&node);
1658
1659   vam->retval = ntohl (mp->retval);
1660   vam->result_ready = 1;
1661 }
1662
1663 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
1664   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1665 {
1666   vat_main_t *vam = &vat_main;
1667   i32 retval = ntohl (mp->retval);
1668   if (vam->async_mode)
1669     {
1670       vam->async_errors += (retval < 0);
1671     }
1672   else
1673     {
1674       vam->retval = retval;
1675       vam->sw_if_index = ntohl (mp->sw_if_index);
1676       vam->result_ready = 1;
1677     }
1678 }
1679
1680 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
1681   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1682 {
1683   vat_main_t *vam = &vat_main;
1684   vat_json_node_t node;
1685
1686   vat_json_init_object (&node);
1687   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1688   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1689
1690   vat_json_print (vam->ofp, &node);
1691   vat_json_free (&node);
1692
1693   vam->retval = ntohl (mp->retval);
1694   vam->result_ready = 1;
1695 }
1696
1697 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler
1698   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
1699 {
1700   vat_main_t *vam = &vat_main;
1701   i32 retval = ntohl (mp->retval);
1702   if (vam->async_mode)
1703     {
1704       vam->async_errors += (retval < 0);
1705     }
1706   else
1707     {
1708       vam->retval = retval;
1709       vam->result_ready = 1;
1710     }
1711 }
1712
1713 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler_json
1714   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
1715 {
1716   vat_main_t *vam = &vat_main;
1717   vat_json_node_t node;
1718
1719   vat_json_init_object (&node);
1720   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1721   vat_json_object_add_uint (&node, "fwd_entry_index",
1722                             clib_net_to_host_u32 (mp->fwd_entry_index));
1723
1724   vat_json_print (vam->ofp, &node);
1725   vat_json_free (&node);
1726
1727   vam->retval = ntohl (mp->retval);
1728   vam->result_ready = 1;
1729 }
1730
1731 static void vl_api_one_add_del_locator_set_reply_t_handler
1732   (vl_api_one_add_del_locator_set_reply_t * mp)
1733 {
1734   vat_main_t *vam = &vat_main;
1735   i32 retval = ntohl (mp->retval);
1736   if (vam->async_mode)
1737     {
1738       vam->async_errors += (retval < 0);
1739     }
1740   else
1741     {
1742       vam->retval = retval;
1743       vam->result_ready = 1;
1744     }
1745 }
1746
1747 static void vl_api_one_add_del_locator_set_reply_t_handler_json
1748   (vl_api_one_add_del_locator_set_reply_t * mp)
1749 {
1750   vat_main_t *vam = &vat_main;
1751   vat_json_node_t node;
1752
1753   vat_json_init_object (&node);
1754   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1755   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
1756
1757   vat_json_print (vam->ofp, &node);
1758   vat_json_free (&node);
1759
1760   vam->retval = ntohl (mp->retval);
1761   vam->result_ready = 1;
1762 }
1763
1764 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
1765   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1766 {
1767   vat_main_t *vam = &vat_main;
1768   i32 retval = ntohl (mp->retval);
1769   if (vam->async_mode)
1770     {
1771       vam->async_errors += (retval < 0);
1772     }
1773   else
1774     {
1775       vam->retval = retval;
1776       vam->sw_if_index = ntohl (mp->sw_if_index);
1777       vam->result_ready = 1;
1778     }
1779 }
1780
1781 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
1782   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1783 {
1784   vat_main_t *vam = &vat_main;
1785   vat_json_node_t node;
1786
1787   vat_json_init_object (&node);
1788   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1789   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1790
1791   vat_json_print (vam->ofp, &node);
1792   vat_json_free (&node);
1793
1794   vam->retval = ntohl (mp->retval);
1795   vam->result_ready = 1;
1796 }
1797
1798 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler
1799   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
1800 {
1801   vat_main_t *vam = &vat_main;
1802   i32 retval = ntohl (mp->retval);
1803   if (vam->async_mode)
1804     {
1805       vam->async_errors += (retval < 0);
1806     }
1807   else
1808     {
1809       vam->retval = retval;
1810       vam->sw_if_index = ntohl (mp->sw_if_index);
1811       vam->result_ready = 1;
1812     }
1813 }
1814
1815 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler_json
1816   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
1817 {
1818   vat_main_t *vam = &vat_main;
1819   vat_json_node_t node;
1820
1821   vat_json_init_object (&node);
1822   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1823   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1824
1825   vat_json_print (vam->ofp, &node);
1826   vat_json_free (&node);
1827
1828   vam->retval = ntohl (mp->retval);
1829   vam->result_ready = 1;
1830 }
1831
1832 static void vl_api_gre_add_del_tunnel_reply_t_handler
1833   (vl_api_gre_add_del_tunnel_reply_t * mp)
1834 {
1835   vat_main_t *vam = &vat_main;
1836   i32 retval = ntohl (mp->retval);
1837   if (vam->async_mode)
1838     {
1839       vam->async_errors += (retval < 0);
1840     }
1841   else
1842     {
1843       vam->retval = retval;
1844       vam->sw_if_index = ntohl (mp->sw_if_index);
1845       vam->result_ready = 1;
1846     }
1847 }
1848
1849 static void vl_api_gre_add_del_tunnel_reply_t_handler_json
1850   (vl_api_gre_add_del_tunnel_reply_t * mp)
1851 {
1852   vat_main_t *vam = &vat_main;
1853   vat_json_node_t node;
1854
1855   vat_json_init_object (&node);
1856   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1857   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1858
1859   vat_json_print (vam->ofp, &node);
1860   vat_json_free (&node);
1861
1862   vam->retval = ntohl (mp->retval);
1863   vam->result_ready = 1;
1864 }
1865
1866 static void vl_api_create_vhost_user_if_reply_t_handler
1867   (vl_api_create_vhost_user_if_reply_t * mp)
1868 {
1869   vat_main_t *vam = &vat_main;
1870   i32 retval = ntohl (mp->retval);
1871   if (vam->async_mode)
1872     {
1873       vam->async_errors += (retval < 0);
1874     }
1875   else
1876     {
1877       vam->retval = retval;
1878       vam->sw_if_index = ntohl (mp->sw_if_index);
1879       vam->result_ready = 1;
1880     }
1881 }
1882
1883 static void vl_api_create_vhost_user_if_reply_t_handler_json
1884   (vl_api_create_vhost_user_if_reply_t * mp)
1885 {
1886   vat_main_t *vam = &vat_main;
1887   vat_json_node_t node;
1888
1889   vat_json_init_object (&node);
1890   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1891   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1892
1893   vat_json_print (vam->ofp, &node);
1894   vat_json_free (&node);
1895
1896   vam->retval = ntohl (mp->retval);
1897   vam->result_ready = 1;
1898 }
1899
1900 static void vl_api_ip_address_details_t_handler
1901   (vl_api_ip_address_details_t * mp)
1902 {
1903   vat_main_t *vam = &vat_main;
1904   static ip_address_details_t empty_ip_address_details = { {0} };
1905   ip_address_details_t *address = NULL;
1906   ip_details_t *current_ip_details = NULL;
1907   ip_details_t *details = NULL;
1908
1909   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
1910
1911   if (!details || vam->current_sw_if_index >= vec_len (details)
1912       || !details[vam->current_sw_if_index].present)
1913     {
1914       errmsg ("ip address details arrived but not stored");
1915       errmsg ("ip_dump should be called first");
1916       return;
1917     }
1918
1919   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
1920
1921 #define addresses (current_ip_details->addr)
1922
1923   vec_validate_init_empty (addresses, vec_len (addresses),
1924                            empty_ip_address_details);
1925
1926   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
1927
1928   clib_memcpy (&address->ip, &mp->ip, sizeof (address->ip));
1929   address->prefix_length = mp->prefix_length;
1930 #undef addresses
1931 }
1932
1933 static void vl_api_ip_address_details_t_handler_json
1934   (vl_api_ip_address_details_t * mp)
1935 {
1936   vat_main_t *vam = &vat_main;
1937   vat_json_node_t *node = NULL;
1938   struct in6_addr ip6;
1939   struct in_addr ip4;
1940
1941   if (VAT_JSON_ARRAY != vam->json_tree.type)
1942     {
1943       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1944       vat_json_init_array (&vam->json_tree);
1945     }
1946   node = vat_json_array_add (&vam->json_tree);
1947
1948   vat_json_init_object (node);
1949   if (vam->is_ipv6)
1950     {
1951       clib_memcpy (&ip6, mp->ip, sizeof (ip6));
1952       vat_json_object_add_ip6 (node, "ip", ip6);
1953     }
1954   else
1955     {
1956       clib_memcpy (&ip4, mp->ip, sizeof (ip4));
1957       vat_json_object_add_ip4 (node, "ip", ip4);
1958     }
1959   vat_json_object_add_uint (node, "prefix_length", mp->prefix_length);
1960 }
1961
1962 static void
1963 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
1964 {
1965   vat_main_t *vam = &vat_main;
1966   static ip_details_t empty_ip_details = { 0 };
1967   ip_details_t *ip = NULL;
1968   u32 sw_if_index = ~0;
1969
1970   sw_if_index = ntohl (mp->sw_if_index);
1971
1972   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1973                            sw_if_index, empty_ip_details);
1974
1975   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1976                          sw_if_index);
1977
1978   ip->present = 1;
1979 }
1980
1981 static void
1982 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
1983 {
1984   vat_main_t *vam = &vat_main;
1985
1986   if (VAT_JSON_ARRAY != vam->json_tree.type)
1987     {
1988       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1989       vat_json_init_array (&vam->json_tree);
1990     }
1991   vat_json_array_add_uint (&vam->json_tree,
1992                            clib_net_to_host_u32 (mp->sw_if_index));
1993 }
1994
1995 static void vl_api_map_domain_details_t_handler_json
1996   (vl_api_map_domain_details_t * mp)
1997 {
1998   vat_json_node_t *node = NULL;
1999   vat_main_t *vam = &vat_main;
2000   struct in6_addr ip6;
2001   struct in_addr ip4;
2002
2003   if (VAT_JSON_ARRAY != vam->json_tree.type)
2004     {
2005       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2006       vat_json_init_array (&vam->json_tree);
2007     }
2008
2009   node = vat_json_array_add (&vam->json_tree);
2010   vat_json_init_object (node);
2011
2012   vat_json_object_add_uint (node, "domain_index",
2013                             clib_net_to_host_u32 (mp->domain_index));
2014   clib_memcpy (&ip6, mp->ip6_prefix, sizeof (ip6));
2015   vat_json_object_add_ip6 (node, "ip6_prefix", ip6);
2016   clib_memcpy (&ip4, mp->ip4_prefix, sizeof (ip4));
2017   vat_json_object_add_ip4 (node, "ip4_prefix", ip4);
2018   clib_memcpy (&ip6, mp->ip6_src, sizeof (ip6));
2019   vat_json_object_add_ip6 (node, "ip6_src", ip6);
2020   vat_json_object_add_int (node, "ip6_prefix_len", mp->ip6_prefix_len);
2021   vat_json_object_add_int (node, "ip4_prefix_len", mp->ip4_prefix_len);
2022   vat_json_object_add_int (node, "ip6_src_len", mp->ip6_src_len);
2023   vat_json_object_add_int (node, "ea_bits_len", mp->ea_bits_len);
2024   vat_json_object_add_int (node, "psid_offset", mp->psid_offset);
2025   vat_json_object_add_int (node, "psid_length", mp->psid_length);
2026   vat_json_object_add_uint (node, "flags", mp->flags);
2027   vat_json_object_add_uint (node, "mtu", clib_net_to_host_u16 (mp->mtu));
2028   vat_json_object_add_int (node, "is_translation", mp->is_translation);
2029 }
2030
2031 static void vl_api_map_domain_details_t_handler
2032   (vl_api_map_domain_details_t * mp)
2033 {
2034   vat_main_t *vam = &vat_main;
2035
2036   if (mp->is_translation)
2037     {
2038       print (vam->ofp,
2039              "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U/%d (ip6-src) index: %u",
2040              format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
2041              format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
2042              format_ip6_address, mp->ip6_src, mp->ip6_src_len,
2043              clib_net_to_host_u32 (mp->domain_index));
2044     }
2045   else
2046     {
2047       print (vam->ofp,
2048              "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U (ip6-src) index: %u",
2049              format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
2050              format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
2051              format_ip6_address, mp->ip6_src,
2052              clib_net_to_host_u32 (mp->domain_index));
2053     }
2054   print (vam->ofp, "  ea-len %d psid-offset %d psid-len %d mtu %d %s",
2055          mp->ea_bits_len, mp->psid_offset, mp->psid_length, mp->mtu,
2056          mp->is_translation ? "map-t" : "");
2057 }
2058
2059 static void vl_api_map_rule_details_t_handler_json
2060   (vl_api_map_rule_details_t * mp)
2061 {
2062   struct in6_addr ip6;
2063   vat_json_node_t *node = NULL;
2064   vat_main_t *vam = &vat_main;
2065
2066   if (VAT_JSON_ARRAY != vam->json_tree.type)
2067     {
2068       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2069       vat_json_init_array (&vam->json_tree);
2070     }
2071
2072   node = vat_json_array_add (&vam->json_tree);
2073   vat_json_init_object (node);
2074
2075   vat_json_object_add_uint (node, "psid", clib_net_to_host_u16 (mp->psid));
2076   clib_memcpy (&ip6, mp->ip6_dst, sizeof (ip6));
2077   vat_json_object_add_ip6 (node, "ip6_dst", ip6);
2078 }
2079
2080 static void
2081 vl_api_map_rule_details_t_handler (vl_api_map_rule_details_t * mp)
2082 {
2083   vat_main_t *vam = &vat_main;
2084   print (vam->ofp, " %d (psid) %U (ip6-dst)",
2085          clib_net_to_host_u16 (mp->psid), format_ip6_address, mp->ip6_dst);
2086 }
2087
2088 static void
2089 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
2090 {
2091   errmsg ("DHCP compl event: pid %d %s hostname %s host_addr %U "
2092           "router_addr %U host_mac %U",
2093           ntohl (mp->pid), mp->is_ipv6 ? "ipv6" : "ipv4", mp->hostname,
2094           format_ip4_address, &mp->host_address,
2095           format_ip4_address, &mp->router_address,
2096           format_ethernet_address, mp->host_mac);
2097 }
2098
2099 static void vl_api_dhcp_compl_event_t_handler_json
2100   (vl_api_dhcp_compl_event_t * mp)
2101 {
2102   /* JSON output not supported */
2103 }
2104
2105 static void
2106 set_simple_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
2107                               u32 counter)
2108 {
2109   vat_main_t *vam = &vat_main;
2110   static u64 default_counter = 0;
2111
2112   vec_validate_init_empty (vam->simple_interface_counters, vnet_counter_type,
2113                            NULL);
2114   vec_validate_init_empty (vam->simple_interface_counters[vnet_counter_type],
2115                            sw_if_index, default_counter);
2116   vam->simple_interface_counters[vnet_counter_type][sw_if_index] = counter;
2117 }
2118
2119 static void
2120 set_combined_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
2121                                 interface_counter_t counter)
2122 {
2123   vat_main_t *vam = &vat_main;
2124   static interface_counter_t default_counter = { 0, };
2125
2126   vec_validate_init_empty (vam->combined_interface_counters,
2127                            vnet_counter_type, NULL);
2128   vec_validate_init_empty (vam->combined_interface_counters
2129                            [vnet_counter_type], sw_if_index, default_counter);
2130   vam->combined_interface_counters[vnet_counter_type][sw_if_index] = counter;
2131 }
2132
2133 static void vl_api_vnet_interface_simple_counters_t_handler
2134   (vl_api_vnet_interface_simple_counters_t * mp)
2135 {
2136   /* not supported */
2137 }
2138
2139 static void vl_api_vnet_interface_combined_counters_t_handler
2140   (vl_api_vnet_interface_combined_counters_t * mp)
2141 {
2142   /* not supported */
2143 }
2144
2145 static void vl_api_vnet_interface_simple_counters_t_handler_json
2146   (vl_api_vnet_interface_simple_counters_t * mp)
2147 {
2148   u64 *v_packets;
2149   u64 packets;
2150   u32 count;
2151   u32 first_sw_if_index;
2152   int i;
2153
2154   count = ntohl (mp->count);
2155   first_sw_if_index = ntohl (mp->first_sw_if_index);
2156
2157   v_packets = (u64 *) & mp->data;
2158   for (i = 0; i < count; i++)
2159     {
2160       packets = clib_net_to_host_u64 (clib_mem_unaligned (v_packets, u64));
2161       set_simple_interface_counter (mp->vnet_counter_type,
2162                                     first_sw_if_index + i, packets);
2163       v_packets++;
2164     }
2165 }
2166
2167 static void vl_api_vnet_interface_combined_counters_t_handler_json
2168   (vl_api_vnet_interface_combined_counters_t * mp)
2169 {
2170   interface_counter_t counter;
2171   vlib_counter_t *v;
2172   u32 first_sw_if_index;
2173   int i;
2174   u32 count;
2175
2176   count = ntohl (mp->count);
2177   first_sw_if_index = ntohl (mp->first_sw_if_index);
2178
2179   v = (vlib_counter_t *) & mp->data;
2180   for (i = 0; i < count; i++)
2181     {
2182       counter.packets =
2183         clib_net_to_host_u64 (clib_mem_unaligned (&v->packets, u64));
2184       counter.bytes =
2185         clib_net_to_host_u64 (clib_mem_unaligned (&v->bytes, u64));
2186       set_combined_interface_counter (mp->vnet_counter_type,
2187                                       first_sw_if_index + i, counter);
2188       v++;
2189     }
2190 }
2191
2192 static u32
2193 ip4_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2194 {
2195   vat_main_t *vam = &vat_main;
2196   u32 i;
2197
2198   for (i = 0; i < vec_len (vam->ip4_fib_counters_vrf_id_by_index); i++)
2199     {
2200       if (vam->ip4_fib_counters_vrf_id_by_index[i] == vrf_id)
2201         {
2202           return i;
2203         }
2204     }
2205   return ~0;
2206 }
2207
2208 static u32
2209 ip6_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2210 {
2211   vat_main_t *vam = &vat_main;
2212   u32 i;
2213
2214   for (i = 0; i < vec_len (vam->ip6_fib_counters_vrf_id_by_index); i++)
2215     {
2216       if (vam->ip6_fib_counters_vrf_id_by_index[i] == vrf_id)
2217         {
2218           return i;
2219         }
2220     }
2221   return ~0;
2222 }
2223
2224 static void vl_api_vnet_ip4_fib_counters_t_handler
2225   (vl_api_vnet_ip4_fib_counters_t * mp)
2226 {
2227   /* not supported */
2228 }
2229
2230 static void vl_api_vnet_ip4_fib_counters_t_handler_json
2231   (vl_api_vnet_ip4_fib_counters_t * mp)
2232 {
2233   vat_main_t *vam = &vat_main;
2234   vl_api_ip4_fib_counter_t *v;
2235   ip4_fib_counter_t *counter;
2236   struct in_addr ip4;
2237   u32 vrf_id;
2238   u32 vrf_index;
2239   u32 count;
2240   int i;
2241
2242   vrf_id = ntohl (mp->vrf_id);
2243   vrf_index = ip4_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2244   if (~0 == vrf_index)
2245     {
2246       vrf_index = vec_len (vam->ip4_fib_counters_vrf_id_by_index);
2247       vec_validate (vam->ip4_fib_counters_vrf_id_by_index, vrf_index);
2248       vam->ip4_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2249       vec_validate (vam->ip4_fib_counters, vrf_index);
2250       vam->ip4_fib_counters[vrf_index] = NULL;
2251     }
2252
2253   vec_free (vam->ip4_fib_counters[vrf_index]);
2254   v = (vl_api_ip4_fib_counter_t *) & mp->c;
2255   count = ntohl (mp->count);
2256   for (i = 0; i < count; i++)
2257     {
2258       vec_validate (vam->ip4_fib_counters[vrf_index], i);
2259       counter = &vam->ip4_fib_counters[vrf_index][i];
2260       clib_memcpy (&ip4, &v->address, sizeof (ip4));
2261       counter->address = ip4;
2262       counter->address_length = v->address_length;
2263       counter->packets = clib_net_to_host_u64 (v->packets);
2264       counter->bytes = clib_net_to_host_u64 (v->bytes);
2265       v++;
2266     }
2267 }
2268
2269 static void vl_api_vnet_ip4_nbr_counters_t_handler
2270   (vl_api_vnet_ip4_nbr_counters_t * mp)
2271 {
2272   /* not supported */
2273 }
2274
2275 static void vl_api_vnet_ip4_nbr_counters_t_handler_json
2276   (vl_api_vnet_ip4_nbr_counters_t * mp)
2277 {
2278   vat_main_t *vam = &vat_main;
2279   vl_api_ip4_nbr_counter_t *v;
2280   ip4_nbr_counter_t *counter;
2281   u32 sw_if_index;
2282   u32 count;
2283   int i;
2284
2285   sw_if_index = ntohl (mp->sw_if_index);
2286   count = ntohl (mp->count);
2287   vec_validate (vam->ip4_nbr_counters, sw_if_index);
2288
2289   if (mp->begin)
2290     vec_free (vam->ip4_nbr_counters[sw_if_index]);
2291
2292   v = (vl_api_ip4_nbr_counter_t *) & mp->c;
2293   for (i = 0; i < count; i++)
2294     {
2295       vec_validate (vam->ip4_nbr_counters[sw_if_index], i);
2296       counter = &vam->ip4_nbr_counters[sw_if_index][i];
2297       counter->address.s_addr = v->address;
2298       counter->packets = clib_net_to_host_u64 (v->packets);
2299       counter->bytes = clib_net_to_host_u64 (v->bytes);
2300       counter->linkt = v->link_type;
2301       v++;
2302     }
2303 }
2304
2305 static void vl_api_vnet_ip6_fib_counters_t_handler
2306   (vl_api_vnet_ip6_fib_counters_t * mp)
2307 {
2308   /* not supported */
2309 }
2310
2311 static void vl_api_vnet_ip6_fib_counters_t_handler_json
2312   (vl_api_vnet_ip6_fib_counters_t * mp)
2313 {
2314   vat_main_t *vam = &vat_main;
2315   vl_api_ip6_fib_counter_t *v;
2316   ip6_fib_counter_t *counter;
2317   struct in6_addr ip6;
2318   u32 vrf_id;
2319   u32 vrf_index;
2320   u32 count;
2321   int i;
2322
2323   vrf_id = ntohl (mp->vrf_id);
2324   vrf_index = ip6_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2325   if (~0 == vrf_index)
2326     {
2327       vrf_index = vec_len (vam->ip6_fib_counters_vrf_id_by_index);
2328       vec_validate (vam->ip6_fib_counters_vrf_id_by_index, vrf_index);
2329       vam->ip6_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2330       vec_validate (vam->ip6_fib_counters, vrf_index);
2331       vam->ip6_fib_counters[vrf_index] = NULL;
2332     }
2333
2334   vec_free (vam->ip6_fib_counters[vrf_index]);
2335   v = (vl_api_ip6_fib_counter_t *) & mp->c;
2336   count = ntohl (mp->count);
2337   for (i = 0; i < count; i++)
2338     {
2339       vec_validate (vam->ip6_fib_counters[vrf_index], i);
2340       counter = &vam->ip6_fib_counters[vrf_index][i];
2341       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2342       counter->address = ip6;
2343       counter->address_length = v->address_length;
2344       counter->packets = clib_net_to_host_u64 (v->packets);
2345       counter->bytes = clib_net_to_host_u64 (v->bytes);
2346       v++;
2347     }
2348 }
2349
2350 static void vl_api_vnet_ip6_nbr_counters_t_handler
2351   (vl_api_vnet_ip6_nbr_counters_t * mp)
2352 {
2353   /* not supported */
2354 }
2355
2356 static void vl_api_vnet_ip6_nbr_counters_t_handler_json
2357   (vl_api_vnet_ip6_nbr_counters_t * mp)
2358 {
2359   vat_main_t *vam = &vat_main;
2360   vl_api_ip6_nbr_counter_t *v;
2361   ip6_nbr_counter_t *counter;
2362   struct in6_addr ip6;
2363   u32 sw_if_index;
2364   u32 count;
2365   int i;
2366
2367   sw_if_index = ntohl (mp->sw_if_index);
2368   count = ntohl (mp->count);
2369   vec_validate (vam->ip6_nbr_counters, sw_if_index);
2370
2371   if (mp->begin)
2372     vec_free (vam->ip6_nbr_counters[sw_if_index]);
2373
2374   v = (vl_api_ip6_nbr_counter_t *) & mp->c;
2375   for (i = 0; i < count; i++)
2376     {
2377       vec_validate (vam->ip6_nbr_counters[sw_if_index], i);
2378       counter = &vam->ip6_nbr_counters[sw_if_index][i];
2379       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2380       counter->address = ip6;
2381       counter->packets = clib_net_to_host_u64 (v->packets);
2382       counter->bytes = clib_net_to_host_u64 (v->bytes);
2383       v++;
2384     }
2385 }
2386
2387 static void vl_api_get_first_msg_id_reply_t_handler
2388   (vl_api_get_first_msg_id_reply_t * mp)
2389 {
2390   vat_main_t *vam = &vat_main;
2391   i32 retval = ntohl (mp->retval);
2392
2393   if (vam->async_mode)
2394     {
2395       vam->async_errors += (retval < 0);
2396     }
2397   else
2398     {
2399       vam->retval = retval;
2400       vam->result_ready = 1;
2401     }
2402   if (retval >= 0)
2403     {
2404       errmsg ("first message id %d", ntohs (mp->first_msg_id));
2405     }
2406 }
2407
2408 static void vl_api_get_first_msg_id_reply_t_handler_json
2409   (vl_api_get_first_msg_id_reply_t * mp)
2410 {
2411   vat_main_t *vam = &vat_main;
2412   vat_json_node_t node;
2413
2414   vat_json_init_object (&node);
2415   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2416   vat_json_object_add_uint (&node, "first_msg_id",
2417                             (uint) ntohs (mp->first_msg_id));
2418
2419   vat_json_print (vam->ofp, &node);
2420   vat_json_free (&node);
2421
2422   vam->retval = ntohl (mp->retval);
2423   vam->result_ready = 1;
2424 }
2425
2426 static void vl_api_get_node_graph_reply_t_handler
2427   (vl_api_get_node_graph_reply_t * mp)
2428 {
2429   vat_main_t *vam = &vat_main;
2430   api_main_t *am = &api_main;
2431   i32 retval = ntohl (mp->retval);
2432   u8 *pvt_copy, *reply;
2433   void *oldheap;
2434   vlib_node_t *node;
2435   int i;
2436
2437   if (vam->async_mode)
2438     {
2439       vam->async_errors += (retval < 0);
2440     }
2441   else
2442     {
2443       vam->retval = retval;
2444       vam->result_ready = 1;
2445     }
2446
2447   /* "Should never happen..." */
2448   if (retval != 0)
2449     return;
2450
2451   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2452   pvt_copy = vec_dup (reply);
2453
2454   /* Toss the shared-memory original... */
2455   pthread_mutex_lock (&am->vlib_rp->mutex);
2456   oldheap = svm_push_data_heap (am->vlib_rp);
2457
2458   vec_free (reply);
2459
2460   svm_pop_heap (oldheap);
2461   pthread_mutex_unlock (&am->vlib_rp->mutex);
2462
2463   if (vam->graph_nodes)
2464     {
2465       hash_free (vam->graph_node_index_by_name);
2466
2467       for (i = 0; i < vec_len (vam->graph_nodes); i++)
2468         {
2469           node = vam->graph_nodes[i];
2470           vec_free (node->name);
2471           vec_free (node->next_nodes);
2472           vec_free (node);
2473         }
2474       vec_free (vam->graph_nodes);
2475     }
2476
2477   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2478   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2479   vec_free (pvt_copy);
2480
2481   for (i = 0; i < vec_len (vam->graph_nodes); i++)
2482     {
2483       node = vam->graph_nodes[i];
2484       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2485     }
2486 }
2487
2488 static void vl_api_get_node_graph_reply_t_handler_json
2489   (vl_api_get_node_graph_reply_t * mp)
2490 {
2491   vat_main_t *vam = &vat_main;
2492   api_main_t *am = &api_main;
2493   void *oldheap;
2494   vat_json_node_t node;
2495   u8 *reply;
2496
2497   /* $$$$ make this real? */
2498   vat_json_init_object (&node);
2499   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2500   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2501
2502   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2503
2504   /* Toss the shared-memory original... */
2505   pthread_mutex_lock (&am->vlib_rp->mutex);
2506   oldheap = svm_push_data_heap (am->vlib_rp);
2507
2508   vec_free (reply);
2509
2510   svm_pop_heap (oldheap);
2511   pthread_mutex_unlock (&am->vlib_rp->mutex);
2512
2513   vat_json_print (vam->ofp, &node);
2514   vat_json_free (&node);
2515
2516   vam->retval = ntohl (mp->retval);
2517   vam->result_ready = 1;
2518 }
2519
2520 static void
2521 vl_api_one_locator_details_t_handler (vl_api_one_locator_details_t * mp)
2522 {
2523   vat_main_t *vam = &vat_main;
2524   u8 *s = 0;
2525
2526   if (mp->local)
2527     {
2528       s = format (s, "%=16d%=16d%=16d",
2529                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
2530     }
2531   else
2532     {
2533       s = format (s, "%=16U%=16d%=16d",
2534                   mp->is_ipv6 ? format_ip6_address :
2535                   format_ip4_address,
2536                   mp->ip_address, mp->priority, mp->weight);
2537     }
2538
2539   print (vam->ofp, "%v", s);
2540   vec_free (s);
2541 }
2542
2543 static void
2544 vl_api_one_locator_details_t_handler_json (vl_api_one_locator_details_t * mp)
2545 {
2546   vat_main_t *vam = &vat_main;
2547   vat_json_node_t *node = NULL;
2548   struct in6_addr ip6;
2549   struct in_addr ip4;
2550
2551   if (VAT_JSON_ARRAY != vam->json_tree.type)
2552     {
2553       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2554       vat_json_init_array (&vam->json_tree);
2555     }
2556   node = vat_json_array_add (&vam->json_tree);
2557   vat_json_init_object (node);
2558
2559   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2560   vat_json_object_add_uint (node, "priority", mp->priority);
2561   vat_json_object_add_uint (node, "weight", mp->weight);
2562
2563   if (mp->local)
2564     vat_json_object_add_uint (node, "sw_if_index",
2565                               clib_net_to_host_u32 (mp->sw_if_index));
2566   else
2567     {
2568       if (mp->is_ipv6)
2569         {
2570           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2571           vat_json_object_add_ip6 (node, "address", ip6);
2572         }
2573       else
2574         {
2575           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2576           vat_json_object_add_ip4 (node, "address", ip4);
2577         }
2578     }
2579 }
2580
2581 static void
2582 vl_api_one_locator_set_details_t_handler (vl_api_one_locator_set_details_t *
2583                                           mp)
2584 {
2585   vat_main_t *vam = &vat_main;
2586   u8 *ls_name = 0;
2587
2588   ls_name = format (0, "%s", mp->ls_name);
2589
2590   print (vam->ofp, "%=10d%=15v", clib_net_to_host_u32 (mp->ls_index),
2591          ls_name);
2592   vec_free (ls_name);
2593 }
2594
2595 static void
2596   vl_api_one_locator_set_details_t_handler_json
2597   (vl_api_one_locator_set_details_t * mp)
2598 {
2599   vat_main_t *vam = &vat_main;
2600   vat_json_node_t *node = 0;
2601   u8 *ls_name = 0;
2602
2603   ls_name = format (0, "%s", mp->ls_name);
2604   vec_add1 (ls_name, 0);
2605
2606   if (VAT_JSON_ARRAY != vam->json_tree.type)
2607     {
2608       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2609       vat_json_init_array (&vam->json_tree);
2610     }
2611   node = vat_json_array_add (&vam->json_tree);
2612
2613   vat_json_init_object (node);
2614   vat_json_object_add_string_copy (node, "ls_name", ls_name);
2615   vat_json_object_add_uint (node, "ls_index",
2616                             clib_net_to_host_u32 (mp->ls_index));
2617   vec_free (ls_name);
2618 }
2619
2620 typedef struct
2621 {
2622   u32 spi;
2623   u8 si;
2624 } __attribute__ ((__packed__)) lisp_nsh_api_t;
2625
2626 uword
2627 unformat_nsh_address (unformat_input_t * input, va_list * args)
2628 {
2629   lisp_nsh_api_t *nsh = va_arg (*args, lisp_nsh_api_t *);
2630   return unformat (input, "SPI:%d SI:%d", &nsh->spi, &nsh->si);
2631 }
2632
2633 u8 *
2634 format_nsh_address_vat (u8 * s, va_list * args)
2635 {
2636   nsh_t *a = va_arg (*args, nsh_t *);
2637   return format (s, "SPI:%d SI:%d", clib_net_to_host_u32 (a->spi), a->si);
2638 }
2639
2640 static u8 *
2641 format_lisp_flat_eid (u8 * s, va_list * args)
2642 {
2643   u32 type = va_arg (*args, u32);
2644   u8 *eid = va_arg (*args, u8 *);
2645   u32 eid_len = va_arg (*args, u32);
2646
2647   switch (type)
2648     {
2649     case 0:
2650       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
2651     case 1:
2652       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
2653     case 2:
2654       return format (s, "%U", format_ethernet_address, eid);
2655     case 3:
2656       return format (s, "%U", format_nsh_address_vat, eid);
2657     }
2658   return 0;
2659 }
2660
2661 static u8 *
2662 format_lisp_eid_vat (u8 * s, va_list * args)
2663 {
2664   u32 type = va_arg (*args, u32);
2665   u8 *eid = va_arg (*args, u8 *);
2666   u32 eid_len = va_arg (*args, u32);
2667   u8 *seid = va_arg (*args, u8 *);
2668   u32 seid_len = va_arg (*args, u32);
2669   u32 is_src_dst = va_arg (*args, u32);
2670
2671   if (is_src_dst)
2672     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
2673
2674   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
2675
2676   return s;
2677 }
2678
2679 static void
2680 vl_api_one_eid_table_details_t_handler (vl_api_one_eid_table_details_t * mp)
2681 {
2682   vat_main_t *vam = &vat_main;
2683   u8 *s = 0, *eid = 0;
2684
2685   if (~0 == mp->locator_set_index)
2686     s = format (0, "action: %d", mp->action);
2687   else
2688     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
2689
2690   eid = format (0, "%U", format_lisp_eid_vat,
2691                 mp->eid_type,
2692                 mp->eid,
2693                 mp->eid_prefix_len,
2694                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2695   vec_add1 (eid, 0);
2696
2697   print (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s",
2698          clib_net_to_host_u32 (mp->vni),
2699          eid,
2700          mp->is_local ? "local" : "remote",
2701          s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
2702          clib_net_to_host_u16 (mp->key_id), mp->key);
2703
2704   vec_free (s);
2705   vec_free (eid);
2706 }
2707
2708 static void
2709 vl_api_one_eid_table_details_t_handler_json (vl_api_one_eid_table_details_t
2710                                              * mp)
2711 {
2712   vat_main_t *vam = &vat_main;
2713   vat_json_node_t *node = 0;
2714   u8 *eid = 0;
2715
2716   if (VAT_JSON_ARRAY != vam->json_tree.type)
2717     {
2718       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2719       vat_json_init_array (&vam->json_tree);
2720     }
2721   node = vat_json_array_add (&vam->json_tree);
2722
2723   vat_json_init_object (node);
2724   if (~0 == mp->locator_set_index)
2725     vat_json_object_add_uint (node, "action", mp->action);
2726   else
2727     vat_json_object_add_uint (node, "locator_set_index",
2728                               clib_net_to_host_u32 (mp->locator_set_index));
2729
2730   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
2731   if (mp->eid_type == 3)
2732     {
2733       vat_json_node_t *nsh_json = vat_json_object_add (node, "eid");
2734       vat_json_init_object (nsh_json);
2735       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) mp->eid;
2736       vat_json_object_add_uint (nsh_json, "spi",
2737                                 clib_net_to_host_u32 (nsh->spi));
2738       vat_json_object_add_uint (nsh_json, "si", nsh->si);
2739     }
2740   else
2741     {
2742       eid = format (0, "%U", format_lisp_eid_vat,
2743                     mp->eid_type,
2744                     mp->eid,
2745                     mp->eid_prefix_len,
2746                     mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2747       vec_add1 (eid, 0);
2748       vat_json_object_add_string_copy (node, "eid", eid);
2749       vec_free (eid);
2750     }
2751   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2752   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
2753   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
2754
2755   if (mp->key_id)
2756     {
2757       vat_json_object_add_uint (node, "key_id",
2758                                 clib_net_to_host_u16 (mp->key_id));
2759       vat_json_object_add_string_copy (node, "key", mp->key);
2760     }
2761 }
2762
2763 static void
2764 vl_api_one_stats_details_t_handler (vl_api_one_stats_details_t * mp)
2765 {
2766   vat_main_t *vam = &vat_main;
2767   u8 *seid = 0, *deid = 0;
2768   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
2769
2770   deid = format (0, "%U", format_lisp_eid_vat,
2771                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
2772
2773   seid = format (0, "%U", format_lisp_eid_vat,
2774                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
2775
2776   vec_add1 (deid, 0);
2777   vec_add1 (seid, 0);
2778
2779   if (mp->is_ip4)
2780     format_ip_address_fcn = format_ip4_address;
2781   else
2782     format_ip_address_fcn = format_ip6_address;
2783
2784
2785   print (vam->ofp, "([%d] %s %s) (%U %U) %u %u",
2786          clib_net_to_host_u32 (mp->vni),
2787          seid, deid,
2788          format_ip_address_fcn, mp->lloc,
2789          format_ip_address_fcn, mp->rloc,
2790          clib_net_to_host_u32 (mp->pkt_count),
2791          clib_net_to_host_u32 (mp->bytes));
2792
2793   vec_free (deid);
2794   vec_free (seid);
2795 }
2796
2797 static void
2798 vl_api_one_stats_details_t_handler_json (vl_api_one_stats_details_t * mp)
2799 {
2800   struct in6_addr ip6;
2801   struct in_addr ip4;
2802   vat_main_t *vam = &vat_main;
2803   vat_json_node_t *node = 0;
2804   u8 *deid = 0, *seid = 0;
2805
2806   if (VAT_JSON_ARRAY != vam->json_tree.type)
2807     {
2808       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2809       vat_json_init_array (&vam->json_tree);
2810     }
2811   node = vat_json_array_add (&vam->json_tree);
2812
2813   vat_json_init_object (node);
2814   deid = format (0, "%U", format_lisp_eid_vat,
2815                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
2816
2817   seid = format (0, "%U", format_lisp_eid_vat,
2818                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
2819
2820   vec_add1 (deid, 0);
2821   vec_add1 (seid, 0);
2822
2823   vat_json_object_add_string_copy (node, "seid", seid);
2824   vat_json_object_add_string_copy (node, "deid", deid);
2825   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2826
2827   if (mp->is_ip4)
2828     {
2829       clib_memcpy (&ip4, mp->lloc, sizeof (ip4));
2830       vat_json_object_add_ip4 (node, "lloc", ip4);
2831       clib_memcpy (&ip4, mp->rloc, sizeof (ip4));
2832       vat_json_object_add_ip4 (node, "rloc", ip4);
2833     }
2834   else
2835     {
2836       clib_memcpy (&ip6, mp->lloc, sizeof (ip6));
2837       vat_json_object_add_ip6 (node, "lloc", ip6);
2838       clib_memcpy (&ip6, mp->rloc, sizeof (ip6));
2839       vat_json_object_add_ip6 (node, "rloc", ip6);
2840     }
2841   vat_json_object_add_uint (node, "pkt_count",
2842                             clib_net_to_host_u32 (mp->pkt_count));
2843   vat_json_object_add_uint (node, "bytes", clib_net_to_host_u32 (mp->bytes));
2844
2845   vec_free (deid);
2846   vec_free (seid);
2847 }
2848
2849 static void
2850   vl_api_one_eid_table_map_details_t_handler
2851   (vl_api_one_eid_table_map_details_t * mp)
2852 {
2853   vat_main_t *vam = &vat_main;
2854
2855   u8 *line = format (0, "%=10d%=10d",
2856                      clib_net_to_host_u32 (mp->vni),
2857                      clib_net_to_host_u32 (mp->dp_table));
2858   print (vam->ofp, "%v", line);
2859   vec_free (line);
2860 }
2861
2862 static void
2863   vl_api_one_eid_table_map_details_t_handler_json
2864   (vl_api_one_eid_table_map_details_t * mp)
2865 {
2866   vat_main_t *vam = &vat_main;
2867   vat_json_node_t *node = NULL;
2868
2869   if (VAT_JSON_ARRAY != vam->json_tree.type)
2870     {
2871       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2872       vat_json_init_array (&vam->json_tree);
2873     }
2874   node = vat_json_array_add (&vam->json_tree);
2875   vat_json_init_object (node);
2876   vat_json_object_add_uint (node, "dp_table",
2877                             clib_net_to_host_u32 (mp->dp_table));
2878   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2879 }
2880
2881 static void
2882   vl_api_one_eid_table_vni_details_t_handler
2883   (vl_api_one_eid_table_vni_details_t * mp)
2884 {
2885   vat_main_t *vam = &vat_main;
2886
2887   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
2888   print (vam->ofp, "%v", line);
2889   vec_free (line);
2890 }
2891
2892 static void
2893   vl_api_one_eid_table_vni_details_t_handler_json
2894   (vl_api_one_eid_table_vni_details_t * mp)
2895 {
2896   vat_main_t *vam = &vat_main;
2897   vat_json_node_t *node = NULL;
2898
2899   if (VAT_JSON_ARRAY != vam->json_tree.type)
2900     {
2901       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2902       vat_json_init_array (&vam->json_tree);
2903     }
2904   node = vat_json_array_add (&vam->json_tree);
2905   vat_json_init_object (node);
2906   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2907 }
2908
2909 static void
2910   vl_api_show_one_map_register_state_reply_t_handler
2911   (vl_api_show_one_map_register_state_reply_t * mp)
2912 {
2913   vat_main_t *vam = &vat_main;
2914   int retval = clib_net_to_host_u32 (mp->retval);
2915
2916   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
2917
2918   vam->retval = retval;
2919   vam->result_ready = 1;
2920 }
2921
2922 static void
2923   vl_api_show_one_map_register_state_reply_t_handler_json
2924   (vl_api_show_one_map_register_state_reply_t * mp)
2925 {
2926   vat_main_t *vam = &vat_main;
2927   vat_json_node_t _node, *node = &_node;
2928   int retval = clib_net_to_host_u32 (mp->retval);
2929
2930   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
2931
2932   vat_json_init_object (node);
2933   vat_json_object_add_string_copy (node, "state", s);
2934
2935   vat_json_print (vam->ofp, node);
2936   vat_json_free (node);
2937
2938   vam->retval = retval;
2939   vam->result_ready = 1;
2940   vec_free (s);
2941 }
2942
2943 static void
2944   vl_api_show_one_rloc_probe_state_reply_t_handler
2945   (vl_api_show_one_rloc_probe_state_reply_t * mp)
2946 {
2947   vat_main_t *vam = &vat_main;
2948   int retval = clib_net_to_host_u32 (mp->retval);
2949
2950   if (retval)
2951     goto end;
2952
2953   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
2954 end:
2955   vam->retval = retval;
2956   vam->result_ready = 1;
2957 }
2958
2959 static void
2960   vl_api_show_one_rloc_probe_state_reply_t_handler_json
2961   (vl_api_show_one_rloc_probe_state_reply_t * mp)
2962 {
2963   vat_main_t *vam = &vat_main;
2964   vat_json_node_t _node, *node = &_node;
2965   int retval = clib_net_to_host_u32 (mp->retval);
2966
2967   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
2968   vat_json_init_object (node);
2969   vat_json_object_add_string_copy (node, "state", s);
2970
2971   vat_json_print (vam->ofp, node);
2972   vat_json_free (node);
2973
2974   vam->retval = retval;
2975   vam->result_ready = 1;
2976   vec_free (s);
2977 }
2978
2979 static void
2980   vl_api_show_one_stats_enable_disable_reply_t_handler
2981   (vl_api_show_one_stats_enable_disable_reply_t * mp)
2982 {
2983   vat_main_t *vam = &vat_main;
2984   int retval = clib_net_to_host_u32 (mp->retval);
2985
2986   if (retval)
2987     goto end;
2988
2989   print (vam->ofp, "%s", mp->is_en ? "enabled" : "disabled");
2990 end:
2991   vam->retval = retval;
2992   vam->result_ready = 1;
2993 }
2994
2995 static void
2996   vl_api_show_one_stats_enable_disable_reply_t_handler_json
2997   (vl_api_show_one_stats_enable_disable_reply_t * mp)
2998 {
2999   vat_main_t *vam = &vat_main;
3000   vat_json_node_t _node, *node = &_node;
3001   int retval = clib_net_to_host_u32 (mp->retval);
3002
3003   u8 *s = format (0, "%s", mp->is_en ? "enabled" : "disabled");
3004   vat_json_init_object (node);
3005   vat_json_object_add_string_copy (node, "state", s);
3006
3007   vat_json_print (vam->ofp, node);
3008   vat_json_free (node);
3009
3010   vam->retval = retval;
3011   vam->result_ready = 1;
3012   vec_free (s);
3013 }
3014
3015 static void
3016 api_gpe_fwd_entry_net_to_host (vl_api_gpe_fwd_entry_t * e)
3017 {
3018   e->dp_table = clib_net_to_host_u32 (e->dp_table);
3019   e->fwd_entry_index = clib_net_to_host_u32 (e->fwd_entry_index);
3020   e->vni = clib_net_to_host_u32 (e->vni);
3021 }
3022
3023 static void
3024   gpe_fwd_entries_get_reply_t_net_to_host
3025   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3026 {
3027   u32 i;
3028
3029   mp->count = clib_net_to_host_u32 (mp->count);
3030   for (i = 0; i < mp->count; i++)
3031     {
3032       api_gpe_fwd_entry_net_to_host (&mp->entries[i]);
3033     }
3034 }
3035
3036 static u8 *
3037 format_gpe_encap_mode (u8 * s, va_list * args)
3038 {
3039   u32 mode = va_arg (*args, u32);
3040
3041   switch (mode)
3042     {
3043     case 0:
3044       return format (s, "lisp");
3045     case 1:
3046       return format (s, "vxlan");
3047     }
3048   return 0;
3049 }
3050
3051 static void
3052   vl_api_gpe_get_encap_mode_reply_t_handler
3053   (vl_api_gpe_get_encap_mode_reply_t * mp)
3054 {
3055   vat_main_t *vam = &vat_main;
3056
3057   print (vam->ofp, "gpe mode: %U", format_gpe_encap_mode, mp->encap_mode);
3058   vam->retval = ntohl (mp->retval);
3059   vam->result_ready = 1;
3060 }
3061
3062 static void
3063   vl_api_gpe_get_encap_mode_reply_t_handler_json
3064   (vl_api_gpe_get_encap_mode_reply_t * mp)
3065 {
3066   vat_main_t *vam = &vat_main;
3067   vat_json_node_t node;
3068
3069   u8 *encap_mode = format (0, "%U", format_gpe_encap_mode, mp->encap_mode);
3070   vec_add1 (encap_mode, 0);
3071
3072   vat_json_init_object (&node);
3073   vat_json_object_add_string_copy (&node, "gpe_mode", encap_mode);
3074
3075   vec_free (encap_mode);
3076   vat_json_print (vam->ofp, &node);
3077   vat_json_free (&node);
3078
3079   vam->retval = ntohl (mp->retval);
3080   vam->result_ready = 1;
3081 }
3082
3083 static void
3084   vl_api_gpe_fwd_entry_path_details_t_handler
3085   (vl_api_gpe_fwd_entry_path_details_t * mp)
3086 {
3087   vat_main_t *vam = &vat_main;
3088   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3089
3090   if (mp->lcl_loc.is_ip4)
3091     format_ip_address_fcn = format_ip4_address;
3092   else
3093     format_ip_address_fcn = format_ip6_address;
3094
3095   print (vam->ofp, "w:%d %30U %30U", mp->rmt_loc.weight,
3096          format_ip_address_fcn, &mp->lcl_loc,
3097          format_ip_address_fcn, &mp->rmt_loc);
3098 }
3099
3100 static void
3101 lisp_fill_locator_node (vat_json_node_t * n, vl_api_gpe_locator_t * loc)
3102 {
3103   struct in6_addr ip6;
3104   struct in_addr ip4;
3105
3106   if (loc->is_ip4)
3107     {
3108       clib_memcpy (&ip4, loc->addr, sizeof (ip4));
3109       vat_json_object_add_ip4 (n, "address", ip4);
3110     }
3111   else
3112     {
3113       clib_memcpy (&ip6, loc->addr, sizeof (ip6));
3114       vat_json_object_add_ip6 (n, "address", ip6);
3115     }
3116   vat_json_object_add_uint (n, "weight", loc->weight);
3117 }
3118
3119 static void
3120   vl_api_gpe_fwd_entry_path_details_t_handler_json
3121   (vl_api_gpe_fwd_entry_path_details_t * mp)
3122 {
3123   vat_main_t *vam = &vat_main;
3124   vat_json_node_t *node = NULL;
3125   vat_json_node_t *loc_node;
3126
3127   if (VAT_JSON_ARRAY != vam->json_tree.type)
3128     {
3129       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3130       vat_json_init_array (&vam->json_tree);
3131     }
3132   node = vat_json_array_add (&vam->json_tree);
3133   vat_json_init_object (node);
3134
3135   loc_node = vat_json_object_add (node, "local_locator");
3136   vat_json_init_object (loc_node);
3137   lisp_fill_locator_node (loc_node, &mp->lcl_loc);
3138
3139   loc_node = vat_json_object_add (node, "remote_locator");
3140   vat_json_init_object (loc_node);
3141   lisp_fill_locator_node (loc_node, &mp->rmt_loc);
3142 }
3143
3144 static void
3145   vl_api_gpe_fwd_entries_get_reply_t_handler
3146   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3147 {
3148   vat_main_t *vam = &vat_main;
3149   u32 i;
3150   int retval = clib_net_to_host_u32 (mp->retval);
3151   vl_api_gpe_fwd_entry_t *e;
3152
3153   if (retval)
3154     goto end;
3155
3156   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3157
3158   for (i = 0; i < mp->count; i++)
3159     {
3160       e = &mp->entries[i];
3161       print (vam->ofp, "%10d %10d %U %40U", e->fwd_entry_index, e->dp_table,
3162              format_lisp_flat_eid, e->eid_type, e->leid, e->leid_prefix_len,
3163              format_lisp_flat_eid, e->eid_type, e->reid, e->reid_prefix_len);
3164     }
3165
3166 end:
3167   vam->retval = retval;
3168   vam->result_ready = 1;
3169 }
3170
3171 static void
3172   vl_api_gpe_fwd_entries_get_reply_t_handler_json
3173   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3174 {
3175   u8 *s = 0;
3176   vat_main_t *vam = &vat_main;
3177   vat_json_node_t *e = 0, root;
3178   u32 i;
3179   int retval = clib_net_to_host_u32 (mp->retval);
3180   vl_api_gpe_fwd_entry_t *fwd;
3181
3182   if (retval)
3183     goto end;
3184
3185   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3186   vat_json_init_array (&root);
3187
3188   for (i = 0; i < mp->count; i++)
3189     {
3190       e = vat_json_array_add (&root);
3191       fwd = &mp->entries[i];
3192
3193       vat_json_init_object (e);
3194       vat_json_object_add_int (e, "fwd_entry_index", fwd->fwd_entry_index);
3195       vat_json_object_add_int (e, "dp_table", fwd->dp_table);
3196       vat_json_object_add_int (e, "vni", fwd->vni);
3197       vat_json_object_add_int (e, "action", fwd->action);
3198
3199       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->leid,
3200                   fwd->leid_prefix_len);
3201       vec_add1 (s, 0);
3202       vat_json_object_add_string_copy (e, "leid", s);
3203       vec_free (s);
3204
3205       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->reid,
3206                   fwd->reid_prefix_len);
3207       vec_add1 (s, 0);
3208       vat_json_object_add_string_copy (e, "reid", s);
3209       vec_free (s);
3210     }
3211
3212   vat_json_print (vam->ofp, &root);
3213   vat_json_free (&root);
3214
3215 end:
3216   vam->retval = retval;
3217   vam->result_ready = 1;
3218 }
3219
3220 static void
3221   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler
3222   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3223 {
3224   vat_main_t *vam = &vat_main;
3225   u32 i, n;
3226   int retval = clib_net_to_host_u32 (mp->retval);
3227   vl_api_gpe_native_fwd_rpath_t *r;
3228
3229   if (retval)
3230     goto end;
3231
3232   n = clib_net_to_host_u32 (mp->count);
3233
3234   for (i = 0; i < n; i++)
3235     {
3236       r = &mp->entries[i];
3237       print (vam->ofp, "fib_index: %d sw_if_index %d nh %U",
3238              clib_net_to_host_u32 (r->fib_index),
3239              clib_net_to_host_u32 (r->nh_sw_if_index),
3240              r->is_ip4 ? format_ip4_address : format_ip6_address, r->nh_addr);
3241     }
3242
3243 end:
3244   vam->retval = retval;
3245   vam->result_ready = 1;
3246 }
3247
3248 static void
3249   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler_json
3250   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3251 {
3252   vat_main_t *vam = &vat_main;
3253   vat_json_node_t root, *e;
3254   u32 i, n;
3255   int retval = clib_net_to_host_u32 (mp->retval);
3256   vl_api_gpe_native_fwd_rpath_t *r;
3257   u8 *s;
3258
3259   if (retval)
3260     goto end;
3261
3262   n = clib_net_to_host_u32 (mp->count);
3263   vat_json_init_array (&root);
3264
3265   for (i = 0; i < n; i++)
3266     {
3267       e = vat_json_array_add (&root);
3268       vat_json_init_object (e);
3269       r = &mp->entries[i];
3270       s =
3271         format (0, "%U", r->is_ip4 ? format_ip4_address : format_ip6_address,
3272                 r->nh_addr);
3273       vec_add1 (s, 0);
3274       vat_json_object_add_string_copy (e, "ip4", s);
3275       vec_free (s);
3276
3277       vat_json_object_add_uint (e, "fib_index",
3278                                 clib_net_to_host_u32 (r->fib_index));
3279       vat_json_object_add_uint (e, "nh_sw_if_index",
3280                                 clib_net_to_host_u32 (r->nh_sw_if_index));
3281     }
3282
3283   vat_json_print (vam->ofp, &root);
3284   vat_json_free (&root);
3285
3286 end:
3287   vam->retval = retval;
3288   vam->result_ready = 1;
3289 }
3290
3291 static void
3292   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler
3293   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3294 {
3295   vat_main_t *vam = &vat_main;
3296   u32 i, n;
3297   int retval = clib_net_to_host_u32 (mp->retval);
3298
3299   if (retval)
3300     goto end;
3301
3302   n = clib_net_to_host_u32 (mp->count);
3303
3304   for (i = 0; i < n; i++)
3305     print (vam->ofp, "%d", clib_net_to_host_u32 (mp->vnis[i]));
3306
3307 end:
3308   vam->retval = retval;
3309   vam->result_ready = 1;
3310 }
3311
3312 static void
3313   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler_json
3314   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3315 {
3316   vat_main_t *vam = &vat_main;
3317   vat_json_node_t root;
3318   u32 i, n;
3319   int retval = clib_net_to_host_u32 (mp->retval);
3320
3321   if (retval)
3322     goto end;
3323
3324   n = clib_net_to_host_u32 (mp->count);
3325   vat_json_init_array (&root);
3326
3327   for (i = 0; i < n; i++)
3328     vat_json_array_add_uint (&root, clib_net_to_host_u32 (mp->vnis[i]));
3329
3330   vat_json_print (vam->ofp, &root);
3331   vat_json_free (&root);
3332
3333 end:
3334   vam->retval = retval;
3335   vam->result_ready = 1;
3336 }
3337
3338 static void
3339   vl_api_one_l2_arp_entries_get_reply_t_handler
3340   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3341 {
3342   vat_main_t *vam = &vat_main;
3343   u32 i, n;
3344   int retval = clib_net_to_host_u32 (mp->retval);
3345
3346   if (retval)
3347     goto end;
3348
3349   n = clib_net_to_host_u32 (mp->count);
3350
3351   for (i = 0; i < n; i++)
3352     print (vam->ofp, "%U -> %U", format_ip4_address, &mp->entries[i].ip4,
3353            format_ethernet_address, mp->entries[i].mac);
3354
3355 end:
3356   vam->retval = retval;
3357   vam->result_ready = 1;
3358 }
3359
3360 static void
3361   vl_api_one_l2_arp_entries_get_reply_t_handler_json
3362   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3363 {
3364   u8 *s = 0;
3365   vat_main_t *vam = &vat_main;
3366   vat_json_node_t *e = 0, root;
3367   u32 i, n;
3368   int retval = clib_net_to_host_u32 (mp->retval);
3369   vl_api_one_l2_arp_entry_t *arp_entry;
3370
3371   if (retval)
3372     goto end;
3373
3374   n = clib_net_to_host_u32 (mp->count);
3375   vat_json_init_array (&root);
3376
3377   for (i = 0; i < n; i++)
3378     {
3379       e = vat_json_array_add (&root);
3380       arp_entry = &mp->entries[i];
3381
3382       vat_json_init_object (e);
3383       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3384       vec_add1 (s, 0);
3385
3386       vat_json_object_add_string_copy (e, "mac", s);
3387       vec_free (s);
3388
3389       s = format (0, "%U", format_ip4_address, &arp_entry->ip4);
3390       vec_add1 (s, 0);
3391       vat_json_object_add_string_copy (e, "ip4", s);
3392       vec_free (s);
3393     }
3394
3395   vat_json_print (vam->ofp, &root);
3396   vat_json_free (&root);
3397
3398 end:
3399   vam->retval = retval;
3400   vam->result_ready = 1;
3401 }
3402
3403 static void
3404   vl_api_one_l2_arp_bd_get_reply_t_handler
3405   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3406 {
3407   vat_main_t *vam = &vat_main;
3408   u32 i, n;
3409   int retval = clib_net_to_host_u32 (mp->retval);
3410
3411   if (retval)
3412     goto end;
3413
3414   n = clib_net_to_host_u32 (mp->count);
3415
3416   for (i = 0; i < n; i++)
3417     {
3418       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3419     }
3420
3421 end:
3422   vam->retval = retval;
3423   vam->result_ready = 1;
3424 }
3425
3426 static void
3427   vl_api_one_l2_arp_bd_get_reply_t_handler_json
3428   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3429 {
3430   vat_main_t *vam = &vat_main;
3431   vat_json_node_t root;
3432   u32 i, n;
3433   int retval = clib_net_to_host_u32 (mp->retval);
3434
3435   if (retval)
3436     goto end;
3437
3438   n = clib_net_to_host_u32 (mp->count);
3439   vat_json_init_array (&root);
3440
3441   for (i = 0; i < n; i++)
3442     {
3443       vat_json_array_add_uint (&root,
3444                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3445     }
3446
3447   vat_json_print (vam->ofp, &root);
3448   vat_json_free (&root);
3449
3450 end:
3451   vam->retval = retval;
3452   vam->result_ready = 1;
3453 }
3454
3455 static void
3456   vl_api_one_adjacencies_get_reply_t_handler
3457   (vl_api_one_adjacencies_get_reply_t * mp)
3458 {
3459   vat_main_t *vam = &vat_main;
3460   u32 i, n;
3461   int retval = clib_net_to_host_u32 (mp->retval);
3462   vl_api_one_adjacency_t *a;
3463
3464   if (retval)
3465     goto end;
3466
3467   n = clib_net_to_host_u32 (mp->count);
3468
3469   for (i = 0; i < n; i++)
3470     {
3471       a = &mp->adjacencies[i];
3472       print (vam->ofp, "%U %40U",
3473              format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
3474              format_lisp_flat_eid, a->eid_type, a->reid, a->reid_prefix_len);
3475     }
3476
3477 end:
3478   vam->retval = retval;
3479   vam->result_ready = 1;
3480 }
3481
3482 static void
3483   vl_api_one_adjacencies_get_reply_t_handler_json
3484   (vl_api_one_adjacencies_get_reply_t * mp)
3485 {
3486   u8 *s = 0;
3487   vat_main_t *vam = &vat_main;
3488   vat_json_node_t *e = 0, root;
3489   u32 i, n;
3490   int retval = clib_net_to_host_u32 (mp->retval);
3491   vl_api_one_adjacency_t *a;
3492
3493   if (retval)
3494     goto end;
3495
3496   n = clib_net_to_host_u32 (mp->count);
3497   vat_json_init_array (&root);
3498
3499   for (i = 0; i < n; i++)
3500     {
3501       e = vat_json_array_add (&root);
3502       a = &mp->adjacencies[i];
3503
3504       vat_json_init_object (e);
3505       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
3506                   a->leid_prefix_len);
3507       vec_add1 (s, 0);
3508       vat_json_object_add_string_copy (e, "leid", s);
3509       vec_free (s);
3510
3511       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
3512                   a->reid_prefix_len);
3513       vec_add1 (s, 0);
3514       vat_json_object_add_string_copy (e, "reid", s);
3515       vec_free (s);
3516     }
3517
3518   vat_json_print (vam->ofp, &root);
3519   vat_json_free (&root);
3520
3521 end:
3522   vam->retval = retval;
3523   vam->result_ready = 1;
3524 }
3525
3526 static void
3527 vl_api_one_map_server_details_t_handler (vl_api_one_map_server_details_t * mp)
3528 {
3529   vat_main_t *vam = &vat_main;
3530
3531   print (vam->ofp, "%=20U",
3532          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
3533          mp->ip_address);
3534 }
3535
3536 static void
3537   vl_api_one_map_server_details_t_handler_json
3538   (vl_api_one_map_server_details_t * mp)
3539 {
3540   vat_main_t *vam = &vat_main;
3541   vat_json_node_t *node = NULL;
3542   struct in6_addr ip6;
3543   struct in_addr ip4;
3544
3545   if (VAT_JSON_ARRAY != vam->json_tree.type)
3546     {
3547       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3548       vat_json_init_array (&vam->json_tree);
3549     }
3550   node = vat_json_array_add (&vam->json_tree);
3551
3552   vat_json_init_object (node);
3553   if (mp->is_ipv6)
3554     {
3555       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
3556       vat_json_object_add_ip6 (node, "map-server", ip6);
3557     }
3558   else
3559     {
3560       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
3561       vat_json_object_add_ip4 (node, "map-server", ip4);
3562     }
3563 }
3564
3565 static void
3566 vl_api_one_map_resolver_details_t_handler (vl_api_one_map_resolver_details_t
3567                                            * mp)
3568 {
3569   vat_main_t *vam = &vat_main;
3570
3571   print (vam->ofp, "%=20U",
3572          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
3573          mp->ip_address);
3574 }
3575
3576 static void
3577   vl_api_one_map_resolver_details_t_handler_json
3578   (vl_api_one_map_resolver_details_t * mp)
3579 {
3580   vat_main_t *vam = &vat_main;
3581   vat_json_node_t *node = NULL;
3582   struct in6_addr ip6;
3583   struct in_addr ip4;
3584
3585   if (VAT_JSON_ARRAY != vam->json_tree.type)
3586     {
3587       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3588       vat_json_init_array (&vam->json_tree);
3589     }
3590   node = vat_json_array_add (&vam->json_tree);
3591
3592   vat_json_init_object (node);
3593   if (mp->is_ipv6)
3594     {
3595       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
3596       vat_json_object_add_ip6 (node, "map resolver", ip6);
3597     }
3598   else
3599     {
3600       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
3601       vat_json_object_add_ip4 (node, "map resolver", ip4);
3602     }
3603 }
3604
3605 static void
3606 vl_api_show_one_status_reply_t_handler (vl_api_show_one_status_reply_t * mp)
3607 {
3608   vat_main_t *vam = &vat_main;
3609   i32 retval = ntohl (mp->retval);
3610
3611   if (0 <= retval)
3612     {
3613       print (vam->ofp, "feature: %s\ngpe: %s",
3614              mp->feature_status ? "enabled" : "disabled",
3615              mp->gpe_status ? "enabled" : "disabled");
3616     }
3617
3618   vam->retval = retval;
3619   vam->result_ready = 1;
3620 }
3621
3622 static void
3623   vl_api_show_one_status_reply_t_handler_json
3624   (vl_api_show_one_status_reply_t * mp)
3625 {
3626   vat_main_t *vam = &vat_main;
3627   vat_json_node_t node;
3628   u8 *gpe_status = NULL;
3629   u8 *feature_status = NULL;
3630
3631   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
3632   feature_status = format (0, "%s",
3633                            mp->feature_status ? "enabled" : "disabled");
3634   vec_add1 (gpe_status, 0);
3635   vec_add1 (feature_status, 0);
3636
3637   vat_json_init_object (&node);
3638   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
3639   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
3640
3641   vec_free (gpe_status);
3642   vec_free (feature_status);
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
3652   vl_api_one_get_map_request_itr_rlocs_reply_t_handler
3653   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
3654 {
3655   vat_main_t *vam = &vat_main;
3656   i32 retval = ntohl (mp->retval);
3657
3658   if (retval >= 0)
3659     {
3660       print (vam->ofp, "%=20s", mp->locator_set_name);
3661     }
3662
3663   vam->retval = retval;
3664   vam->result_ready = 1;
3665 }
3666
3667 static void
3668   vl_api_one_get_map_request_itr_rlocs_reply_t_handler_json
3669   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
3670 {
3671   vat_main_t *vam = &vat_main;
3672   vat_json_node_t *node = NULL;
3673
3674   if (VAT_JSON_ARRAY != vam->json_tree.type)
3675     {
3676       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3677       vat_json_init_array (&vam->json_tree);
3678     }
3679   node = vat_json_array_add (&vam->json_tree);
3680
3681   vat_json_init_object (node);
3682   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
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 static u8 *
3692 format_lisp_map_request_mode (u8 * s, va_list * args)
3693 {
3694   u32 mode = va_arg (*args, u32);
3695
3696   switch (mode)
3697     {
3698     case 0:
3699       return format (0, "dst-only");
3700     case 1:
3701       return format (0, "src-dst");
3702     }
3703   return 0;
3704 }
3705
3706 static void
3707   vl_api_show_one_map_request_mode_reply_t_handler
3708   (vl_api_show_one_map_request_mode_reply_t * mp)
3709 {
3710   vat_main_t *vam = &vat_main;
3711   i32 retval = ntohl (mp->retval);
3712
3713   if (0 <= retval)
3714     {
3715       u32 mode = mp->mode;
3716       print (vam->ofp, "map_request_mode: %U",
3717              format_lisp_map_request_mode, mode);
3718     }
3719
3720   vam->retval = retval;
3721   vam->result_ready = 1;
3722 }
3723
3724 static void
3725   vl_api_show_one_map_request_mode_reply_t_handler_json
3726   (vl_api_show_one_map_request_mode_reply_t * mp)
3727 {
3728   vat_main_t *vam = &vat_main;
3729   vat_json_node_t node;
3730   u8 *s = 0;
3731   u32 mode;
3732
3733   mode = mp->mode;
3734   s = format (0, "%U", format_lisp_map_request_mode, mode);
3735   vec_add1 (s, 0);
3736
3737   vat_json_init_object (&node);
3738   vat_json_object_add_string_copy (&node, "map_request_mode", s);
3739   vat_json_print (vam->ofp, &node);
3740   vat_json_free (&node);
3741
3742   vec_free (s);
3743   vam->retval = ntohl (mp->retval);
3744   vam->result_ready = 1;
3745 }
3746
3747 static void
3748   vl_api_show_one_use_petr_reply_t_handler
3749   (vl_api_show_one_use_petr_reply_t * mp)
3750 {
3751   vat_main_t *vam = &vat_main;
3752   i32 retval = ntohl (mp->retval);
3753
3754   if (0 <= retval)
3755     {
3756       print (vam->ofp, "%s\n", mp->status ? "enabled" : "disabled");
3757       if (mp->status)
3758         {
3759           print (vam->ofp, "Proxy-ETR address; %U",
3760                  mp->is_ip4 ? format_ip4_address : format_ip6_address,
3761                  mp->address);
3762         }
3763     }
3764
3765   vam->retval = retval;
3766   vam->result_ready = 1;
3767 }
3768
3769 static void
3770   vl_api_show_one_use_petr_reply_t_handler_json
3771   (vl_api_show_one_use_petr_reply_t * mp)
3772 {
3773   vat_main_t *vam = &vat_main;
3774   vat_json_node_t node;
3775   u8 *status = 0;
3776   struct in_addr ip4;
3777   struct in6_addr ip6;
3778
3779   status = format (0, "%s", mp->status ? "enabled" : "disabled");
3780   vec_add1 (status, 0);
3781
3782   vat_json_init_object (&node);
3783   vat_json_object_add_string_copy (&node, "status", status);
3784   if (mp->status)
3785     {
3786       if (mp->is_ip4)
3787         {
3788           clib_memcpy (&ip6, mp->address, sizeof (ip6));
3789           vat_json_object_add_ip6 (&node, "address", ip6);
3790         }
3791       else
3792         {
3793           clib_memcpy (&ip4, mp->address, sizeof (ip4));
3794           vat_json_object_add_ip4 (&node, "address", ip4);
3795         }
3796     }
3797
3798   vec_free (status);
3799
3800   vat_json_print (vam->ofp, &node);
3801   vat_json_free (&node);
3802
3803   vam->retval = ntohl (mp->retval);
3804   vam->result_ready = 1;
3805 }
3806
3807 static void
3808   vl_api_show_one_nsh_mapping_reply_t_handler
3809   (vl_api_show_one_nsh_mapping_reply_t * mp)
3810 {
3811   vat_main_t *vam = &vat_main;
3812   i32 retval = ntohl (mp->retval);
3813
3814   if (0 <= retval)
3815     {
3816       print (vam->ofp, "%-20s%-16s",
3817              mp->is_set ? "set" : "not-set",
3818              mp->is_set ? (char *) mp->locator_set_name : "");
3819     }
3820
3821   vam->retval = retval;
3822   vam->result_ready = 1;
3823 }
3824
3825 static void
3826   vl_api_show_one_nsh_mapping_reply_t_handler_json
3827   (vl_api_show_one_nsh_mapping_reply_t * mp)
3828 {
3829   vat_main_t *vam = &vat_main;
3830   vat_json_node_t node;
3831   u8 *status = 0;
3832
3833   status = format (0, "%s", mp->is_set ? "yes" : "no");
3834   vec_add1 (status, 0);
3835
3836   vat_json_init_object (&node);
3837   vat_json_object_add_string_copy (&node, "is_set", status);
3838   if (mp->is_set)
3839     {
3840       vat_json_object_add_string_copy (&node, "locator_set",
3841                                        mp->locator_set_name);
3842     }
3843
3844   vec_free (status);
3845
3846   vat_json_print (vam->ofp, &node);
3847   vat_json_free (&node);
3848
3849   vam->retval = ntohl (mp->retval);
3850   vam->result_ready = 1;
3851 }
3852
3853 static void
3854 vl_api_show_one_pitr_reply_t_handler (vl_api_show_one_pitr_reply_t * mp)
3855 {
3856   vat_main_t *vam = &vat_main;
3857   i32 retval = ntohl (mp->retval);
3858
3859   if (0 <= retval)
3860     {
3861       print (vam->ofp, "%-20s%-16s",
3862              mp->status ? "enabled" : "disabled",
3863              mp->status ? (char *) mp->locator_set_name : "");
3864     }
3865
3866   vam->retval = retval;
3867   vam->result_ready = 1;
3868 }
3869
3870 static void
3871 vl_api_show_one_pitr_reply_t_handler_json (vl_api_show_one_pitr_reply_t * mp)
3872 {
3873   vat_main_t *vam = &vat_main;
3874   vat_json_node_t node;
3875   u8 *status = 0;
3876
3877   status = format (0, "%s", mp->status ? "enabled" : "disabled");
3878   vec_add1 (status, 0);
3879
3880   vat_json_init_object (&node);
3881   vat_json_object_add_string_copy (&node, "status", status);
3882   if (mp->status)
3883     {
3884       vat_json_object_add_string_copy (&node, "locator_set",
3885                                        mp->locator_set_name);
3886     }
3887
3888   vec_free (status);
3889
3890   vat_json_print (vam->ofp, &node);
3891   vat_json_free (&node);
3892
3893   vam->retval = ntohl (mp->retval);
3894   vam->result_ready = 1;
3895 }
3896
3897 static u8 *
3898 format_policer_type (u8 * s, va_list * va)
3899 {
3900   u32 i = va_arg (*va, u32);
3901
3902   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
3903     s = format (s, "1r2c");
3904   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
3905     s = format (s, "1r3c");
3906   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
3907     s = format (s, "2r3c-2698");
3908   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
3909     s = format (s, "2r3c-4115");
3910   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
3911     s = format (s, "2r3c-mef5cf1");
3912   else
3913     s = format (s, "ILLEGAL");
3914   return s;
3915 }
3916
3917 static u8 *
3918 format_policer_rate_type (u8 * s, va_list * va)
3919 {
3920   u32 i = va_arg (*va, u32);
3921
3922   if (i == SSE2_QOS_RATE_KBPS)
3923     s = format (s, "kbps");
3924   else if (i == SSE2_QOS_RATE_PPS)
3925     s = format (s, "pps");
3926   else
3927     s = format (s, "ILLEGAL");
3928   return s;
3929 }
3930
3931 static u8 *
3932 format_policer_round_type (u8 * s, va_list * va)
3933 {
3934   u32 i = va_arg (*va, u32);
3935
3936   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
3937     s = format (s, "closest");
3938   else if (i == SSE2_QOS_ROUND_TO_UP)
3939     s = format (s, "up");
3940   else if (i == SSE2_QOS_ROUND_TO_DOWN)
3941     s = format (s, "down");
3942   else
3943     s = format (s, "ILLEGAL");
3944   return s;
3945 }
3946
3947 static u8 *
3948 format_policer_action_type (u8 * s, va_list * va)
3949 {
3950   u32 i = va_arg (*va, u32);
3951
3952   if (i == SSE2_QOS_ACTION_DROP)
3953     s = format (s, "drop");
3954   else if (i == SSE2_QOS_ACTION_TRANSMIT)
3955     s = format (s, "transmit");
3956   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3957     s = format (s, "mark-and-transmit");
3958   else
3959     s = format (s, "ILLEGAL");
3960   return s;
3961 }
3962
3963 static u8 *
3964 format_dscp (u8 * s, va_list * va)
3965 {
3966   u32 i = va_arg (*va, u32);
3967   char *t = 0;
3968
3969   switch (i)
3970     {
3971 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
3972       foreach_vnet_dscp
3973 #undef _
3974     default:
3975       return format (s, "ILLEGAL");
3976     }
3977   s = format (s, "%s", t);
3978   return s;
3979 }
3980
3981 static void
3982 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
3983 {
3984   vat_main_t *vam = &vat_main;
3985   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
3986
3987   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3988     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
3989   else
3990     conform_dscp_str = format (0, "");
3991
3992   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3993     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
3994   else
3995     exceed_dscp_str = format (0, "");
3996
3997   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3998     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
3999   else
4000     violate_dscp_str = format (0, "");
4001
4002   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
4003          "rate type %U, round type %U, %s rate, %s color-aware, "
4004          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
4005          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
4006          "conform action %U%s, exceed action %U%s, violate action %U%s",
4007          mp->name,
4008          format_policer_type, mp->type,
4009          ntohl (mp->cir),
4010          ntohl (mp->eir),
4011          clib_net_to_host_u64 (mp->cb),
4012          clib_net_to_host_u64 (mp->eb),
4013          format_policer_rate_type, mp->rate_type,
4014          format_policer_round_type, mp->round_type,
4015          mp->single_rate ? "single" : "dual",
4016          mp->color_aware ? "is" : "not",
4017          ntohl (mp->cir_tokens_per_period),
4018          ntohl (mp->pir_tokens_per_period),
4019          ntohl (mp->scale),
4020          ntohl (mp->current_limit),
4021          ntohl (mp->current_bucket),
4022          ntohl (mp->extended_limit),
4023          ntohl (mp->extended_bucket),
4024          clib_net_to_host_u64 (mp->last_update_time),
4025          format_policer_action_type, mp->conform_action_type,
4026          conform_dscp_str,
4027          format_policer_action_type, mp->exceed_action_type,
4028          exceed_dscp_str,
4029          format_policer_action_type, mp->violate_action_type,
4030          violate_dscp_str);
4031
4032   vec_free (conform_dscp_str);
4033   vec_free (exceed_dscp_str);
4034   vec_free (violate_dscp_str);
4035 }
4036
4037 static void vl_api_policer_details_t_handler_json
4038   (vl_api_policer_details_t * mp)
4039 {
4040   vat_main_t *vam = &vat_main;
4041   vat_json_node_t *node;
4042   u8 *rate_type_str, *round_type_str, *type_str;
4043   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
4044
4045   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
4046   round_type_str =
4047     format (0, "%U", format_policer_round_type, mp->round_type);
4048   type_str = format (0, "%U", format_policer_type, mp->type);
4049   conform_action_str = format (0, "%U", format_policer_action_type,
4050                                mp->conform_action_type);
4051   exceed_action_str = format (0, "%U", format_policer_action_type,
4052                               mp->exceed_action_type);
4053   violate_action_str = format (0, "%U", format_policer_action_type,
4054                                mp->violate_action_type);
4055
4056   if (VAT_JSON_ARRAY != vam->json_tree.type)
4057     {
4058       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4059       vat_json_init_array (&vam->json_tree);
4060     }
4061   node = vat_json_array_add (&vam->json_tree);
4062
4063   vat_json_init_object (node);
4064   vat_json_object_add_string_copy (node, "name", mp->name);
4065   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
4066   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
4067   vat_json_object_add_uint (node, "cb", clib_net_to_host_u64 (mp->cb));
4068   vat_json_object_add_uint (node, "eb", clib_net_to_host_u64 (mp->eb));
4069   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
4070   vat_json_object_add_string_copy (node, "round_type", round_type_str);
4071   vat_json_object_add_string_copy (node, "type", type_str);
4072   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
4073   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
4074   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
4075   vat_json_object_add_uint (node, "cir_tokens_per_period",
4076                             ntohl (mp->cir_tokens_per_period));
4077   vat_json_object_add_uint (node, "eir_tokens_per_period",
4078                             ntohl (mp->pir_tokens_per_period));
4079   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
4080   vat_json_object_add_uint (node, "current_bucket",
4081                             ntohl (mp->current_bucket));
4082   vat_json_object_add_uint (node, "extended_limit",
4083                             ntohl (mp->extended_limit));
4084   vat_json_object_add_uint (node, "extended_bucket",
4085                             ntohl (mp->extended_bucket));
4086   vat_json_object_add_uint (node, "last_update_time",
4087                             ntohl (mp->last_update_time));
4088   vat_json_object_add_string_copy (node, "conform_action",
4089                                    conform_action_str);
4090   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4091     {
4092       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4093       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
4094       vec_free (dscp_str);
4095     }
4096   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
4097   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4098     {
4099       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4100       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
4101       vec_free (dscp_str);
4102     }
4103   vat_json_object_add_string_copy (node, "violate_action",
4104                                    violate_action_str);
4105   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4106     {
4107       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4108       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
4109       vec_free (dscp_str);
4110     }
4111
4112   vec_free (rate_type_str);
4113   vec_free (round_type_str);
4114   vec_free (type_str);
4115   vec_free (conform_action_str);
4116   vec_free (exceed_action_str);
4117   vec_free (violate_action_str);
4118 }
4119
4120 static void
4121 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
4122                                            mp)
4123 {
4124   vat_main_t *vam = &vat_main;
4125   int i, count = ntohl (mp->count);
4126
4127   if (count > 0)
4128     print (vam->ofp, "classify table ids (%d) : ", count);
4129   for (i = 0; i < count; i++)
4130     {
4131       print (vam->ofp, "%d", ntohl (mp->ids[i]));
4132       print (vam->ofp, (i < count - 1) ? "," : "");
4133     }
4134   vam->retval = ntohl (mp->retval);
4135   vam->result_ready = 1;
4136 }
4137
4138 static void
4139   vl_api_classify_table_ids_reply_t_handler_json
4140   (vl_api_classify_table_ids_reply_t * mp)
4141 {
4142   vat_main_t *vam = &vat_main;
4143   int i, count = ntohl (mp->count);
4144
4145   if (count > 0)
4146     {
4147       vat_json_node_t node;
4148
4149       vat_json_init_object (&node);
4150       for (i = 0; i < count; i++)
4151         {
4152           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
4153         }
4154       vat_json_print (vam->ofp, &node);
4155       vat_json_free (&node);
4156     }
4157   vam->retval = ntohl (mp->retval);
4158   vam->result_ready = 1;
4159 }
4160
4161 static void
4162   vl_api_classify_table_by_interface_reply_t_handler
4163   (vl_api_classify_table_by_interface_reply_t * mp)
4164 {
4165   vat_main_t *vam = &vat_main;
4166   u32 table_id;
4167
4168   table_id = ntohl (mp->l2_table_id);
4169   if (table_id != ~0)
4170     print (vam->ofp, "l2 table id : %d", table_id);
4171   else
4172     print (vam->ofp, "l2 table id : No input ACL tables configured");
4173   table_id = ntohl (mp->ip4_table_id);
4174   if (table_id != ~0)
4175     print (vam->ofp, "ip4 table id : %d", table_id);
4176   else
4177     print (vam->ofp, "ip4 table id : No input ACL tables configured");
4178   table_id = ntohl (mp->ip6_table_id);
4179   if (table_id != ~0)
4180     print (vam->ofp, "ip6 table id : %d", table_id);
4181   else
4182     print (vam->ofp, "ip6 table id : No input ACL tables configured");
4183   vam->retval = ntohl (mp->retval);
4184   vam->result_ready = 1;
4185 }
4186
4187 static void
4188   vl_api_classify_table_by_interface_reply_t_handler_json
4189   (vl_api_classify_table_by_interface_reply_t * mp)
4190 {
4191   vat_main_t *vam = &vat_main;
4192   vat_json_node_t node;
4193
4194   vat_json_init_object (&node);
4195
4196   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
4197   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
4198   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
4199
4200   vat_json_print (vam->ofp, &node);
4201   vat_json_free (&node);
4202
4203   vam->retval = ntohl (mp->retval);
4204   vam->result_ready = 1;
4205 }
4206
4207 static void vl_api_policer_add_del_reply_t_handler
4208   (vl_api_policer_add_del_reply_t * mp)
4209 {
4210   vat_main_t *vam = &vat_main;
4211   i32 retval = ntohl (mp->retval);
4212   if (vam->async_mode)
4213     {
4214       vam->async_errors += (retval < 0);
4215     }
4216   else
4217     {
4218       vam->retval = retval;
4219       vam->result_ready = 1;
4220       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
4221         /*
4222          * Note: this is just barely thread-safe, depends on
4223          * the main thread spinning waiting for an answer...
4224          */
4225         errmsg ("policer index %d", ntohl (mp->policer_index));
4226     }
4227 }
4228
4229 static void vl_api_policer_add_del_reply_t_handler_json
4230   (vl_api_policer_add_del_reply_t * mp)
4231 {
4232   vat_main_t *vam = &vat_main;
4233   vat_json_node_t node;
4234
4235   vat_json_init_object (&node);
4236   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
4237   vat_json_object_add_uint (&node, "policer_index",
4238                             ntohl (mp->policer_index));
4239
4240   vat_json_print (vam->ofp, &node);
4241   vat_json_free (&node);
4242
4243   vam->retval = ntohl (mp->retval);
4244   vam->result_ready = 1;
4245 }
4246
4247 /* Format hex dump. */
4248 u8 *
4249 format_hex_bytes (u8 * s, va_list * va)
4250 {
4251   u8 *bytes = va_arg (*va, u8 *);
4252   int n_bytes = va_arg (*va, int);
4253   uword i;
4254
4255   /* Print short or long form depending on byte count. */
4256   uword short_form = n_bytes <= 32;
4257   uword indent = format_get_indent (s);
4258
4259   if (n_bytes == 0)
4260     return s;
4261
4262   for (i = 0; i < n_bytes; i++)
4263     {
4264       if (!short_form && (i % 32) == 0)
4265         s = format (s, "%08x: ", i);
4266       s = format (s, "%02x", bytes[i]);
4267       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
4268         s = format (s, "\n%U", format_white_space, indent);
4269     }
4270
4271   return s;
4272 }
4273
4274 static void
4275 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
4276                                             * mp)
4277 {
4278   vat_main_t *vam = &vat_main;
4279   i32 retval = ntohl (mp->retval);
4280   if (retval == 0)
4281     {
4282       print (vam->ofp, "classify table info :");
4283       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
4284              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
4285              ntohl (mp->miss_next_index));
4286       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
4287              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
4288              ntohl (mp->match_n_vectors));
4289       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
4290              ntohl (mp->mask_length));
4291     }
4292   vam->retval = retval;
4293   vam->result_ready = 1;
4294 }
4295
4296 static void
4297   vl_api_classify_table_info_reply_t_handler_json
4298   (vl_api_classify_table_info_reply_t * mp)
4299 {
4300   vat_main_t *vam = &vat_main;
4301   vat_json_node_t node;
4302
4303   i32 retval = ntohl (mp->retval);
4304   if (retval == 0)
4305     {
4306       vat_json_init_object (&node);
4307
4308       vat_json_object_add_int (&node, "sessions",
4309                                ntohl (mp->active_sessions));
4310       vat_json_object_add_int (&node, "nexttbl",
4311                                ntohl (mp->next_table_index));
4312       vat_json_object_add_int (&node, "nextnode",
4313                                ntohl (mp->miss_next_index));
4314       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
4315       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
4316       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
4317       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
4318                       ntohl (mp->mask_length), 0);
4319       vat_json_object_add_string_copy (&node, "mask", s);
4320
4321       vat_json_print (vam->ofp, &node);
4322       vat_json_free (&node);
4323     }
4324   vam->retval = ntohl (mp->retval);
4325   vam->result_ready = 1;
4326 }
4327
4328 static void
4329 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
4330                                            mp)
4331 {
4332   vat_main_t *vam = &vat_main;
4333
4334   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
4335          ntohl (mp->hit_next_index), ntohl (mp->advance),
4336          ntohl (mp->opaque_index));
4337   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
4338          ntohl (mp->match_length));
4339 }
4340
4341 static void
4342   vl_api_classify_session_details_t_handler_json
4343   (vl_api_classify_session_details_t * mp)
4344 {
4345   vat_main_t *vam = &vat_main;
4346   vat_json_node_t *node = NULL;
4347
4348   if (VAT_JSON_ARRAY != vam->json_tree.type)
4349     {
4350       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4351       vat_json_init_array (&vam->json_tree);
4352     }
4353   node = vat_json_array_add (&vam->json_tree);
4354
4355   vat_json_init_object (node);
4356   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
4357   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
4358   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
4359   u8 *s =
4360     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
4361             0);
4362   vat_json_object_add_string_copy (node, "match", s);
4363 }
4364
4365 static void vl_api_pg_create_interface_reply_t_handler
4366   (vl_api_pg_create_interface_reply_t * mp)
4367 {
4368   vat_main_t *vam = &vat_main;
4369
4370   vam->retval = ntohl (mp->retval);
4371   vam->result_ready = 1;
4372 }
4373
4374 static void vl_api_pg_create_interface_reply_t_handler_json
4375   (vl_api_pg_create_interface_reply_t * mp)
4376 {
4377   vat_main_t *vam = &vat_main;
4378   vat_json_node_t node;
4379
4380   i32 retval = ntohl (mp->retval);
4381   if (retval == 0)
4382     {
4383       vat_json_init_object (&node);
4384
4385       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
4386
4387       vat_json_print (vam->ofp, &node);
4388       vat_json_free (&node);
4389     }
4390   vam->retval = ntohl (mp->retval);
4391   vam->result_ready = 1;
4392 }
4393
4394 static void vl_api_policer_classify_details_t_handler
4395   (vl_api_policer_classify_details_t * mp)
4396 {
4397   vat_main_t *vam = &vat_main;
4398
4399   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
4400          ntohl (mp->table_index));
4401 }
4402
4403 static void vl_api_policer_classify_details_t_handler_json
4404   (vl_api_policer_classify_details_t * mp)
4405 {
4406   vat_main_t *vam = &vat_main;
4407   vat_json_node_t *node;
4408
4409   if (VAT_JSON_ARRAY != vam->json_tree.type)
4410     {
4411       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4412       vat_json_init_array (&vam->json_tree);
4413     }
4414   node = vat_json_array_add (&vam->json_tree);
4415
4416   vat_json_init_object (node);
4417   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
4418   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
4419 }
4420
4421 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler
4422   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
4423 {
4424   vat_main_t *vam = &vat_main;
4425   i32 retval = ntohl (mp->retval);
4426   if (vam->async_mode)
4427     {
4428       vam->async_errors += (retval < 0);
4429     }
4430   else
4431     {
4432       vam->retval = retval;
4433       vam->sw_if_index = ntohl (mp->sw_if_index);
4434       vam->result_ready = 1;
4435     }
4436 }
4437
4438 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler_json
4439   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
4440 {
4441   vat_main_t *vam = &vat_main;
4442   vat_json_node_t node;
4443
4444   vat_json_init_object (&node);
4445   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
4446   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
4447
4448   vat_json_print (vam->ofp, &node);
4449   vat_json_free (&node);
4450
4451   vam->retval = ntohl (mp->retval);
4452   vam->result_ready = 1;
4453 }
4454
4455 static void vl_api_flow_classify_details_t_handler
4456   (vl_api_flow_classify_details_t * mp)
4457 {
4458   vat_main_t *vam = &vat_main;
4459
4460   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
4461          ntohl (mp->table_index));
4462 }
4463
4464 static void vl_api_flow_classify_details_t_handler_json
4465   (vl_api_flow_classify_details_t * mp)
4466 {
4467   vat_main_t *vam = &vat_main;
4468   vat_json_node_t *node;
4469
4470   if (VAT_JSON_ARRAY != vam->json_tree.type)
4471     {
4472       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4473       vat_json_init_array (&vam->json_tree);
4474     }
4475   node = vat_json_array_add (&vam->json_tree);
4476
4477   vat_json_init_object (node);
4478   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
4479   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
4480 }
4481
4482 #define vl_api_vnet_interface_simple_counters_t_endian vl_noop_handler
4483 #define vl_api_vnet_interface_simple_counters_t_print vl_noop_handler
4484 #define vl_api_vnet_interface_combined_counters_t_endian vl_noop_handler
4485 #define vl_api_vnet_interface_combined_counters_t_print vl_noop_handler
4486 #define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
4487 #define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler
4488 #define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler
4489 #define vl_api_vnet_ip6_fib_counters_t_print vl_noop_handler
4490 #define vl_api_vnet_ip4_nbr_counters_t_endian vl_noop_handler
4491 #define vl_api_vnet_ip4_nbr_counters_t_print vl_noop_handler
4492 #define vl_api_vnet_ip6_nbr_counters_t_endian vl_noop_handler
4493 #define vl_api_vnet_ip6_nbr_counters_t_print vl_noop_handler
4494 #define vl_api_one_adjacencies_get_reply_t_endian vl_noop_handler
4495 #define vl_api_one_adjacencies_get_reply_t_print vl_noop_handler
4496 #define vl_api_one_l2_arp_bd_get_reply_t_print vl_noop_handler
4497 #define vl_api_one_l2_arp_entries_get_reply_t_endian vl_noop_handler
4498 #define vl_api_one_l2_arp_entries_get_reply_t_print vl_noop_handler
4499 #define vl_api_one_l2_arp_bd_get_reply_t_endian vl_noop_handler
4500
4501 /*
4502  * Generate boilerplate reply handlers, which
4503  * dig the return value out of the xxx_reply_t API message,
4504  * stick it into vam->retval, and set vam->result_ready
4505  *
4506  * Could also do this by pointing N message decode slots at
4507  * a single function, but that could break in subtle ways.
4508  */
4509
4510 #define foreach_standard_reply_retval_handler           \
4511 _(sw_interface_set_flags_reply)                         \
4512 _(sw_interface_add_del_address_reply)                   \
4513 _(sw_interface_set_table_reply)                         \
4514 _(sw_interface_set_mpls_enable_reply)                   \
4515 _(sw_interface_set_vpath_reply)                         \
4516 _(sw_interface_set_vxlan_bypass_reply)                  \
4517 _(sw_interface_set_vxlan_gpe_bypass_reply)              \
4518 _(sw_interface_set_l2_bridge_reply)                     \
4519 _(bridge_domain_add_del_reply)                          \
4520 _(sw_interface_set_l2_xconnect_reply)                   \
4521 _(l2fib_add_del_reply)                                  \
4522 _(l2fib_flush_int_reply)                                \
4523 _(l2fib_flush_bd_reply)                                 \
4524 _(ip_add_del_route_reply)                               \
4525 _(ip_mroute_add_del_reply)                              \
4526 _(mpls_route_add_del_reply)                             \
4527 _(mpls_ip_bind_unbind_reply)                            \
4528 _(proxy_arp_add_del_reply)                              \
4529 _(proxy_arp_intfc_enable_disable_reply)                 \
4530 _(sw_interface_set_unnumbered_reply)                    \
4531 _(ip_neighbor_add_del_reply)                            \
4532 _(reset_vrf_reply)                                      \
4533 _(oam_add_del_reply)                                    \
4534 _(reset_fib_reply)                                      \
4535 _(dhcp_proxy_config_reply)                              \
4536 _(dhcp_proxy_set_vss_reply)                             \
4537 _(dhcp_client_config_reply)                             \
4538 _(set_ip_flow_hash_reply)                               \
4539 _(sw_interface_ip6_enable_disable_reply)                \
4540 _(sw_interface_ip6_set_link_local_address_reply)        \
4541 _(ip6nd_proxy_add_del_reply)                            \
4542 _(sw_interface_ip6nd_ra_prefix_reply)                   \
4543 _(sw_interface_ip6nd_ra_config_reply)                   \
4544 _(set_arp_neighbor_limit_reply)                         \
4545 _(l2_patch_add_del_reply)                               \
4546 _(sr_policy_add_reply)                                  \
4547 _(sr_policy_mod_reply)                                  \
4548 _(sr_policy_del_reply)                                  \
4549 _(sr_localsid_add_del_reply)                            \
4550 _(sr_steering_add_del_reply)                            \
4551 _(classify_add_del_session_reply)                       \
4552 _(classify_set_interface_ip_table_reply)                \
4553 _(classify_set_interface_l2_tables_reply)               \
4554 _(l2tpv3_set_tunnel_cookies_reply)                      \
4555 _(l2tpv3_interface_enable_disable_reply)                \
4556 _(l2tpv3_set_lookup_key_reply)                          \
4557 _(l2_fib_clear_table_reply)                             \
4558 _(l2_interface_efp_filter_reply)                        \
4559 _(l2_interface_vlan_tag_rewrite_reply)                  \
4560 _(modify_vhost_user_if_reply)                           \
4561 _(delete_vhost_user_if_reply)                           \
4562 _(want_ip4_arp_events_reply)                            \
4563 _(want_ip6_nd_events_reply)                             \
4564 _(input_acl_set_interface_reply)                        \
4565 _(ipsec_spd_add_del_reply)                              \
4566 _(ipsec_interface_add_del_spd_reply)                    \
4567 _(ipsec_spd_add_del_entry_reply)                        \
4568 _(ipsec_sad_add_del_entry_reply)                        \
4569 _(ipsec_sa_set_key_reply)                               \
4570 _(ipsec_tunnel_if_add_del_reply)                        \
4571 _(ikev2_profile_add_del_reply)                          \
4572 _(ikev2_profile_set_auth_reply)                         \
4573 _(ikev2_profile_set_id_reply)                           \
4574 _(ikev2_profile_set_ts_reply)                           \
4575 _(ikev2_set_local_key_reply)                            \
4576 _(ikev2_set_responder_reply)                            \
4577 _(ikev2_set_ike_transforms_reply)                       \
4578 _(ikev2_set_esp_transforms_reply)                       \
4579 _(ikev2_set_sa_lifetime_reply)                          \
4580 _(ikev2_initiate_sa_init_reply)                         \
4581 _(ikev2_initiate_del_ike_sa_reply)                      \
4582 _(ikev2_initiate_del_child_sa_reply)                    \
4583 _(ikev2_initiate_rekey_child_sa_reply)                  \
4584 _(delete_loopback_reply)                                \
4585 _(bd_ip_mac_add_del_reply)                              \
4586 _(map_del_domain_reply)                                 \
4587 _(map_add_del_rule_reply)                               \
4588 _(want_interface_events_reply)                          \
4589 _(want_stats_reply)                                     \
4590 _(cop_interface_enable_disable_reply)                   \
4591 _(cop_whitelist_enable_disable_reply)                   \
4592 _(sw_interface_clear_stats_reply)                       \
4593 _(ioam_enable_reply)                              \
4594 _(ioam_disable_reply)                              \
4595 _(one_add_del_locator_reply)                            \
4596 _(one_add_del_local_eid_reply)                          \
4597 _(one_add_del_remote_mapping_reply)                     \
4598 _(one_add_del_adjacency_reply)                          \
4599 _(one_add_del_map_resolver_reply)                       \
4600 _(one_add_del_map_server_reply)                         \
4601 _(one_enable_disable_reply)                             \
4602 _(one_rloc_probe_enable_disable_reply)                  \
4603 _(one_map_register_enable_disable_reply)                \
4604 _(one_pitr_set_locator_set_reply)                       \
4605 _(one_map_request_mode_reply)                           \
4606 _(one_add_del_map_request_itr_rlocs_reply)              \
4607 _(one_eid_table_add_del_map_reply)                      \
4608 _(one_use_petr_reply)                                   \
4609 _(one_stats_enable_disable_reply)                       \
4610 _(one_add_del_l2_arp_entry_reply)                       \
4611 _(one_stats_flush_reply)                                \
4612 _(gpe_enable_disable_reply)                             \
4613 _(gpe_set_encap_mode_reply)                             \
4614 _(gpe_add_del_iface_reply)                              \
4615 _(gpe_add_del_native_fwd_rpath_reply)                   \
4616 _(af_packet_delete_reply)                               \
4617 _(policer_classify_set_interface_reply)                 \
4618 _(netmap_create_reply)                                  \
4619 _(netmap_delete_reply)                                  \
4620 _(set_ipfix_exporter_reply)                             \
4621 _(set_ipfix_classify_stream_reply)                      \
4622 _(ipfix_classify_table_add_del_reply)                   \
4623 _(flow_classify_set_interface_reply)                    \
4624 _(sw_interface_span_enable_disable_reply)               \
4625 _(pg_capture_reply)                                     \
4626 _(pg_enable_disable_reply)                              \
4627 _(ip_source_and_port_range_check_add_del_reply)         \
4628 _(ip_source_and_port_range_check_interface_add_del_reply)\
4629 _(delete_subif_reply)                                   \
4630 _(l2_interface_pbb_tag_rewrite_reply)                   \
4631 _(punt_reply)                                           \
4632 _(feature_enable_disable_reply)                         \
4633 _(sw_interface_tag_add_del_reply)                       \
4634 _(sw_interface_set_mtu_reply)                           \
4635 _(p2p_ethernet_add_reply)                               \
4636 _(p2p_ethernet_del_reply)
4637
4638 #define _(n)                                    \
4639     static void vl_api_##n##_t_handler          \
4640     (vl_api_##n##_t * mp)                       \
4641     {                                           \
4642         vat_main_t * vam = &vat_main;           \
4643         i32 retval = ntohl(mp->retval);         \
4644         if (vam->async_mode) {                  \
4645             vam->async_errors += (retval < 0);  \
4646         } else {                                \
4647             vam->retval = retval;               \
4648             vam->result_ready = 1;              \
4649         }                                       \
4650     }
4651 foreach_standard_reply_retval_handler;
4652 #undef _
4653
4654 #define _(n)                                    \
4655     static void vl_api_##n##_t_handler_json     \
4656     (vl_api_##n##_t * mp)                       \
4657     {                                           \
4658         vat_main_t * vam = &vat_main;           \
4659         vat_json_node_t node;                   \
4660         vat_json_init_object(&node);            \
4661         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
4662         vat_json_print(vam->ofp, &node);        \
4663         vam->retval = ntohl(mp->retval);        \
4664         vam->result_ready = 1;                  \
4665     }
4666 foreach_standard_reply_retval_handler;
4667 #undef _
4668
4669 /*
4670  * Table of message reply handlers, must include boilerplate handlers
4671  * we just generated
4672  */
4673
4674 #define foreach_vpe_api_reply_msg                                       \
4675 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
4676 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
4677 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
4678 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
4679 _(CONTROL_PING_REPLY, control_ping_reply)                               \
4680 _(CLI_REPLY, cli_reply)                                                 \
4681 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
4682 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
4683   sw_interface_add_del_address_reply)                                   \
4684 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
4685 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
4686 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
4687 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
4688 _(SW_INTERFACE_SET_VXLAN_GPE_BYPASS_REPLY, sw_interface_set_vxlan_gpe_bypass_reply) \
4689 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
4690   sw_interface_set_l2_xconnect_reply)                                   \
4691 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
4692   sw_interface_set_l2_bridge_reply)                                     \
4693 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
4694 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
4695 _(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply)     \
4696 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
4697 _(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply)                         \
4698 _(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply)                           \
4699 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
4700 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
4701 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
4702 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
4703 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
4704 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
4705 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
4706 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
4707 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
4708 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
4709 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
4710 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
4711   proxy_arp_intfc_enable_disable_reply)                                 \
4712 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
4713 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
4714   sw_interface_set_unnumbered_reply)                                    \
4715 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
4716 _(RESET_VRF_REPLY, reset_vrf_reply)                                     \
4717 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
4718 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
4719 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
4720 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
4721 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
4722 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
4723 _(DHCP_PROXY_DETAILS, dhcp_proxy_details)                               \
4724 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
4725 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
4726 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
4727   sw_interface_ip6_enable_disable_reply)                                \
4728 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY,                        \
4729   sw_interface_ip6_set_link_local_address_reply)                        \
4730 _(IP6ND_PROXY_ADD_DEL_REPLY, ip6nd_proxy_add_del_reply)                 \
4731 _(IP6ND_PROXY_DETAILS, ip6nd_proxy_details)                             \
4732 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
4733   sw_interface_ip6nd_ra_prefix_reply)                                   \
4734 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
4735   sw_interface_ip6nd_ra_config_reply)                                   \
4736 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
4737 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
4738 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
4739 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
4740 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
4741 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
4742 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
4743 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
4744 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
4745 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
4746 classify_set_interface_ip_table_reply)                                  \
4747 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
4748   classify_set_interface_l2_tables_reply)                               \
4749 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
4750 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
4751 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
4752 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
4753 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
4754   l2tpv3_interface_enable_disable_reply)                                \
4755 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
4756 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
4757 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
4758 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
4759 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
4760 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
4761 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
4762 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
4763 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
4764 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
4765 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
4766 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
4767 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
4768 _(SHOW_VERSION_REPLY, show_version_reply)                               \
4769 _(L2_FIB_TABLE_DETAILS, l2_fib_table_details)                           \
4770 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)           \
4771 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
4772 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
4773 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
4774 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
4775 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
4776 _(IP6_ND_EVENT, ip6_nd_event)                                           \
4777 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
4778 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
4779 _(IP_DETAILS, ip_details)                                               \
4780 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
4781 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
4782 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
4783 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
4784 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
4785 _(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply)         \
4786 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
4787 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
4788 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
4789 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
4790 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
4791 _(IKEV2_SET_RESPONDER_REPLY, ikev2_set_responder_reply)                 \
4792 _(IKEV2_SET_IKE_TRANSFORMS_REPLY, ikev2_set_ike_transforms_reply)       \
4793 _(IKEV2_SET_ESP_TRANSFORMS_REPLY, ikev2_set_esp_transforms_reply)       \
4794 _(IKEV2_SET_SA_LIFETIME_REPLY, ikev2_set_sa_lifetime_reply)             \
4795 _(IKEV2_INITIATE_SA_INIT_REPLY, ikev2_initiate_sa_init_reply)           \
4796 _(IKEV2_INITIATE_DEL_IKE_SA_REPLY, ikev2_initiate_del_ike_sa_reply)     \
4797 _(IKEV2_INITIATE_DEL_CHILD_SA_REPLY, ikev2_initiate_del_child_sa_reply) \
4798 _(IKEV2_INITIATE_REKEY_CHILD_SA_REPLY, ikev2_initiate_rekey_child_sa_reply) \
4799 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
4800 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
4801 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
4802 _(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply)                           \
4803 _(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply)                           \
4804 _(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply)                       \
4805 _(MAP_DOMAIN_DETAILS, map_domain_details)                               \
4806 _(MAP_RULE_DETAILS, map_rule_details)                                   \
4807 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
4808 _(WANT_STATS_REPLY, want_stats_reply)                                   \
4809 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
4810 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
4811 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
4812 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
4813 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
4814 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
4815 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
4816 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
4817 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
4818 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
4819 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
4820 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
4821 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
4822 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
4823 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
4824 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
4825   one_map_register_enable_disable_reply)                                \
4826 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
4827   one_rloc_probe_enable_disable_reply)                                  \
4828 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
4829 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
4830 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
4831 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
4832 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
4833 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
4834 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
4835 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
4836 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
4837 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
4838 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
4839 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
4840 _(ONE_STATS_DETAILS, one_stats_details)                                 \
4841 _(ONE_STATS_FLUSH_REPLY, one_stats_flush_reply)                         \
4842 _(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply)       \
4843 _(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,                                  \
4844   show_one_stats_enable_disable_reply)                                  \
4845 _(ONE_ADD_DEL_L2_ARP_ENTRY_REPLY, one_add_del_l2_arp_entry_reply)       \
4846 _(ONE_L2_ARP_BD_GET_REPLY, one_l2_arp_bd_get_reply)                     \
4847 _(ONE_L2_ARP_ENTRIES_GET_REPLY, one_l2_arp_entries_get_reply)           \
4848 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
4849 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
4850 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
4851 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
4852 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
4853 _(GPE_FWD_ENTRY_VNIS_GET_REPLY, gpe_fwd_entry_vnis_get_reply)           \
4854 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
4855 _(GPE_NATIVE_FWD_RPATHS_GET_REPLY, gpe_native_fwd_rpaths_get_reply)     \
4856 _(GPE_ADD_DEL_NATIVE_FWD_RPATH_REPLY,                                   \
4857   gpe_add_del_native_fwd_rpath_reply)                                   \
4858 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
4859   gpe_fwd_entry_path_details)                                           \
4860 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
4861 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
4862   one_add_del_map_request_itr_rlocs_reply)                              \
4863 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
4864   one_get_map_request_itr_rlocs_reply)                                  \
4865 _(SHOW_ONE_NSH_MAPPING_REPLY, show_one_nsh_mapping_reply)               \
4866 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
4867 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
4868 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
4869 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
4870 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
4871   show_one_map_register_state_reply)                                    \
4872 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
4873 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
4874 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
4875 _(POLICER_DETAILS, policer_details)                                     \
4876 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
4877 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
4878 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
4879 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
4880 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
4881 _(MPLS_FIB_DETAILS, mpls_fib_details)                                   \
4882 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
4883 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
4884 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
4885 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
4886 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
4887 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
4888 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
4889 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
4890 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
4891 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
4892 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
4893 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
4894 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
4895 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
4896 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
4897 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
4898 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
4899 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
4900 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
4901  ip_source_and_port_range_check_add_del_reply)                          \
4902 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
4903  ip_source_and_port_range_check_interface_add_del_reply)                \
4904 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
4905 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
4906 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
4907 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
4908 _(PUNT_REPLY, punt_reply)                                               \
4909 _(IP_FIB_DETAILS, ip_fib_details)                                       \
4910 _(IP6_FIB_DETAILS, ip6_fib_details)                                     \
4911 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
4912 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
4913 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
4914 _(SW_INTERFACE_SET_MTU_REPLY, sw_interface_set_mtu_reply)               \
4915 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
4916 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)           \
4917 _(P2P_ETHERNET_ADD_REPLY, p2p_ethernet_add_reply)                       \
4918 _(P2P_ETHERNET_DEL_REPLY, p2p_ethernet_del_reply)
4919
4920 #define foreach_standalone_reply_msg                                    \
4921 _(SW_INTERFACE_SET_FLAGS, sw_interface_set_flags)                       \
4922 _(VNET_INTERFACE_SIMPLE_COUNTERS, vnet_interface_simple_counters)       \
4923 _(VNET_INTERFACE_COMBINED_COUNTERS, vnet_interface_combined_counters)   \
4924 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
4925 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
4926 _(VNET_IP4_NBR_COUNTERS, vnet_ip4_nbr_counters)                         \
4927 _(VNET_IP6_NBR_COUNTERS, vnet_ip6_nbr_counters)
4928
4929 typedef struct
4930 {
4931   u8 *name;
4932   u32 value;
4933 } name_sort_t;
4934
4935
4936 #define STR_VTR_OP_CASE(op)     \
4937     case L2_VTR_ ## op:         \
4938         return "" # op;
4939
4940 static const char *
4941 str_vtr_op (u32 vtr_op)
4942 {
4943   switch (vtr_op)
4944     {
4945       STR_VTR_OP_CASE (DISABLED);
4946       STR_VTR_OP_CASE (PUSH_1);
4947       STR_VTR_OP_CASE (PUSH_2);
4948       STR_VTR_OP_CASE (POP_1);
4949       STR_VTR_OP_CASE (POP_2);
4950       STR_VTR_OP_CASE (TRANSLATE_1_1);
4951       STR_VTR_OP_CASE (TRANSLATE_1_2);
4952       STR_VTR_OP_CASE (TRANSLATE_2_1);
4953       STR_VTR_OP_CASE (TRANSLATE_2_2);
4954     }
4955
4956   return "UNKNOWN";
4957 }
4958
4959 static int
4960 dump_sub_interface_table (vat_main_t * vam)
4961 {
4962   const sw_interface_subif_t *sub = NULL;
4963
4964   if (vam->json_output)
4965     {
4966       clib_warning
4967         ("JSON output supported only for VPE API calls and dump_stats_table");
4968       return -99;
4969     }
4970
4971   print (vam->ofp,
4972          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
4973          "Interface", "sw_if_index",
4974          "sub id", "dot1ad", "tags", "outer id",
4975          "inner id", "exact", "default", "outer any", "inner any");
4976
4977   vec_foreach (sub, vam->sw_if_subif_table)
4978   {
4979     print (vam->ofp,
4980            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
4981            sub->interface_name,
4982            sub->sw_if_index,
4983            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
4984            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
4985            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
4986            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
4987     if (sub->vtr_op != L2_VTR_DISABLED)
4988       {
4989         print (vam->ofp,
4990                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
4991                "tag1: %d tag2: %d ]",
4992                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
4993                sub->vtr_tag1, sub->vtr_tag2);
4994       }
4995   }
4996
4997   return 0;
4998 }
4999
5000 static int
5001 name_sort_cmp (void *a1, void *a2)
5002 {
5003   name_sort_t *n1 = a1;
5004   name_sort_t *n2 = a2;
5005
5006   return strcmp ((char *) n1->name, (char *) n2->name);
5007 }
5008
5009 static int
5010 dump_interface_table (vat_main_t * vam)
5011 {
5012   hash_pair_t *p;
5013   name_sort_t *nses = 0, *ns;
5014
5015   if (vam->json_output)
5016     {
5017       clib_warning
5018         ("JSON output supported only for VPE API calls and dump_stats_table");
5019       return -99;
5020     }
5021
5022   /* *INDENT-OFF* */
5023   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5024   ({
5025     vec_add2 (nses, ns, 1);
5026     ns->name = (u8 *)(p->key);
5027     ns->value = (u32) p->value[0];
5028   }));
5029   /* *INDENT-ON* */
5030
5031   vec_sort_with_function (nses, name_sort_cmp);
5032
5033   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
5034   vec_foreach (ns, nses)
5035   {
5036     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
5037   }
5038   vec_free (nses);
5039   return 0;
5040 }
5041
5042 static int
5043 dump_ip_table (vat_main_t * vam, int is_ipv6)
5044 {
5045   const ip_details_t *det = NULL;
5046   const ip_address_details_t *address = NULL;
5047   u32 i = ~0;
5048
5049   print (vam->ofp, "%-12s", "sw_if_index");
5050
5051   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
5052   {
5053     i++;
5054     if (!det->present)
5055       {
5056         continue;
5057       }
5058     print (vam->ofp, "%-12d", i);
5059     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
5060     if (!det->addr)
5061       {
5062         continue;
5063       }
5064     vec_foreach (address, det->addr)
5065     {
5066       print (vam->ofp,
5067              "            %-30U%-13d",
5068              is_ipv6 ? format_ip6_address : format_ip4_address,
5069              address->ip, address->prefix_length);
5070     }
5071   }
5072
5073   return 0;
5074 }
5075
5076 static int
5077 dump_ipv4_table (vat_main_t * vam)
5078 {
5079   if (vam->json_output)
5080     {
5081       clib_warning
5082         ("JSON output supported only for VPE API calls and dump_stats_table");
5083       return -99;
5084     }
5085
5086   return dump_ip_table (vam, 0);
5087 }
5088
5089 static int
5090 dump_ipv6_table (vat_main_t * vam)
5091 {
5092   if (vam->json_output)
5093     {
5094       clib_warning
5095         ("JSON output supported only for VPE API calls and dump_stats_table");
5096       return -99;
5097     }
5098
5099   return dump_ip_table (vam, 1);
5100 }
5101
5102 static char *
5103 counter_type_to_str (u8 counter_type, u8 is_combined)
5104 {
5105   if (!is_combined)
5106     {
5107       switch (counter_type)
5108         {
5109         case VNET_INTERFACE_COUNTER_DROP:
5110           return "drop";
5111         case VNET_INTERFACE_COUNTER_PUNT:
5112           return "punt";
5113         case VNET_INTERFACE_COUNTER_IP4:
5114           return "ip4";
5115         case VNET_INTERFACE_COUNTER_IP6:
5116           return "ip6";
5117         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
5118           return "rx-no-buf";
5119         case VNET_INTERFACE_COUNTER_RX_MISS:
5120           return "rx-miss";
5121         case VNET_INTERFACE_COUNTER_RX_ERROR:
5122           return "rx-error";
5123         case VNET_INTERFACE_COUNTER_TX_ERROR:
5124           return "tx-error";
5125         default:
5126           return "INVALID-COUNTER-TYPE";
5127         }
5128     }
5129   else
5130     {
5131       switch (counter_type)
5132         {
5133         case VNET_INTERFACE_COUNTER_RX:
5134           return "rx";
5135         case VNET_INTERFACE_COUNTER_TX:
5136           return "tx";
5137         default:
5138           return "INVALID-COUNTER-TYPE";
5139         }
5140     }
5141 }
5142
5143 static int
5144 dump_stats_table (vat_main_t * vam)
5145 {
5146   vat_json_node_t node;
5147   vat_json_node_t *msg_array;
5148   vat_json_node_t *msg;
5149   vat_json_node_t *counter_array;
5150   vat_json_node_t *counter;
5151   interface_counter_t c;
5152   u64 packets;
5153   ip4_fib_counter_t *c4;
5154   ip6_fib_counter_t *c6;
5155   ip4_nbr_counter_t *n4;
5156   ip6_nbr_counter_t *n6;
5157   int i, j;
5158
5159   if (!vam->json_output)
5160     {
5161       clib_warning ("dump_stats_table supported only in JSON format");
5162       return -99;
5163     }
5164
5165   vat_json_init_object (&node);
5166
5167   /* interface counters */
5168   msg_array = vat_json_object_add (&node, "interface_counters");
5169   vat_json_init_array (msg_array);
5170   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
5171     {
5172       msg = vat_json_array_add (msg_array);
5173       vat_json_init_object (msg);
5174       vat_json_object_add_string_copy (msg, "vnet_counter_type",
5175                                        (u8 *) counter_type_to_str (i, 0));
5176       vat_json_object_add_int (msg, "is_combined", 0);
5177       counter_array = vat_json_object_add (msg, "data");
5178       vat_json_init_array (counter_array);
5179       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
5180         {
5181           packets = vam->simple_interface_counters[i][j];
5182           vat_json_array_add_uint (counter_array, packets);
5183         }
5184     }
5185   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
5186     {
5187       msg = vat_json_array_add (msg_array);
5188       vat_json_init_object (msg);
5189       vat_json_object_add_string_copy (msg, "vnet_counter_type",
5190                                        (u8 *) counter_type_to_str (i, 1));
5191       vat_json_object_add_int (msg, "is_combined", 1);
5192       counter_array = vat_json_object_add (msg, "data");
5193       vat_json_init_array (counter_array);
5194       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
5195         {
5196           c = vam->combined_interface_counters[i][j];
5197           counter = vat_json_array_add (counter_array);
5198           vat_json_init_object (counter);
5199           vat_json_object_add_uint (counter, "packets", c.packets);
5200           vat_json_object_add_uint (counter, "bytes", c.bytes);
5201         }
5202     }
5203
5204   /* ip4 fib counters */
5205   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
5206   vat_json_init_array (msg_array);
5207   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
5208     {
5209       msg = vat_json_array_add (msg_array);
5210       vat_json_init_object (msg);
5211       vat_json_object_add_uint (msg, "vrf_id",
5212                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
5213       counter_array = vat_json_object_add (msg, "c");
5214       vat_json_init_array (counter_array);
5215       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
5216         {
5217           counter = vat_json_array_add (counter_array);
5218           vat_json_init_object (counter);
5219           c4 = &vam->ip4_fib_counters[i][j];
5220           vat_json_object_add_ip4 (counter, "address", c4->address);
5221           vat_json_object_add_uint (counter, "address_length",
5222                                     c4->address_length);
5223           vat_json_object_add_uint (counter, "packets", c4->packets);
5224           vat_json_object_add_uint (counter, "bytes", c4->bytes);
5225         }
5226     }
5227
5228   /* ip6 fib counters */
5229   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
5230   vat_json_init_array (msg_array);
5231   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
5232     {
5233       msg = vat_json_array_add (msg_array);
5234       vat_json_init_object (msg);
5235       vat_json_object_add_uint (msg, "vrf_id",
5236                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
5237       counter_array = vat_json_object_add (msg, "c");
5238       vat_json_init_array (counter_array);
5239       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
5240         {
5241           counter = vat_json_array_add (counter_array);
5242           vat_json_init_object (counter);
5243           c6 = &vam->ip6_fib_counters[i][j];
5244           vat_json_object_add_ip6 (counter, "address", c6->address);
5245           vat_json_object_add_uint (counter, "address_length",
5246                                     c6->address_length);
5247           vat_json_object_add_uint (counter, "packets", c6->packets);
5248           vat_json_object_add_uint (counter, "bytes", c6->bytes);
5249         }
5250     }
5251
5252   /* ip4 nbr counters */
5253   msg_array = vat_json_object_add (&node, "ip4_nbr_counters");
5254   vat_json_init_array (msg_array);
5255   for (i = 0; i < vec_len (vam->ip4_nbr_counters); i++)
5256     {
5257       msg = vat_json_array_add (msg_array);
5258       vat_json_init_object (msg);
5259       vat_json_object_add_uint (msg, "sw_if_index", i);
5260       counter_array = vat_json_object_add (msg, "c");
5261       vat_json_init_array (counter_array);
5262       for (j = 0; j < vec_len (vam->ip4_nbr_counters[i]); j++)
5263         {
5264           counter = vat_json_array_add (counter_array);
5265           vat_json_init_object (counter);
5266           n4 = &vam->ip4_nbr_counters[i][j];
5267           vat_json_object_add_ip4 (counter, "address", n4->address);
5268           vat_json_object_add_uint (counter, "link-type", n4->linkt);
5269           vat_json_object_add_uint (counter, "packets", n4->packets);
5270           vat_json_object_add_uint (counter, "bytes", n4->bytes);
5271         }
5272     }
5273
5274   /* ip6 nbr counters */
5275   msg_array = vat_json_object_add (&node, "ip6_nbr_counters");
5276   vat_json_init_array (msg_array);
5277   for (i = 0; i < vec_len (vam->ip6_nbr_counters); i++)
5278     {
5279       msg = vat_json_array_add (msg_array);
5280       vat_json_init_object (msg);
5281       vat_json_object_add_uint (msg, "sw_if_index", i);
5282       counter_array = vat_json_object_add (msg, "c");
5283       vat_json_init_array (counter_array);
5284       for (j = 0; j < vec_len (vam->ip6_nbr_counters[i]); j++)
5285         {
5286           counter = vat_json_array_add (counter_array);
5287           vat_json_init_object (counter);
5288           n6 = &vam->ip6_nbr_counters[i][j];
5289           vat_json_object_add_ip6 (counter, "address", n6->address);
5290           vat_json_object_add_uint (counter, "packets", n6->packets);
5291           vat_json_object_add_uint (counter, "bytes", n6->bytes);
5292         }
5293     }
5294
5295   vat_json_print (vam->ofp, &node);
5296   vat_json_free (&node);
5297
5298   return 0;
5299 }
5300
5301 int
5302 exec (vat_main_t * vam)
5303 {
5304   api_main_t *am = &api_main;
5305   vl_api_cli_t *mp;
5306   f64 timeout;
5307   void *oldheap;
5308   u8 *cmd = 0;
5309   unformat_input_t *i = vam->input;
5310
5311   if (vec_len (i->buffer) == 0)
5312     return -1;
5313
5314   if (vam->exec_mode == 0 && unformat (i, "mode"))
5315     {
5316       vam->exec_mode = 1;
5317       return 0;
5318     }
5319   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
5320     {
5321       vam->exec_mode = 0;
5322       return 0;
5323     }
5324
5325
5326   M (CLI, mp);
5327
5328   /*
5329    * Copy cmd into shared memory.
5330    * In order for the CLI command to work, it
5331    * must be a vector ending in \n, not a C-string ending
5332    * in \n\0.
5333    */
5334   pthread_mutex_lock (&am->vlib_rp->mutex);
5335   oldheap = svm_push_data_heap (am->vlib_rp);
5336
5337   vec_validate (cmd, vec_len (vam->input->buffer) - 1);
5338   clib_memcpy (cmd, vam->input->buffer, vec_len (vam->input->buffer));
5339
5340   svm_pop_heap (oldheap);
5341   pthread_mutex_unlock (&am->vlib_rp->mutex);
5342
5343   mp->cmd_in_shmem = pointer_to_uword (cmd);
5344   S (mp);
5345   timeout = vat_time_now (vam) + 10.0;
5346
5347   while (vat_time_now (vam) < timeout)
5348     {
5349       if (vam->result_ready == 1)
5350         {
5351           u8 *free_me;
5352           if (vam->shmem_result != NULL)
5353             print (vam->ofp, "%s", vam->shmem_result);
5354           pthread_mutex_lock (&am->vlib_rp->mutex);
5355           oldheap = svm_push_data_heap (am->vlib_rp);
5356
5357           free_me = (u8 *) vam->shmem_result;
5358           vec_free (free_me);
5359
5360           svm_pop_heap (oldheap);
5361           pthread_mutex_unlock (&am->vlib_rp->mutex);
5362           return 0;
5363         }
5364     }
5365   return -99;
5366 }
5367
5368 /*
5369  * Future replacement of exec() that passes CLI buffers directly in
5370  * the API messages instead of an additional shared memory area.
5371  */
5372 static int
5373 exec_inband (vat_main_t * vam)
5374 {
5375   vl_api_cli_inband_t *mp;
5376   unformat_input_t *i = vam->input;
5377   int ret;
5378
5379   if (vec_len (i->buffer) == 0)
5380     return -1;
5381
5382   if (vam->exec_mode == 0 && unformat (i, "mode"))
5383     {
5384       vam->exec_mode = 1;
5385       return 0;
5386     }
5387   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
5388     {
5389       vam->exec_mode = 0;
5390       return 0;
5391     }
5392
5393   /*
5394    * In order for the CLI command to work, it
5395    * must be a vector ending in \n, not a C-string ending
5396    * in \n\0.
5397    */
5398   u32 len = vec_len (vam->input->buffer);
5399   M2 (CLI_INBAND, mp, len);
5400   clib_memcpy (mp->cmd, vam->input->buffer, len);
5401   mp->length = htonl (len);
5402
5403   S (mp);
5404   W2 (ret, print (vam->ofp, "%s", vam->cmd_reply));
5405   return ret;
5406 }
5407
5408 static int
5409 api_create_loopback (vat_main_t * vam)
5410 {
5411   unformat_input_t *i = vam->input;
5412   vl_api_create_loopback_t *mp;
5413   vl_api_create_loopback_instance_t *mp_lbi;
5414   u8 mac_address[6];
5415   u8 mac_set = 0;
5416   u8 is_specified = 0;
5417   u32 user_instance = 0;
5418   int ret;
5419
5420   memset (mac_address, 0, sizeof (mac_address));
5421
5422   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5423     {
5424       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5425         mac_set = 1;
5426       if (unformat (i, "instance %d", &user_instance))
5427         is_specified = 1;
5428       else
5429         break;
5430     }
5431
5432   if (is_specified)
5433     {
5434       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
5435       mp_lbi->is_specified = is_specified;
5436       if (is_specified)
5437         mp_lbi->user_instance = htonl (user_instance);
5438       if (mac_set)
5439         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
5440       S (mp_lbi);
5441     }
5442   else
5443     {
5444       /* Construct the API message */
5445       M (CREATE_LOOPBACK, mp);
5446       if (mac_set)
5447         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
5448       S (mp);
5449     }
5450
5451   W (ret);
5452   return ret;
5453 }
5454
5455 static int
5456 api_delete_loopback (vat_main_t * vam)
5457 {
5458   unformat_input_t *i = vam->input;
5459   vl_api_delete_loopback_t *mp;
5460   u32 sw_if_index = ~0;
5461   int ret;
5462
5463   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5464     {
5465       if (unformat (i, "sw_if_index %d", &sw_if_index))
5466         ;
5467       else
5468         break;
5469     }
5470
5471   if (sw_if_index == ~0)
5472     {
5473       errmsg ("missing sw_if_index");
5474       return -99;
5475     }
5476
5477   /* Construct the API message */
5478   M (DELETE_LOOPBACK, mp);
5479   mp->sw_if_index = ntohl (sw_if_index);
5480
5481   S (mp);
5482   W (ret);
5483   return ret;
5484 }
5485
5486 static int
5487 api_want_stats (vat_main_t * vam)
5488 {
5489   unformat_input_t *i = vam->input;
5490   vl_api_want_stats_t *mp;
5491   int enable = -1;
5492   int ret;
5493
5494   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5495     {
5496       if (unformat (i, "enable"))
5497         enable = 1;
5498       else if (unformat (i, "disable"))
5499         enable = 0;
5500       else
5501         break;
5502     }
5503
5504   if (enable == -1)
5505     {
5506       errmsg ("missing enable|disable");
5507       return -99;
5508     }
5509
5510   M (WANT_STATS, mp);
5511   mp->enable_disable = enable;
5512
5513   S (mp);
5514   W (ret);
5515   return ret;
5516 }
5517
5518 static int
5519 api_want_interface_events (vat_main_t * vam)
5520 {
5521   unformat_input_t *i = vam->input;
5522   vl_api_want_interface_events_t *mp;
5523   int enable = -1;
5524   int ret;
5525
5526   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5527     {
5528       if (unformat (i, "enable"))
5529         enable = 1;
5530       else if (unformat (i, "disable"))
5531         enable = 0;
5532       else
5533         break;
5534     }
5535
5536   if (enable == -1)
5537     {
5538       errmsg ("missing enable|disable");
5539       return -99;
5540     }
5541
5542   M (WANT_INTERFACE_EVENTS, mp);
5543   mp->enable_disable = enable;
5544
5545   vam->interface_event_display = enable;
5546
5547   S (mp);
5548   W (ret);
5549   return ret;
5550 }
5551
5552
5553 /* Note: non-static, called once to set up the initial intfc table */
5554 int
5555 api_sw_interface_dump (vat_main_t * vam)
5556 {
5557   vl_api_sw_interface_dump_t *mp;
5558   vl_api_control_ping_t *mp_ping;
5559   hash_pair_t *p;
5560   name_sort_t *nses = 0, *ns;
5561   sw_interface_subif_t *sub = NULL;
5562   int ret;
5563
5564   /* Toss the old name table */
5565   /* *INDENT-OFF* */
5566   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5567   ({
5568     vec_add2 (nses, ns, 1);
5569     ns->name = (u8 *)(p->key);
5570     ns->value = (u32) p->value[0];
5571   }));
5572   /* *INDENT-ON* */
5573
5574   hash_free (vam->sw_if_index_by_interface_name);
5575
5576   vec_foreach (ns, nses) vec_free (ns->name);
5577
5578   vec_free (nses);
5579
5580   vec_foreach (sub, vam->sw_if_subif_table)
5581   {
5582     vec_free (sub->interface_name);
5583   }
5584   vec_free (vam->sw_if_subif_table);
5585
5586   /* recreate the interface name hash table */
5587   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
5588
5589   /* Get list of ethernets */
5590   M (SW_INTERFACE_DUMP, mp);
5591   mp->name_filter_valid = 1;
5592   strncpy ((char *) mp->name_filter, "Ether", sizeof (mp->name_filter) - 1);
5593   S (mp);
5594
5595   /* and local / loopback interfaces */
5596   M (SW_INTERFACE_DUMP, mp);
5597   mp->name_filter_valid = 1;
5598   strncpy ((char *) mp->name_filter, "lo", sizeof (mp->name_filter) - 1);
5599   S (mp);
5600
5601   /* and packet-generator interfaces */
5602   M (SW_INTERFACE_DUMP, mp);
5603   mp->name_filter_valid = 1;
5604   strncpy ((char *) mp->name_filter, "pg", sizeof (mp->name_filter) - 1);
5605   S (mp);
5606
5607   /* and vxlan-gpe tunnel interfaces */
5608   M (SW_INTERFACE_DUMP, mp);
5609   mp->name_filter_valid = 1;
5610   strncpy ((char *) mp->name_filter, "vxlan_gpe",
5611            sizeof (mp->name_filter) - 1);
5612   S (mp);
5613
5614   /* and vxlan tunnel interfaces */
5615   M (SW_INTERFACE_DUMP, mp);
5616   mp->name_filter_valid = 1;
5617   strncpy ((char *) mp->name_filter, "vxlan", sizeof (mp->name_filter) - 1);
5618   S (mp);
5619
5620   /* and host (af_packet) interfaces */
5621   M (SW_INTERFACE_DUMP, mp);
5622   mp->name_filter_valid = 1;
5623   strncpy ((char *) mp->name_filter, "host", sizeof (mp->name_filter) - 1);
5624   S (mp);
5625
5626   /* and l2tpv3 tunnel interfaces */
5627   M (SW_INTERFACE_DUMP, mp);
5628   mp->name_filter_valid = 1;
5629   strncpy ((char *) mp->name_filter, "l2tpv3_tunnel",
5630            sizeof (mp->name_filter) - 1);
5631   S (mp);
5632
5633   /* and GRE tunnel interfaces */
5634   M (SW_INTERFACE_DUMP, mp);
5635   mp->name_filter_valid = 1;
5636   strncpy ((char *) mp->name_filter, "gre", sizeof (mp->name_filter) - 1);
5637   S (mp);
5638
5639   /* and LISP-GPE interfaces */
5640   M (SW_INTERFACE_DUMP, mp);
5641   mp->name_filter_valid = 1;
5642   strncpy ((char *) mp->name_filter, "lisp_gpe",
5643            sizeof (mp->name_filter) - 1);
5644   S (mp);
5645
5646   /* and IPSEC tunnel interfaces */
5647   M (SW_INTERFACE_DUMP, mp);
5648   mp->name_filter_valid = 1;
5649   strncpy ((char *) mp->name_filter, "ipsec", sizeof (mp->name_filter) - 1);
5650   S (mp);
5651
5652   /* Use a control ping for synchronization */
5653   M (CONTROL_PING, mp_ping);
5654   S (mp_ping);
5655
5656   W (ret);
5657   return ret;
5658 }
5659
5660 static int
5661 api_sw_interface_set_flags (vat_main_t * vam)
5662 {
5663   unformat_input_t *i = vam->input;
5664   vl_api_sw_interface_set_flags_t *mp;
5665   u32 sw_if_index;
5666   u8 sw_if_index_set = 0;
5667   u8 admin_up = 0, link_up = 0;
5668   int ret;
5669
5670   /* Parse args required to build the message */
5671   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5672     {
5673       if (unformat (i, "admin-up"))
5674         admin_up = 1;
5675       else if (unformat (i, "admin-down"))
5676         admin_up = 0;
5677       else if (unformat (i, "link-up"))
5678         link_up = 1;
5679       else if (unformat (i, "link-down"))
5680         link_up = 0;
5681       else
5682         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5683         sw_if_index_set = 1;
5684       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5685         sw_if_index_set = 1;
5686       else
5687         break;
5688     }
5689
5690   if (sw_if_index_set == 0)
5691     {
5692       errmsg ("missing interface name or sw_if_index");
5693       return -99;
5694     }
5695
5696   /* Construct the API message */
5697   M (SW_INTERFACE_SET_FLAGS, mp);
5698   mp->sw_if_index = ntohl (sw_if_index);
5699   mp->admin_up_down = admin_up;
5700   mp->link_up_down = link_up;
5701
5702   /* send it... */
5703   S (mp);
5704
5705   /* Wait for a reply, return the good/bad news... */
5706   W (ret);
5707   return ret;
5708 }
5709
5710 static int
5711 api_sw_interface_clear_stats (vat_main_t * vam)
5712 {
5713   unformat_input_t *i = vam->input;
5714   vl_api_sw_interface_clear_stats_t *mp;
5715   u32 sw_if_index;
5716   u8 sw_if_index_set = 0;
5717   int ret;
5718
5719   /* Parse args required to build the message */
5720   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5721     {
5722       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5723         sw_if_index_set = 1;
5724       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5725         sw_if_index_set = 1;
5726       else
5727         break;
5728     }
5729
5730   /* Construct the API message */
5731   M (SW_INTERFACE_CLEAR_STATS, mp);
5732
5733   if (sw_if_index_set == 1)
5734     mp->sw_if_index = ntohl (sw_if_index);
5735   else
5736     mp->sw_if_index = ~0;
5737
5738   /* send it... */
5739   S (mp);
5740
5741   /* Wait for a reply, return the good/bad news... */
5742   W (ret);
5743   return ret;
5744 }
5745
5746 static int
5747 api_sw_interface_add_del_address (vat_main_t * vam)
5748 {
5749   unformat_input_t *i = vam->input;
5750   vl_api_sw_interface_add_del_address_t *mp;
5751   u32 sw_if_index;
5752   u8 sw_if_index_set = 0;
5753   u8 is_add = 1, del_all = 0;
5754   u32 address_length = 0;
5755   u8 v4_address_set = 0;
5756   u8 v6_address_set = 0;
5757   ip4_address_t v4address;
5758   ip6_address_t v6address;
5759   int ret;
5760
5761   /* Parse args required to build the message */
5762   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5763     {
5764       if (unformat (i, "del-all"))
5765         del_all = 1;
5766       else if (unformat (i, "del"))
5767         is_add = 0;
5768       else
5769         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5770         sw_if_index_set = 1;
5771       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5772         sw_if_index_set = 1;
5773       else if (unformat (i, "%U/%d",
5774                          unformat_ip4_address, &v4address, &address_length))
5775         v4_address_set = 1;
5776       else if (unformat (i, "%U/%d",
5777                          unformat_ip6_address, &v6address, &address_length))
5778         v6_address_set = 1;
5779       else
5780         break;
5781     }
5782
5783   if (sw_if_index_set == 0)
5784     {
5785       errmsg ("missing interface name or sw_if_index");
5786       return -99;
5787     }
5788   if (v4_address_set && v6_address_set)
5789     {
5790       errmsg ("both v4 and v6 addresses set");
5791       return -99;
5792     }
5793   if (!v4_address_set && !v6_address_set && !del_all)
5794     {
5795       errmsg ("no addresses set");
5796       return -99;
5797     }
5798
5799   /* Construct the API message */
5800   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
5801
5802   mp->sw_if_index = ntohl (sw_if_index);
5803   mp->is_add = is_add;
5804   mp->del_all = del_all;
5805   if (v6_address_set)
5806     {
5807       mp->is_ipv6 = 1;
5808       clib_memcpy (mp->address, &v6address, sizeof (v6address));
5809     }
5810   else
5811     {
5812       clib_memcpy (mp->address, &v4address, sizeof (v4address));
5813     }
5814   mp->address_length = address_length;
5815
5816   /* send it... */
5817   S (mp);
5818
5819   /* Wait for a reply, return good/bad news  */
5820   W (ret);
5821   return ret;
5822 }
5823
5824 static int
5825 api_sw_interface_set_mpls_enable (vat_main_t * vam)
5826 {
5827   unformat_input_t *i = vam->input;
5828   vl_api_sw_interface_set_mpls_enable_t *mp;
5829   u32 sw_if_index;
5830   u8 sw_if_index_set = 0;
5831   u8 enable = 1;
5832   int ret;
5833
5834   /* Parse args required to build the message */
5835   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5836     {
5837       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5838         sw_if_index_set = 1;
5839       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5840         sw_if_index_set = 1;
5841       else if (unformat (i, "disable"))
5842         enable = 0;
5843       else if (unformat (i, "dis"))
5844         enable = 0;
5845       else
5846         break;
5847     }
5848
5849   if (sw_if_index_set == 0)
5850     {
5851       errmsg ("missing interface name or sw_if_index");
5852       return -99;
5853     }
5854
5855   /* Construct the API message */
5856   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
5857
5858   mp->sw_if_index = ntohl (sw_if_index);
5859   mp->enable = enable;
5860
5861   /* send it... */
5862   S (mp);
5863
5864   /* Wait for a reply... */
5865   W (ret);
5866   return ret;
5867 }
5868
5869 static int
5870 api_sw_interface_set_table (vat_main_t * vam)
5871 {
5872   unformat_input_t *i = vam->input;
5873   vl_api_sw_interface_set_table_t *mp;
5874   u32 sw_if_index, vrf_id = 0;
5875   u8 sw_if_index_set = 0;
5876   u8 is_ipv6 = 0;
5877   int ret;
5878
5879   /* Parse args required to build the message */
5880   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5881     {
5882       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5883         sw_if_index_set = 1;
5884       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5885         sw_if_index_set = 1;
5886       else if (unformat (i, "vrf %d", &vrf_id))
5887         ;
5888       else if (unformat (i, "ipv6"))
5889         is_ipv6 = 1;
5890       else
5891         break;
5892     }
5893
5894   if (sw_if_index_set == 0)
5895     {
5896       errmsg ("missing interface name or sw_if_index");
5897       return -99;
5898     }
5899
5900   /* Construct the API message */
5901   M (SW_INTERFACE_SET_TABLE, mp);
5902
5903   mp->sw_if_index = ntohl (sw_if_index);
5904   mp->is_ipv6 = is_ipv6;
5905   mp->vrf_id = ntohl (vrf_id);
5906
5907   /* send it... */
5908   S (mp);
5909
5910   /* Wait for a reply... */
5911   W (ret);
5912   return ret;
5913 }
5914
5915 static void vl_api_sw_interface_get_table_reply_t_handler
5916   (vl_api_sw_interface_get_table_reply_t * mp)
5917 {
5918   vat_main_t *vam = &vat_main;
5919
5920   print (vam->ofp, "%d", ntohl (mp->vrf_id));
5921
5922   vam->retval = ntohl (mp->retval);
5923   vam->result_ready = 1;
5924
5925 }
5926
5927 static void vl_api_sw_interface_get_table_reply_t_handler_json
5928   (vl_api_sw_interface_get_table_reply_t * mp)
5929 {
5930   vat_main_t *vam = &vat_main;
5931   vat_json_node_t node;
5932
5933   vat_json_init_object (&node);
5934   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
5935   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
5936
5937   vat_json_print (vam->ofp, &node);
5938   vat_json_free (&node);
5939
5940   vam->retval = ntohl (mp->retval);
5941   vam->result_ready = 1;
5942 }
5943
5944 static int
5945 api_sw_interface_get_table (vat_main_t * vam)
5946 {
5947   unformat_input_t *i = vam->input;
5948   vl_api_sw_interface_get_table_t *mp;
5949   u32 sw_if_index;
5950   u8 sw_if_index_set = 0;
5951   u8 is_ipv6 = 0;
5952   int ret;
5953
5954   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5955     {
5956       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5957         sw_if_index_set = 1;
5958       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5959         sw_if_index_set = 1;
5960       else if (unformat (i, "ipv6"))
5961         is_ipv6 = 1;
5962       else
5963         break;
5964     }
5965
5966   if (sw_if_index_set == 0)
5967     {
5968       errmsg ("missing interface name or sw_if_index");
5969       return -99;
5970     }
5971
5972   M (SW_INTERFACE_GET_TABLE, mp);
5973   mp->sw_if_index = htonl (sw_if_index);
5974   mp->is_ipv6 = is_ipv6;
5975
5976   S (mp);
5977   W (ret);
5978   return ret;
5979 }
5980
5981 static int
5982 api_sw_interface_set_vpath (vat_main_t * vam)
5983 {
5984   unformat_input_t *i = vam->input;
5985   vl_api_sw_interface_set_vpath_t *mp;
5986   u32 sw_if_index = 0;
5987   u8 sw_if_index_set = 0;
5988   u8 is_enable = 0;
5989   int ret;
5990
5991   /* Parse args required to build the message */
5992   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5993     {
5994       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5995         sw_if_index_set = 1;
5996       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5997         sw_if_index_set = 1;
5998       else if (unformat (i, "enable"))
5999         is_enable = 1;
6000       else if (unformat (i, "disable"))
6001         is_enable = 0;
6002       else
6003         break;
6004     }
6005
6006   if (sw_if_index_set == 0)
6007     {
6008       errmsg ("missing interface name or sw_if_index");
6009       return -99;
6010     }
6011
6012   /* Construct the API message */
6013   M (SW_INTERFACE_SET_VPATH, mp);
6014
6015   mp->sw_if_index = ntohl (sw_if_index);
6016   mp->enable = is_enable;
6017
6018   /* send it... */
6019   S (mp);
6020
6021   /* Wait for a reply... */
6022   W (ret);
6023   return ret;
6024 }
6025
6026 static int
6027 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
6028 {
6029   unformat_input_t *i = vam->input;
6030   vl_api_sw_interface_set_vxlan_bypass_t *mp;
6031   u32 sw_if_index = 0;
6032   u8 sw_if_index_set = 0;
6033   u8 is_enable = 1;
6034   u8 is_ipv6 = 0;
6035   int ret;
6036
6037   /* Parse args required to build the message */
6038   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6039     {
6040       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6041         sw_if_index_set = 1;
6042       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6043         sw_if_index_set = 1;
6044       else if (unformat (i, "enable"))
6045         is_enable = 1;
6046       else if (unformat (i, "disable"))
6047         is_enable = 0;
6048       else if (unformat (i, "ip4"))
6049         is_ipv6 = 0;
6050       else if (unformat (i, "ip6"))
6051         is_ipv6 = 1;
6052       else
6053         break;
6054     }
6055
6056   if (sw_if_index_set == 0)
6057     {
6058       errmsg ("missing interface name or sw_if_index");
6059       return -99;
6060     }
6061
6062   /* Construct the API message */
6063   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
6064
6065   mp->sw_if_index = ntohl (sw_if_index);
6066   mp->enable = is_enable;
6067   mp->is_ipv6 = is_ipv6;
6068
6069   /* send it... */
6070   S (mp);
6071
6072   /* Wait for a reply... */
6073   W (ret);
6074   return ret;
6075 }
6076
6077
6078 static int
6079 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
6080 {
6081   unformat_input_t *i = vam->input;
6082   vl_api_sw_interface_set_l2_xconnect_t *mp;
6083   u32 rx_sw_if_index;
6084   u8 rx_sw_if_index_set = 0;
6085   u32 tx_sw_if_index;
6086   u8 tx_sw_if_index_set = 0;
6087   u8 enable = 1;
6088   int ret;
6089
6090   /* Parse args required to build the message */
6091   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6092     {
6093       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
6094         rx_sw_if_index_set = 1;
6095       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
6096         tx_sw_if_index_set = 1;
6097       else if (unformat (i, "rx"))
6098         {
6099           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6100             {
6101               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6102                             &rx_sw_if_index))
6103                 rx_sw_if_index_set = 1;
6104             }
6105           else
6106             break;
6107         }
6108       else if (unformat (i, "tx"))
6109         {
6110           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6111             {
6112               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6113                             &tx_sw_if_index))
6114                 tx_sw_if_index_set = 1;
6115             }
6116           else
6117             break;
6118         }
6119       else if (unformat (i, "enable"))
6120         enable = 1;
6121       else if (unformat (i, "disable"))
6122         enable = 0;
6123       else
6124         break;
6125     }
6126
6127   if (rx_sw_if_index_set == 0)
6128     {
6129       errmsg ("missing rx interface name or rx_sw_if_index");
6130       return -99;
6131     }
6132
6133   if (enable && (tx_sw_if_index_set == 0))
6134     {
6135       errmsg ("missing tx interface name or tx_sw_if_index");
6136       return -99;
6137     }
6138
6139   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
6140
6141   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6142   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
6143   mp->enable = enable;
6144
6145   S (mp);
6146   W (ret);
6147   return ret;
6148 }
6149
6150 static int
6151 api_sw_interface_set_l2_bridge (vat_main_t * vam)
6152 {
6153   unformat_input_t *i = vam->input;
6154   vl_api_sw_interface_set_l2_bridge_t *mp;
6155   u32 rx_sw_if_index;
6156   u8 rx_sw_if_index_set = 0;
6157   u32 bd_id;
6158   u8 bd_id_set = 0;
6159   u8 bvi = 0;
6160   u32 shg = 0;
6161   u8 enable = 1;
6162   int ret;
6163
6164   /* Parse args required to build the message */
6165   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6166     {
6167       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
6168         rx_sw_if_index_set = 1;
6169       else if (unformat (i, "bd_id %d", &bd_id))
6170         bd_id_set = 1;
6171       else
6172         if (unformat
6173             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
6174         rx_sw_if_index_set = 1;
6175       else if (unformat (i, "shg %d", &shg))
6176         ;
6177       else if (unformat (i, "bvi"))
6178         bvi = 1;
6179       else if (unformat (i, "enable"))
6180         enable = 1;
6181       else if (unformat (i, "disable"))
6182         enable = 0;
6183       else
6184         break;
6185     }
6186
6187   if (rx_sw_if_index_set == 0)
6188     {
6189       errmsg ("missing rx interface name or sw_if_index");
6190       return -99;
6191     }
6192
6193   if (enable && (bd_id_set == 0))
6194     {
6195       errmsg ("missing bridge domain");
6196       return -99;
6197     }
6198
6199   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
6200
6201   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6202   mp->bd_id = ntohl (bd_id);
6203   mp->shg = (u8) shg;
6204   mp->bvi = bvi;
6205   mp->enable = enable;
6206
6207   S (mp);
6208   W (ret);
6209   return ret;
6210 }
6211
6212 static int
6213 api_bridge_domain_dump (vat_main_t * vam)
6214 {
6215   unformat_input_t *i = vam->input;
6216   vl_api_bridge_domain_dump_t *mp;
6217   vl_api_control_ping_t *mp_ping;
6218   u32 bd_id = ~0;
6219   int ret;
6220
6221   /* Parse args required to build the message */
6222   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6223     {
6224       if (unformat (i, "bd_id %d", &bd_id))
6225         ;
6226       else
6227         break;
6228     }
6229
6230   M (BRIDGE_DOMAIN_DUMP, mp);
6231   mp->bd_id = ntohl (bd_id);
6232   S (mp);
6233
6234   /* Use a control ping for synchronization */
6235   M (CONTROL_PING, mp_ping);
6236   S (mp_ping);
6237
6238   W (ret);
6239   return ret;
6240 }
6241
6242 static int
6243 api_bridge_domain_add_del (vat_main_t * vam)
6244 {
6245   unformat_input_t *i = vam->input;
6246   vl_api_bridge_domain_add_del_t *mp;
6247   u32 bd_id = ~0;
6248   u8 is_add = 1;
6249   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
6250   u32 mac_age = 0;
6251   int ret;
6252
6253   /* Parse args required to build the message */
6254   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6255     {
6256       if (unformat (i, "bd_id %d", &bd_id))
6257         ;
6258       else if (unformat (i, "flood %d", &flood))
6259         ;
6260       else if (unformat (i, "uu-flood %d", &uu_flood))
6261         ;
6262       else if (unformat (i, "forward %d", &forward))
6263         ;
6264       else if (unformat (i, "learn %d", &learn))
6265         ;
6266       else if (unformat (i, "arp-term %d", &arp_term))
6267         ;
6268       else if (unformat (i, "mac-age %d", &mac_age))
6269         ;
6270       else if (unformat (i, "del"))
6271         {
6272           is_add = 0;
6273           flood = uu_flood = forward = learn = 0;
6274         }
6275       else
6276         break;
6277     }
6278
6279   if (bd_id == ~0)
6280     {
6281       errmsg ("missing bridge domain");
6282       return -99;
6283     }
6284
6285   if (mac_age > 255)
6286     {
6287       errmsg ("mac age must be less than 256 ");
6288       return -99;
6289     }
6290
6291   M (BRIDGE_DOMAIN_ADD_DEL, mp);
6292
6293   mp->bd_id = ntohl (bd_id);
6294   mp->flood = flood;
6295   mp->uu_flood = uu_flood;
6296   mp->forward = forward;
6297   mp->learn = learn;
6298   mp->arp_term = arp_term;
6299   mp->is_add = is_add;
6300   mp->mac_age = (u8) mac_age;
6301
6302   S (mp);
6303   W (ret);
6304   return ret;
6305 }
6306
6307 static int
6308 api_l2fib_flush_bd (vat_main_t * vam)
6309 {
6310   unformat_input_t *i = vam->input;
6311   vl_api_l2fib_flush_bd_t *mp;
6312   u32 bd_id = ~0;
6313   int ret;
6314
6315   /* Parse args required to build the message */
6316   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6317     {
6318       if (unformat (i, "bd_id %d", &bd_id));
6319       else
6320         break;
6321     }
6322
6323   if (bd_id == ~0)
6324     {
6325       errmsg ("missing bridge domain");
6326       return -99;
6327     }
6328
6329   M (L2FIB_FLUSH_BD, mp);
6330
6331   mp->bd_id = htonl (bd_id);
6332
6333   S (mp);
6334   W (ret);
6335   return ret;
6336 }
6337
6338 static int
6339 api_l2fib_flush_int (vat_main_t * vam)
6340 {
6341   unformat_input_t *i = vam->input;
6342   vl_api_l2fib_flush_int_t *mp;
6343   u32 sw_if_index = ~0;
6344   int ret;
6345
6346   /* Parse args required to build the message */
6347   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6348     {
6349       if (unformat (i, "sw_if_index %d", &sw_if_index));
6350       else
6351         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
6352       else
6353         break;
6354     }
6355
6356   if (sw_if_index == ~0)
6357     {
6358       errmsg ("missing interface name or sw_if_index");
6359       return -99;
6360     }
6361
6362   M (L2FIB_FLUSH_INT, mp);
6363
6364   mp->sw_if_index = ntohl (sw_if_index);
6365
6366   S (mp);
6367   W (ret);
6368   return ret;
6369 }
6370
6371 static int
6372 api_l2fib_add_del (vat_main_t * vam)
6373 {
6374   unformat_input_t *i = vam->input;
6375   vl_api_l2fib_add_del_t *mp;
6376   f64 timeout;
6377   u64 mac = 0;
6378   u8 mac_set = 0;
6379   u32 bd_id;
6380   u8 bd_id_set = 0;
6381   u32 sw_if_index = ~0;
6382   u8 sw_if_index_set = 0;
6383   u8 is_add = 1;
6384   u8 static_mac = 0;
6385   u8 filter_mac = 0;
6386   u8 bvi_mac = 0;
6387   int count = 1;
6388   f64 before = 0;
6389   int j;
6390
6391   /* Parse args required to build the message */
6392   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6393     {
6394       if (unformat (i, "mac %U", unformat_ethernet_address, &mac))
6395         mac_set = 1;
6396       else if (unformat (i, "bd_id %d", &bd_id))
6397         bd_id_set = 1;
6398       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6399         sw_if_index_set = 1;
6400       else if (unformat (i, "sw_if"))
6401         {
6402           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6403             {
6404               if (unformat
6405                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6406                 sw_if_index_set = 1;
6407             }
6408           else
6409             break;
6410         }
6411       else if (unformat (i, "static"))
6412         static_mac = 1;
6413       else if (unformat (i, "filter"))
6414         {
6415           filter_mac = 1;
6416           static_mac = 1;
6417         }
6418       else if (unformat (i, "bvi"))
6419         {
6420           bvi_mac = 1;
6421           static_mac = 1;
6422         }
6423       else if (unformat (i, "del"))
6424         is_add = 0;
6425       else if (unformat (i, "count %d", &count))
6426         ;
6427       else
6428         break;
6429     }
6430
6431   if (mac_set == 0)
6432     {
6433       errmsg ("missing mac address");
6434       return -99;
6435     }
6436
6437   if (bd_id_set == 0)
6438     {
6439       errmsg ("missing bridge domain");
6440       return -99;
6441     }
6442
6443   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
6444     {
6445       errmsg ("missing interface name or sw_if_index");
6446       return -99;
6447     }
6448
6449   if (count > 1)
6450     {
6451       /* Turn on async mode */
6452       vam->async_mode = 1;
6453       vam->async_errors = 0;
6454       before = vat_time_now (vam);
6455     }
6456
6457   for (j = 0; j < count; j++)
6458     {
6459       M (L2FIB_ADD_DEL, mp);
6460
6461       mp->mac = mac;
6462       mp->bd_id = ntohl (bd_id);
6463       mp->is_add = is_add;
6464
6465       if (is_add)
6466         {
6467           mp->sw_if_index = ntohl (sw_if_index);
6468           mp->static_mac = static_mac;
6469           mp->filter_mac = filter_mac;
6470           mp->bvi_mac = bvi_mac;
6471         }
6472       increment_mac_address (&mac);
6473       /* send it... */
6474       S (mp);
6475     }
6476
6477   if (count > 1)
6478     {
6479       vl_api_control_ping_t *mp_ping;
6480       f64 after;
6481
6482       /* Shut off async mode */
6483       vam->async_mode = 0;
6484
6485       M (CONTROL_PING, mp_ping);
6486       S (mp_ping);
6487
6488       timeout = vat_time_now (vam) + 1.0;
6489       while (vat_time_now (vam) < timeout)
6490         if (vam->result_ready == 1)
6491           goto out;
6492       vam->retval = -99;
6493
6494     out:
6495       if (vam->retval == -99)
6496         errmsg ("timeout");
6497
6498       if (vam->async_errors > 0)
6499         {
6500           errmsg ("%d asynchronous errors", vam->async_errors);
6501           vam->retval = -98;
6502         }
6503       vam->async_errors = 0;
6504       after = vat_time_now (vam);
6505
6506       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6507              count, after - before, count / (after - before));
6508     }
6509   else
6510     {
6511       int ret;
6512
6513       /* Wait for a reply... */
6514       W (ret);
6515       return ret;
6516     }
6517   /* Return the good/bad news */
6518   return (vam->retval);
6519 }
6520
6521 static int
6522 api_bridge_domain_set_mac_age (vat_main_t * vam)
6523 {
6524   unformat_input_t *i = vam->input;
6525   vl_api_bridge_domain_set_mac_age_t *mp;
6526   u32 bd_id = ~0;
6527   u32 mac_age = 0;
6528   int ret;
6529
6530   /* Parse args required to build the message */
6531   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6532     {
6533       if (unformat (i, "bd_id %d", &bd_id));
6534       else if (unformat (i, "mac-age %d", &mac_age));
6535       else
6536         break;
6537     }
6538
6539   if (bd_id == ~0)
6540     {
6541       errmsg ("missing bridge domain");
6542       return -99;
6543     }
6544
6545   if (mac_age > 255)
6546     {
6547       errmsg ("mac age must be less than 256 ");
6548       return -99;
6549     }
6550
6551   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
6552
6553   mp->bd_id = htonl (bd_id);
6554   mp->mac_age = (u8) mac_age;
6555
6556   S (mp);
6557   W (ret);
6558   return ret;
6559 }
6560
6561 static int
6562 api_l2_flags (vat_main_t * vam)
6563 {
6564   unformat_input_t *i = vam->input;
6565   vl_api_l2_flags_t *mp;
6566   u32 sw_if_index;
6567   u32 feature_bitmap = 0;
6568   u8 sw_if_index_set = 0;
6569   int ret;
6570
6571   /* Parse args required to build the message */
6572   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6573     {
6574       if (unformat (i, "sw_if_index %d", &sw_if_index))
6575         sw_if_index_set = 1;
6576       else if (unformat (i, "sw_if"))
6577         {
6578           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6579             {
6580               if (unformat
6581                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6582                 sw_if_index_set = 1;
6583             }
6584           else
6585             break;
6586         }
6587       else if (unformat (i, "learn"))
6588         feature_bitmap |= L2INPUT_FEAT_LEARN;
6589       else if (unformat (i, "forward"))
6590         feature_bitmap |= L2INPUT_FEAT_FWD;
6591       else if (unformat (i, "flood"))
6592         feature_bitmap |= L2INPUT_FEAT_FLOOD;
6593       else if (unformat (i, "uu-flood"))
6594         feature_bitmap |= L2INPUT_FEAT_UU_FLOOD;
6595       else
6596         break;
6597     }
6598
6599   if (sw_if_index_set == 0)
6600     {
6601       errmsg ("missing interface name or sw_if_index");
6602       return -99;
6603     }
6604
6605   M (L2_FLAGS, mp);
6606
6607   mp->sw_if_index = ntohl (sw_if_index);
6608   mp->feature_bitmap = ntohl (feature_bitmap);
6609
6610   S (mp);
6611   W (ret);
6612   return ret;
6613 }
6614
6615 static int
6616 api_bridge_flags (vat_main_t * vam)
6617 {
6618   unformat_input_t *i = vam->input;
6619   vl_api_bridge_flags_t *mp;
6620   u32 bd_id;
6621   u8 bd_id_set = 0;
6622   u8 is_set = 1;
6623   u32 flags = 0;
6624   int ret;
6625
6626   /* Parse args required to build the message */
6627   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6628     {
6629       if (unformat (i, "bd_id %d", &bd_id))
6630         bd_id_set = 1;
6631       else if (unformat (i, "learn"))
6632         flags |= L2_LEARN;
6633       else if (unformat (i, "forward"))
6634         flags |= L2_FWD;
6635       else if (unformat (i, "flood"))
6636         flags |= L2_FLOOD;
6637       else if (unformat (i, "uu-flood"))
6638         flags |= L2_UU_FLOOD;
6639       else if (unformat (i, "arp-term"))
6640         flags |= L2_ARP_TERM;
6641       else if (unformat (i, "off"))
6642         is_set = 0;
6643       else if (unformat (i, "disable"))
6644         is_set = 0;
6645       else
6646         break;
6647     }
6648
6649   if (bd_id_set == 0)
6650     {
6651       errmsg ("missing bridge domain");
6652       return -99;
6653     }
6654
6655   M (BRIDGE_FLAGS, mp);
6656
6657   mp->bd_id = ntohl (bd_id);
6658   mp->feature_bitmap = ntohl (flags);
6659   mp->is_set = is_set;
6660
6661   S (mp);
6662   W (ret);
6663   return ret;
6664 }
6665
6666 static int
6667 api_bd_ip_mac_add_del (vat_main_t * vam)
6668 {
6669   unformat_input_t *i = vam->input;
6670   vl_api_bd_ip_mac_add_del_t *mp;
6671   u32 bd_id;
6672   u8 is_ipv6 = 0;
6673   u8 is_add = 1;
6674   u8 bd_id_set = 0;
6675   u8 ip_set = 0;
6676   u8 mac_set = 0;
6677   ip4_address_t v4addr;
6678   ip6_address_t v6addr;
6679   u8 macaddr[6];
6680   int ret;
6681
6682
6683   /* Parse args required to build the message */
6684   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6685     {
6686       if (unformat (i, "bd_id %d", &bd_id))
6687         {
6688           bd_id_set++;
6689         }
6690       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
6691         {
6692           ip_set++;
6693         }
6694       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
6695         {
6696           ip_set++;
6697           is_ipv6++;
6698         }
6699       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
6700         {
6701           mac_set++;
6702         }
6703       else if (unformat (i, "del"))
6704         is_add = 0;
6705       else
6706         break;
6707     }
6708
6709   if (bd_id_set == 0)
6710     {
6711       errmsg ("missing bridge domain");
6712       return -99;
6713     }
6714   else if (ip_set == 0)
6715     {
6716       errmsg ("missing IP address");
6717       return -99;
6718     }
6719   else if (mac_set == 0)
6720     {
6721       errmsg ("missing MAC address");
6722       return -99;
6723     }
6724
6725   M (BD_IP_MAC_ADD_DEL, mp);
6726
6727   mp->bd_id = ntohl (bd_id);
6728   mp->is_ipv6 = is_ipv6;
6729   mp->is_add = is_add;
6730   if (is_ipv6)
6731     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
6732   else
6733     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
6734   clib_memcpy (mp->mac_address, macaddr, 6);
6735   S (mp);
6736   W (ret);
6737   return ret;
6738 }
6739
6740 static int
6741 api_tap_connect (vat_main_t * vam)
6742 {
6743   unformat_input_t *i = vam->input;
6744   vl_api_tap_connect_t *mp;
6745   u8 mac_address[6];
6746   u8 random_mac = 1;
6747   u8 name_set = 0;
6748   u8 *tap_name;
6749   u8 *tag = 0;
6750   ip4_address_t ip4_address;
6751   u32 ip4_mask_width;
6752   int ip4_address_set = 0;
6753   ip6_address_t ip6_address;
6754   u32 ip6_mask_width;
6755   int ip6_address_set = 0;
6756   int ret;
6757
6758   memset (mac_address, 0, sizeof (mac_address));
6759
6760   /* Parse args required to build the message */
6761   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6762     {
6763       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6764         {
6765           random_mac = 0;
6766         }
6767       else if (unformat (i, "random-mac"))
6768         random_mac = 1;
6769       else if (unformat (i, "tapname %s", &tap_name))
6770         name_set = 1;
6771       else if (unformat (i, "tag %s", &tag))
6772         ;
6773       else if (unformat (i, "address %U/%d",
6774                          unformat_ip4_address, &ip4_address, &ip4_mask_width))
6775         ip4_address_set = 1;
6776       else if (unformat (i, "address %U/%d",
6777                          unformat_ip6_address, &ip6_address, &ip6_mask_width))
6778         ip6_address_set = 1;
6779       else
6780         break;
6781     }
6782
6783   if (name_set == 0)
6784     {
6785       errmsg ("missing tap name");
6786       return -99;
6787     }
6788   if (vec_len (tap_name) > 63)
6789     {
6790       errmsg ("tap name too long");
6791       return -99;
6792     }
6793   vec_add1 (tap_name, 0);
6794
6795   if (vec_len (tag) > 63)
6796     {
6797       errmsg ("tag too long");
6798       return -99;
6799     }
6800
6801   /* Construct the API message */
6802   M (TAP_CONNECT, mp);
6803
6804   mp->use_random_mac = random_mac;
6805   clib_memcpy (mp->mac_address, mac_address, 6);
6806   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
6807   if (tag)
6808     clib_memcpy (mp->tag, tag, vec_len (tag));
6809
6810   if (ip4_address_set)
6811     {
6812       mp->ip4_address_set = 1;
6813       clib_memcpy (mp->ip4_address, &ip4_address, sizeof (mp->ip4_address));
6814       mp->ip4_mask_width = ip4_mask_width;
6815     }
6816   if (ip6_address_set)
6817     {
6818       mp->ip6_address_set = 1;
6819       clib_memcpy (mp->ip6_address, &ip6_address, sizeof (mp->ip6_address));
6820       mp->ip6_mask_width = ip6_mask_width;
6821     }
6822
6823   vec_free (tap_name);
6824   vec_free (tag);
6825
6826   /* send it... */
6827   S (mp);
6828
6829   /* Wait for a reply... */
6830   W (ret);
6831   return ret;
6832 }
6833
6834 static int
6835 api_tap_modify (vat_main_t * vam)
6836 {
6837   unformat_input_t *i = vam->input;
6838   vl_api_tap_modify_t *mp;
6839   u8 mac_address[6];
6840   u8 random_mac = 1;
6841   u8 name_set = 0;
6842   u8 *tap_name;
6843   u32 sw_if_index = ~0;
6844   u8 sw_if_index_set = 0;
6845   int ret;
6846
6847   memset (mac_address, 0, sizeof (mac_address));
6848
6849   /* Parse args required to build the message */
6850   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6851     {
6852       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6853         sw_if_index_set = 1;
6854       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6855         sw_if_index_set = 1;
6856       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6857         {
6858           random_mac = 0;
6859         }
6860       else if (unformat (i, "random-mac"))
6861         random_mac = 1;
6862       else if (unformat (i, "tapname %s", &tap_name))
6863         name_set = 1;
6864       else
6865         break;
6866     }
6867
6868   if (sw_if_index_set == 0)
6869     {
6870       errmsg ("missing vpp interface name");
6871       return -99;
6872     }
6873   if (name_set == 0)
6874     {
6875       errmsg ("missing tap name");
6876       return -99;
6877     }
6878   if (vec_len (tap_name) > 63)
6879     {
6880       errmsg ("tap name too long");
6881     }
6882   vec_add1 (tap_name, 0);
6883
6884   /* Construct the API message */
6885   M (TAP_MODIFY, mp);
6886
6887   mp->use_random_mac = random_mac;
6888   mp->sw_if_index = ntohl (sw_if_index);
6889   clib_memcpy (mp->mac_address, mac_address, 6);
6890   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
6891   vec_free (tap_name);
6892
6893   /* send it... */
6894   S (mp);
6895
6896   /* Wait for a reply... */
6897   W (ret);
6898   return ret;
6899 }
6900
6901 static int
6902 api_tap_delete (vat_main_t * vam)
6903 {
6904   unformat_input_t *i = vam->input;
6905   vl_api_tap_delete_t *mp;
6906   u32 sw_if_index = ~0;
6907   u8 sw_if_index_set = 0;
6908   int ret;
6909
6910   /* Parse args required to build the message */
6911   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6912     {
6913       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6914         sw_if_index_set = 1;
6915       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6916         sw_if_index_set = 1;
6917       else
6918         break;
6919     }
6920
6921   if (sw_if_index_set == 0)
6922     {
6923       errmsg ("missing vpp interface name");
6924       return -99;
6925     }
6926
6927   /* Construct the API message */
6928   M (TAP_DELETE, mp);
6929
6930   mp->sw_if_index = ntohl (sw_if_index);
6931
6932   /* send it... */
6933   S (mp);
6934
6935   /* Wait for a reply... */
6936   W (ret);
6937   return ret;
6938 }
6939
6940 static int
6941 api_ip_add_del_route (vat_main_t * vam)
6942 {
6943   unformat_input_t *i = vam->input;
6944   vl_api_ip_add_del_route_t *mp;
6945   u32 sw_if_index = ~0, vrf_id = 0;
6946   u8 is_ipv6 = 0;
6947   u8 is_local = 0, is_drop = 0;
6948   u8 is_unreach = 0, is_prohibit = 0;
6949   u8 create_vrf_if_needed = 0;
6950   u8 is_add = 1;
6951   u32 next_hop_weight = 1;
6952   u8 not_last = 0;
6953   u8 is_multipath = 0;
6954   u8 address_set = 0;
6955   u8 address_length_set = 0;
6956   u32 next_hop_table_id = 0;
6957   u32 resolve_attempts = 0;
6958   u32 dst_address_length = 0;
6959   u8 next_hop_set = 0;
6960   ip4_address_t v4_dst_address, v4_next_hop_address;
6961   ip6_address_t v6_dst_address, v6_next_hop_address;
6962   int count = 1;
6963   int j;
6964   f64 before = 0;
6965   u32 random_add_del = 0;
6966   u32 *random_vector = 0;
6967   uword *random_hash;
6968   u32 random_seed = 0xdeaddabe;
6969   u32 classify_table_index = ~0;
6970   u8 is_classify = 0;
6971   u8 resolve_host = 0, resolve_attached = 0;
6972   mpls_label_t *next_hop_out_label_stack = NULL;
6973   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
6974   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
6975
6976   /* Parse args required to build the message */
6977   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6978     {
6979       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6980         ;
6981       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6982         ;
6983       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
6984         {
6985           address_set = 1;
6986           is_ipv6 = 0;
6987         }
6988       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
6989         {
6990           address_set = 1;
6991           is_ipv6 = 1;
6992         }
6993       else if (unformat (i, "/%d", &dst_address_length))
6994         {
6995           address_length_set = 1;
6996         }
6997
6998       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
6999                                          &v4_next_hop_address))
7000         {
7001           next_hop_set = 1;
7002         }
7003       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
7004                                          &v6_next_hop_address))
7005         {
7006           next_hop_set = 1;
7007         }
7008       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
7009         ;
7010       else if (unformat (i, "weight %d", &next_hop_weight))
7011         ;
7012       else if (unformat (i, "drop"))
7013         {
7014           is_drop = 1;
7015         }
7016       else if (unformat (i, "null-send-unreach"))
7017         {
7018           is_unreach = 1;
7019         }
7020       else if (unformat (i, "null-send-prohibit"))
7021         {
7022           is_prohibit = 1;
7023         }
7024       else if (unformat (i, "local"))
7025         {
7026           is_local = 1;
7027         }
7028       else if (unformat (i, "classify %d", &classify_table_index))
7029         {
7030           is_classify = 1;
7031         }
7032       else if (unformat (i, "del"))
7033         is_add = 0;
7034       else if (unformat (i, "add"))
7035         is_add = 1;
7036       else if (unformat (i, "not-last"))
7037         not_last = 1;
7038       else if (unformat (i, "resolve-via-host"))
7039         resolve_host = 1;
7040       else if (unformat (i, "resolve-via-attached"))
7041         resolve_attached = 1;
7042       else if (unformat (i, "multipath"))
7043         is_multipath = 1;
7044       else if (unformat (i, "vrf %d", &vrf_id))
7045         ;
7046       else if (unformat (i, "create-vrf"))
7047         create_vrf_if_needed = 1;
7048       else if (unformat (i, "count %d", &count))
7049         ;
7050       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
7051         ;
7052       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
7053         ;
7054       else if (unformat (i, "out-label %d", &next_hop_out_label))
7055         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
7056       else if (unformat (i, "via-label %d", &next_hop_via_label))
7057         ;
7058       else if (unformat (i, "random"))
7059         random_add_del = 1;
7060       else if (unformat (i, "seed %d", &random_seed))
7061         ;
7062       else
7063         {
7064           clib_warning ("parse error '%U'", format_unformat_error, i);
7065           return -99;
7066         }
7067     }
7068
7069   if (!next_hop_set && !is_drop && !is_local &&
7070       !is_classify && !is_unreach && !is_prohibit &&
7071       MPLS_LABEL_INVALID == next_hop_via_label)
7072     {
7073       errmsg
7074         ("next hop / local / drop / unreach / prohibit / classify not set");
7075       return -99;
7076     }
7077
7078   if (next_hop_set && MPLS_LABEL_INVALID != next_hop_via_label)
7079     {
7080       errmsg ("next hop and next-hop via label set");
7081       return -99;
7082     }
7083   if (address_set == 0)
7084     {
7085       errmsg ("missing addresses");
7086       return -99;
7087     }
7088
7089   if (address_length_set == 0)
7090     {
7091       errmsg ("missing address length");
7092       return -99;
7093     }
7094
7095   /* Generate a pile of unique, random routes */
7096   if (random_add_del)
7097     {
7098       u32 this_random_address;
7099       random_hash = hash_create (count, sizeof (uword));
7100
7101       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
7102       for (j = 0; j <= count; j++)
7103         {
7104           do
7105             {
7106               this_random_address = random_u32 (&random_seed);
7107               this_random_address =
7108                 clib_host_to_net_u32 (this_random_address);
7109             }
7110           while (hash_get (random_hash, this_random_address));
7111           vec_add1 (random_vector, this_random_address);
7112           hash_set (random_hash, this_random_address, 1);
7113         }
7114       hash_free (random_hash);
7115       v4_dst_address.as_u32 = random_vector[0];
7116     }
7117
7118   if (count > 1)
7119     {
7120       /* Turn on async mode */
7121       vam->async_mode = 1;
7122       vam->async_errors = 0;
7123       before = vat_time_now (vam);
7124     }
7125
7126   for (j = 0; j < count; j++)
7127     {
7128       /* Construct the API message */
7129       M2 (IP_ADD_DEL_ROUTE, mp,
7130           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
7131
7132       mp->next_hop_sw_if_index = ntohl (sw_if_index);
7133       mp->table_id = ntohl (vrf_id);
7134       mp->create_vrf_if_needed = create_vrf_if_needed;
7135
7136       mp->is_add = is_add;
7137       mp->is_drop = is_drop;
7138       mp->is_unreach = is_unreach;
7139       mp->is_prohibit = is_prohibit;
7140       mp->is_ipv6 = is_ipv6;
7141       mp->is_local = is_local;
7142       mp->is_classify = is_classify;
7143       mp->is_multipath = is_multipath;
7144       mp->is_resolve_host = resolve_host;
7145       mp->is_resolve_attached = resolve_attached;
7146       mp->not_last = not_last;
7147       mp->next_hop_weight = next_hop_weight;
7148       mp->dst_address_length = dst_address_length;
7149       mp->next_hop_table_id = ntohl (next_hop_table_id);
7150       mp->classify_table_index = ntohl (classify_table_index);
7151       mp->next_hop_via_label = ntohl (next_hop_via_label);
7152       mp->next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
7153       if (0 != mp->next_hop_n_out_labels)
7154         {
7155           memcpy (mp->next_hop_out_label_stack,
7156                   next_hop_out_label_stack,
7157                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
7158           vec_free (next_hop_out_label_stack);
7159         }
7160
7161       if (is_ipv6)
7162         {
7163           clib_memcpy (mp->dst_address, &v6_dst_address,
7164                        sizeof (v6_dst_address));
7165           if (next_hop_set)
7166             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
7167                          sizeof (v6_next_hop_address));
7168           increment_v6_address (&v6_dst_address);
7169         }
7170       else
7171         {
7172           clib_memcpy (mp->dst_address, &v4_dst_address,
7173                        sizeof (v4_dst_address));
7174           if (next_hop_set)
7175             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
7176                          sizeof (v4_next_hop_address));
7177           if (random_add_del)
7178             v4_dst_address.as_u32 = random_vector[j + 1];
7179           else
7180             increment_v4_address (&v4_dst_address);
7181         }
7182       /* send it... */
7183       S (mp);
7184       /* If we receive SIGTERM, stop now... */
7185       if (vam->do_exit)
7186         break;
7187     }
7188
7189   /* When testing multiple add/del ops, use a control-ping to sync */
7190   if (count > 1)
7191     {
7192       vl_api_control_ping_t *mp_ping;
7193       f64 after;
7194       f64 timeout;
7195
7196       /* Shut off async mode */
7197       vam->async_mode = 0;
7198
7199       M (CONTROL_PING, mp_ping);
7200       S (mp_ping);
7201
7202       timeout = vat_time_now (vam) + 1.0;
7203       while (vat_time_now (vam) < timeout)
7204         if (vam->result_ready == 1)
7205           goto out;
7206       vam->retval = -99;
7207
7208     out:
7209       if (vam->retval == -99)
7210         errmsg ("timeout");
7211
7212       if (vam->async_errors > 0)
7213         {
7214           errmsg ("%d asynchronous errors", vam->async_errors);
7215           vam->retval = -98;
7216         }
7217       vam->async_errors = 0;
7218       after = vat_time_now (vam);
7219
7220       /* slim chance, but we might have eaten SIGTERM on the first iteration */
7221       if (j > 0)
7222         count = j;
7223
7224       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
7225              count, after - before, count / (after - before));
7226     }
7227   else
7228     {
7229       int ret;
7230
7231       /* Wait for a reply... */
7232       W (ret);
7233       return ret;
7234     }
7235
7236   /* Return the good/bad news */
7237   return (vam->retval);
7238 }
7239
7240 static int
7241 api_ip_mroute_add_del (vat_main_t * vam)
7242 {
7243   unformat_input_t *i = vam->input;
7244   vl_api_ip_mroute_add_del_t *mp;
7245   u32 sw_if_index = ~0, vrf_id = 0;
7246   u8 is_ipv6 = 0;
7247   u8 is_local = 0;
7248   u8 create_vrf_if_needed = 0;
7249   u8 is_add = 1;
7250   u8 address_set = 0;
7251   u32 grp_address_length = 0;
7252   ip4_address_t v4_grp_address, v4_src_address;
7253   ip6_address_t v6_grp_address, v6_src_address;
7254   mfib_itf_flags_t iflags = 0;
7255   mfib_entry_flags_t eflags = 0;
7256   int ret;
7257
7258   /* Parse args required to build the message */
7259   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7260     {
7261       if (unformat (i, "sw_if_index %d", &sw_if_index))
7262         ;
7263       else if (unformat (i, "%U %U",
7264                          unformat_ip4_address, &v4_src_address,
7265                          unformat_ip4_address, &v4_grp_address))
7266         {
7267           grp_address_length = 64;
7268           address_set = 1;
7269           is_ipv6 = 0;
7270         }
7271       else if (unformat (i, "%U %U",
7272                          unformat_ip6_address, &v6_src_address,
7273                          unformat_ip6_address, &v6_grp_address))
7274         {
7275           grp_address_length = 256;
7276           address_set = 1;
7277           is_ipv6 = 1;
7278         }
7279       else if (unformat (i, "%U", unformat_ip4_address, &v4_grp_address))
7280         {
7281           memset (&v4_src_address, 0, sizeof (v4_src_address));
7282           grp_address_length = 32;
7283           address_set = 1;
7284           is_ipv6 = 0;
7285         }
7286       else if (unformat (i, "%U", unformat_ip6_address, &v6_grp_address))
7287         {
7288           memset (&v6_src_address, 0, sizeof (v6_src_address));
7289           grp_address_length = 128;
7290           address_set = 1;
7291           is_ipv6 = 1;
7292         }
7293       else if (unformat (i, "/%d", &grp_address_length))
7294         ;
7295       else if (unformat (i, "local"))
7296         {
7297           is_local = 1;
7298         }
7299       else if (unformat (i, "del"))
7300         is_add = 0;
7301       else if (unformat (i, "add"))
7302         is_add = 1;
7303       else if (unformat (i, "vrf %d", &vrf_id))
7304         ;
7305       else if (unformat (i, "create-vrf"))
7306         create_vrf_if_needed = 1;
7307       else if (unformat (i, "%U", unformat_mfib_itf_flags, &iflags))
7308         ;
7309       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
7310         ;
7311       else
7312         {
7313           clib_warning ("parse error '%U'", format_unformat_error, i);
7314           return -99;
7315         }
7316     }
7317
7318   if (address_set == 0)
7319     {
7320       errmsg ("missing addresses\n");
7321       return -99;
7322     }
7323
7324   /* Construct the API message */
7325   M (IP_MROUTE_ADD_DEL, mp);
7326
7327   mp->next_hop_sw_if_index = ntohl (sw_if_index);
7328   mp->table_id = ntohl (vrf_id);
7329   mp->create_vrf_if_needed = create_vrf_if_needed;
7330
7331   mp->is_add = is_add;
7332   mp->is_ipv6 = is_ipv6;
7333   mp->is_local = is_local;
7334   mp->itf_flags = ntohl (iflags);
7335   mp->entry_flags = ntohl (eflags);
7336   mp->grp_address_length = grp_address_length;
7337   mp->grp_address_length = ntohs (mp->grp_address_length);
7338
7339   if (is_ipv6)
7340     {
7341       clib_memcpy (mp->grp_address, &v6_grp_address, sizeof (v6_grp_address));
7342       clib_memcpy (mp->src_address, &v6_src_address, sizeof (v6_src_address));
7343     }
7344   else
7345     {
7346       clib_memcpy (mp->grp_address, &v4_grp_address, sizeof (v4_grp_address));
7347       clib_memcpy (mp->src_address, &v4_src_address, sizeof (v4_src_address));
7348
7349     }
7350
7351   /* send it... */
7352   S (mp);
7353   /* Wait for a reply... */
7354   W (ret);
7355   return ret;
7356 }
7357
7358 static int
7359 api_mpls_route_add_del (vat_main_t * vam)
7360 {
7361   unformat_input_t *i = vam->input;
7362   vl_api_mpls_route_add_del_t *mp;
7363   u32 sw_if_index = ~0, table_id = 0;
7364   u8 create_table_if_needed = 0;
7365   u8 is_add = 1;
7366   u32 next_hop_weight = 1;
7367   u8 is_multipath = 0;
7368   u32 next_hop_table_id = 0;
7369   u8 next_hop_set = 0;
7370   ip4_address_t v4_next_hop_address = {
7371     .as_u32 = 0,
7372   };
7373   ip6_address_t v6_next_hop_address = { {0} };
7374   int count = 1;
7375   int j;
7376   f64 before = 0;
7377   u32 classify_table_index = ~0;
7378   u8 is_classify = 0;
7379   u8 resolve_host = 0, resolve_attached = 0;
7380   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
7381   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
7382   mpls_label_t *next_hop_out_label_stack = NULL;
7383   mpls_label_t local_label = MPLS_LABEL_INVALID;
7384   u8 is_eos = 0;
7385   u8 next_hop_proto_is_ip4 = 1;
7386
7387   /* Parse args required to build the message */
7388   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7389     {
7390       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7391         ;
7392       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7393         ;
7394       else if (unformat (i, "%d", &local_label))
7395         ;
7396       else if (unformat (i, "eos"))
7397         is_eos = 1;
7398       else if (unformat (i, "non-eos"))
7399         is_eos = 0;
7400       else if (unformat (i, "via %U", unformat_ip4_address,
7401                          &v4_next_hop_address))
7402         {
7403           next_hop_set = 1;
7404           next_hop_proto_is_ip4 = 1;
7405         }
7406       else if (unformat (i, "via %U", unformat_ip6_address,
7407                          &v6_next_hop_address))
7408         {
7409           next_hop_set = 1;
7410           next_hop_proto_is_ip4 = 0;
7411         }
7412       else if (unformat (i, "weight %d", &next_hop_weight))
7413         ;
7414       else if (unformat (i, "create-table"))
7415         create_table_if_needed = 1;
7416       else if (unformat (i, "classify %d", &classify_table_index))
7417         {
7418           is_classify = 1;
7419         }
7420       else if (unformat (i, "del"))
7421         is_add = 0;
7422       else if (unformat (i, "add"))
7423         is_add = 1;
7424       else if (unformat (i, "resolve-via-host"))
7425         resolve_host = 1;
7426       else if (unformat (i, "resolve-via-attached"))
7427         resolve_attached = 1;
7428       else if (unformat (i, "multipath"))
7429         is_multipath = 1;
7430       else if (unformat (i, "count %d", &count))
7431         ;
7432       else if (unformat (i, "lookup-in-ip4-table %d", &next_hop_table_id))
7433         {
7434           next_hop_set = 1;
7435           next_hop_proto_is_ip4 = 1;
7436         }
7437       else if (unformat (i, "lookup-in-ip6-table %d", &next_hop_table_id))
7438         {
7439           next_hop_set = 1;
7440           next_hop_proto_is_ip4 = 0;
7441         }
7442       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
7443         ;
7444       else if (unformat (i, "via-label %d", &next_hop_via_label))
7445         ;
7446       else if (unformat (i, "out-label %d", &next_hop_out_label))
7447         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
7448       else
7449         {
7450           clib_warning ("parse error '%U'", format_unformat_error, i);
7451           return -99;
7452         }
7453     }
7454
7455   if (!next_hop_set && !is_classify)
7456     {
7457       errmsg ("next hop / classify not set");
7458       return -99;
7459     }
7460
7461   if (MPLS_LABEL_INVALID == local_label)
7462     {
7463       errmsg ("missing label");
7464       return -99;
7465     }
7466
7467   if (count > 1)
7468     {
7469       /* Turn on async mode */
7470       vam->async_mode = 1;
7471       vam->async_errors = 0;
7472       before = vat_time_now (vam);
7473     }
7474
7475   for (j = 0; j < count; j++)
7476     {
7477       /* Construct the API message */
7478       M2 (MPLS_ROUTE_ADD_DEL, mp,
7479           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
7480
7481       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
7482       mp->mr_table_id = ntohl (table_id);
7483       mp->mr_create_table_if_needed = create_table_if_needed;
7484
7485       mp->mr_is_add = is_add;
7486       mp->mr_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
7487       mp->mr_is_classify = is_classify;
7488       mp->mr_is_multipath = is_multipath;
7489       mp->mr_is_resolve_host = resolve_host;
7490       mp->mr_is_resolve_attached = resolve_attached;
7491       mp->mr_next_hop_weight = next_hop_weight;
7492       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
7493       mp->mr_classify_table_index = ntohl (classify_table_index);
7494       mp->mr_next_hop_via_label = ntohl (next_hop_via_label);
7495       mp->mr_label = ntohl (local_label);
7496       mp->mr_eos = is_eos;
7497
7498       mp->mr_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
7499       if (0 != mp->mr_next_hop_n_out_labels)
7500         {
7501           memcpy (mp->mr_next_hop_out_label_stack,
7502                   next_hop_out_label_stack,
7503                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
7504           vec_free (next_hop_out_label_stack);
7505         }
7506
7507       if (next_hop_set)
7508         {
7509           if (next_hop_proto_is_ip4)
7510             {
7511               clib_memcpy (mp->mr_next_hop,
7512                            &v4_next_hop_address,
7513                            sizeof (v4_next_hop_address));
7514             }
7515           else
7516             {
7517               clib_memcpy (mp->mr_next_hop,
7518                            &v6_next_hop_address,
7519                            sizeof (v6_next_hop_address));
7520             }
7521         }
7522       local_label++;
7523
7524       /* send it... */
7525       S (mp);
7526       /* If we receive SIGTERM, stop now... */
7527       if (vam->do_exit)
7528         break;
7529     }
7530
7531   /* When testing multiple add/del ops, use a control-ping to sync */
7532   if (count > 1)
7533     {
7534       vl_api_control_ping_t *mp_ping;
7535       f64 after;
7536       f64 timeout;
7537
7538       /* Shut off async mode */
7539       vam->async_mode = 0;
7540
7541       M (CONTROL_PING, mp_ping);
7542       S (mp_ping);
7543
7544       timeout = vat_time_now (vam) + 1.0;
7545       while (vat_time_now (vam) < timeout)
7546         if (vam->result_ready == 1)
7547           goto out;
7548       vam->retval = -99;
7549
7550     out:
7551       if (vam->retval == -99)
7552         errmsg ("timeout");
7553
7554       if (vam->async_errors > 0)
7555         {
7556           errmsg ("%d asynchronous errors", vam->async_errors);
7557           vam->retval = -98;
7558         }
7559       vam->async_errors = 0;
7560       after = vat_time_now (vam);
7561
7562       /* slim chance, but we might have eaten SIGTERM on the first iteration */
7563       if (j > 0)
7564         count = j;
7565
7566       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
7567              count, after - before, count / (after - before));
7568     }
7569   else
7570     {
7571       int ret;
7572
7573       /* Wait for a reply... */
7574       W (ret);
7575       return ret;
7576     }
7577
7578   /* Return the good/bad news */
7579   return (vam->retval);
7580 }
7581
7582 static int
7583 api_mpls_ip_bind_unbind (vat_main_t * vam)
7584 {
7585   unformat_input_t *i = vam->input;
7586   vl_api_mpls_ip_bind_unbind_t *mp;
7587   u32 ip_table_id = 0;
7588   u8 create_table_if_needed = 0;
7589   u8 is_bind = 1;
7590   u8 is_ip4 = 1;
7591   ip4_address_t v4_address;
7592   ip6_address_t v6_address;
7593   u32 address_length;
7594   u8 address_set = 0;
7595   mpls_label_t local_label = MPLS_LABEL_INVALID;
7596   int ret;
7597
7598   /* Parse args required to build the message */
7599   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7600     {
7601       if (unformat (i, "%U/%d", unformat_ip4_address,
7602                     &v4_address, &address_length))
7603         {
7604           is_ip4 = 1;
7605           address_set = 1;
7606         }
7607       else if (unformat (i, "%U/%d", unformat_ip6_address,
7608                          &v6_address, &address_length))
7609         {
7610           is_ip4 = 0;
7611           address_set = 1;
7612         }
7613       else if (unformat (i, "%d", &local_label))
7614         ;
7615       else if (unformat (i, "create-table"))
7616         create_table_if_needed = 1;
7617       else if (unformat (i, "table-id %d", &ip_table_id))
7618         ;
7619       else if (unformat (i, "unbind"))
7620         is_bind = 0;
7621       else if (unformat (i, "bind"))
7622         is_bind = 1;
7623       else
7624         {
7625           clib_warning ("parse error '%U'", format_unformat_error, i);
7626           return -99;
7627         }
7628     }
7629
7630   if (!address_set)
7631     {
7632       errmsg ("IP addres not set");
7633       return -99;
7634     }
7635
7636   if (MPLS_LABEL_INVALID == local_label)
7637     {
7638       errmsg ("missing label");
7639       return -99;
7640     }
7641
7642   /* Construct the API message */
7643   M (MPLS_IP_BIND_UNBIND, mp);
7644
7645   mp->mb_create_table_if_needed = create_table_if_needed;
7646   mp->mb_is_bind = is_bind;
7647   mp->mb_is_ip4 = is_ip4;
7648   mp->mb_ip_table_id = ntohl (ip_table_id);
7649   mp->mb_mpls_table_id = 0;
7650   mp->mb_label = ntohl (local_label);
7651   mp->mb_address_length = address_length;
7652
7653   if (is_ip4)
7654     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
7655   else
7656     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
7657
7658   /* send it... */
7659   S (mp);
7660
7661   /* Wait for a reply... */
7662   W (ret);
7663   return ret;
7664 }
7665
7666 static int
7667 api_proxy_arp_add_del (vat_main_t * vam)
7668 {
7669   unformat_input_t *i = vam->input;
7670   vl_api_proxy_arp_add_del_t *mp;
7671   u32 vrf_id = 0;
7672   u8 is_add = 1;
7673   ip4_address_t lo, hi;
7674   u8 range_set = 0;
7675   int ret;
7676
7677   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7678     {
7679       if (unformat (i, "vrf %d", &vrf_id))
7680         ;
7681       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
7682                          unformat_ip4_address, &hi))
7683         range_set = 1;
7684       else if (unformat (i, "del"))
7685         is_add = 0;
7686       else
7687         {
7688           clib_warning ("parse error '%U'", format_unformat_error, i);
7689           return -99;
7690         }
7691     }
7692
7693   if (range_set == 0)
7694     {
7695       errmsg ("address range not set");
7696       return -99;
7697     }
7698
7699   M (PROXY_ARP_ADD_DEL, mp);
7700
7701   mp->vrf_id = ntohl (vrf_id);
7702   mp->is_add = is_add;
7703   clib_memcpy (mp->low_address, &lo, sizeof (mp->low_address));
7704   clib_memcpy (mp->hi_address, &hi, sizeof (mp->hi_address));
7705
7706   S (mp);
7707   W (ret);
7708   return ret;
7709 }
7710
7711 static int
7712 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
7713 {
7714   unformat_input_t *i = vam->input;
7715   vl_api_proxy_arp_intfc_enable_disable_t *mp;
7716   u32 sw_if_index;
7717   u8 enable = 1;
7718   u8 sw_if_index_set = 0;
7719   int ret;
7720
7721   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7722     {
7723       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7724         sw_if_index_set = 1;
7725       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7726         sw_if_index_set = 1;
7727       else if (unformat (i, "enable"))
7728         enable = 1;
7729       else if (unformat (i, "disable"))
7730         enable = 0;
7731       else
7732         {
7733           clib_warning ("parse error '%U'", format_unformat_error, i);
7734           return -99;
7735         }
7736     }
7737
7738   if (sw_if_index_set == 0)
7739     {
7740       errmsg ("missing interface name or sw_if_index");
7741       return -99;
7742     }
7743
7744   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
7745
7746   mp->sw_if_index = ntohl (sw_if_index);
7747   mp->enable_disable = enable;
7748
7749   S (mp);
7750   W (ret);
7751   return ret;
7752 }
7753
7754 static int
7755 api_mpls_tunnel_add_del (vat_main_t * vam)
7756 {
7757   unformat_input_t *i = vam->input;
7758   vl_api_mpls_tunnel_add_del_t *mp;
7759
7760   u8 is_add = 1;
7761   u8 l2_only = 0;
7762   u32 sw_if_index = ~0;
7763   u32 next_hop_sw_if_index = ~0;
7764   u32 next_hop_proto_is_ip4 = 1;
7765
7766   u32 next_hop_table_id = 0;
7767   ip4_address_t v4_next_hop_address = {
7768     .as_u32 = 0,
7769   };
7770   ip6_address_t v6_next_hop_address = { {0} };
7771   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID, *labels = NULL;
7772   int ret;
7773
7774   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7775     {
7776       if (unformat (i, "add"))
7777         is_add = 1;
7778       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
7779         is_add = 0;
7780       else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
7781         ;
7782       else if (unformat (i, "via %U",
7783                          unformat_ip4_address, &v4_next_hop_address))
7784         {
7785           next_hop_proto_is_ip4 = 1;
7786         }
7787       else if (unformat (i, "via %U",
7788                          unformat_ip6_address, &v6_next_hop_address))
7789         {
7790           next_hop_proto_is_ip4 = 0;
7791         }
7792       else if (unformat (i, "l2-only"))
7793         l2_only = 1;
7794       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
7795         ;
7796       else if (unformat (i, "out-label %d", &next_hop_out_label))
7797         vec_add1 (labels, ntohl (next_hop_out_label));
7798       else
7799         {
7800           clib_warning ("parse error '%U'", format_unformat_error, i);
7801           return -99;
7802         }
7803     }
7804
7805   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (mpls_label_t) * vec_len (labels));
7806
7807   mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
7808   mp->mt_sw_if_index = ntohl (sw_if_index);
7809   mp->mt_is_add = is_add;
7810   mp->mt_l2_only = l2_only;
7811   mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
7812   mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
7813
7814   mp->mt_next_hop_n_out_labels = vec_len (labels);
7815
7816   if (0 != mp->mt_next_hop_n_out_labels)
7817     {
7818       clib_memcpy (mp->mt_next_hop_out_label_stack, labels,
7819                    sizeof (mpls_label_t) * mp->mt_next_hop_n_out_labels);
7820       vec_free (labels);
7821     }
7822
7823   if (next_hop_proto_is_ip4)
7824     {
7825       clib_memcpy (mp->mt_next_hop,
7826                    &v4_next_hop_address, sizeof (v4_next_hop_address));
7827     }
7828   else
7829     {
7830       clib_memcpy (mp->mt_next_hop,
7831                    &v6_next_hop_address, sizeof (v6_next_hop_address));
7832     }
7833
7834   S (mp);
7835   W (ret);
7836   return ret;
7837 }
7838
7839 static int
7840 api_sw_interface_set_unnumbered (vat_main_t * vam)
7841 {
7842   unformat_input_t *i = vam->input;
7843   vl_api_sw_interface_set_unnumbered_t *mp;
7844   u32 sw_if_index;
7845   u32 unnum_sw_index = ~0;
7846   u8 is_add = 1;
7847   u8 sw_if_index_set = 0;
7848   int ret;
7849
7850   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7851     {
7852       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7853         sw_if_index_set = 1;
7854       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7855         sw_if_index_set = 1;
7856       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
7857         ;
7858       else if (unformat (i, "del"))
7859         is_add = 0;
7860       else
7861         {
7862           clib_warning ("parse error '%U'", format_unformat_error, i);
7863           return -99;
7864         }
7865     }
7866
7867   if (sw_if_index_set == 0)
7868     {
7869       errmsg ("missing interface name or sw_if_index");
7870       return -99;
7871     }
7872
7873   M (SW_INTERFACE_SET_UNNUMBERED, mp);
7874
7875   mp->sw_if_index = ntohl (sw_if_index);
7876   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
7877   mp->is_add = is_add;
7878
7879   S (mp);
7880   W (ret);
7881   return ret;
7882 }
7883
7884 static int
7885 api_ip_neighbor_add_del (vat_main_t * vam)
7886 {
7887   unformat_input_t *i = vam->input;
7888   vl_api_ip_neighbor_add_del_t *mp;
7889   u32 sw_if_index;
7890   u8 sw_if_index_set = 0;
7891   u8 is_add = 1;
7892   u8 is_static = 0;
7893   u8 is_no_fib_entry = 0;
7894   u8 mac_address[6];
7895   u8 mac_set = 0;
7896   u8 v4_address_set = 0;
7897   u8 v6_address_set = 0;
7898   ip4_address_t v4address;
7899   ip6_address_t v6address;
7900   int ret;
7901
7902   memset (mac_address, 0, sizeof (mac_address));
7903
7904   /* Parse args required to build the message */
7905   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7906     {
7907       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7908         {
7909           mac_set = 1;
7910         }
7911       else if (unformat (i, "del"))
7912         is_add = 0;
7913       else
7914         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7915         sw_if_index_set = 1;
7916       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7917         sw_if_index_set = 1;
7918       else if (unformat (i, "is_static"))
7919         is_static = 1;
7920       else if (unformat (i, "no-fib-entry"))
7921         is_no_fib_entry = 1;
7922       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
7923         v4_address_set = 1;
7924       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
7925         v6_address_set = 1;
7926       else
7927         {
7928           clib_warning ("parse error '%U'", format_unformat_error, i);
7929           return -99;
7930         }
7931     }
7932
7933   if (sw_if_index_set == 0)
7934     {
7935       errmsg ("missing interface name or sw_if_index");
7936       return -99;
7937     }
7938   if (v4_address_set && v6_address_set)
7939     {
7940       errmsg ("both v4 and v6 addresses set");
7941       return -99;
7942     }
7943   if (!v4_address_set && !v6_address_set)
7944     {
7945       errmsg ("no address set");
7946       return -99;
7947     }
7948
7949   /* Construct the API message */
7950   M (IP_NEIGHBOR_ADD_DEL, mp);
7951
7952   mp->sw_if_index = ntohl (sw_if_index);
7953   mp->is_add = is_add;
7954   mp->is_static = is_static;
7955   mp->is_no_adj_fib = is_no_fib_entry;
7956   if (mac_set)
7957     clib_memcpy (mp->mac_address, mac_address, 6);
7958   if (v6_address_set)
7959     {
7960       mp->is_ipv6 = 1;
7961       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
7962     }
7963   else
7964     {
7965       /* mp->is_ipv6 = 0; via memset in M macro above */
7966       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
7967     }
7968
7969   /* send it... */
7970   S (mp);
7971
7972   /* Wait for a reply, return good/bad news  */
7973   W (ret);
7974   return ret;
7975 }
7976
7977 static int
7978 api_reset_vrf (vat_main_t * vam)
7979 {
7980   unformat_input_t *i = vam->input;
7981   vl_api_reset_vrf_t *mp;
7982   u32 vrf_id = 0;
7983   u8 is_ipv6 = 0;
7984   u8 vrf_id_set = 0;
7985   int ret;
7986
7987   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7988     {
7989       if (unformat (i, "vrf %d", &vrf_id))
7990         vrf_id_set = 1;
7991       else if (unformat (i, "ipv6"))
7992         is_ipv6 = 1;
7993       else
7994         {
7995           clib_warning ("parse error '%U'", format_unformat_error, i);
7996           return -99;
7997         }
7998     }
7999
8000   if (vrf_id_set == 0)
8001     {
8002       errmsg ("missing vrf id");
8003       return -99;
8004     }
8005
8006   M (RESET_VRF, mp);
8007
8008   mp->vrf_id = ntohl (vrf_id);
8009   mp->is_ipv6 = is_ipv6;
8010
8011   S (mp);
8012   W (ret);
8013   return ret;
8014 }
8015
8016 static int
8017 api_create_vlan_subif (vat_main_t * vam)
8018 {
8019   unformat_input_t *i = vam->input;
8020   vl_api_create_vlan_subif_t *mp;
8021   u32 sw_if_index;
8022   u8 sw_if_index_set = 0;
8023   u32 vlan_id;
8024   u8 vlan_id_set = 0;
8025   int ret;
8026
8027   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8028     {
8029       if (unformat (i, "sw_if_index %d", &sw_if_index))
8030         sw_if_index_set = 1;
8031       else
8032         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8033         sw_if_index_set = 1;
8034       else if (unformat (i, "vlan %d", &vlan_id))
8035         vlan_id_set = 1;
8036       else
8037         {
8038           clib_warning ("parse error '%U'", format_unformat_error, i);
8039           return -99;
8040         }
8041     }
8042
8043   if (sw_if_index_set == 0)
8044     {
8045       errmsg ("missing interface name or sw_if_index");
8046       return -99;
8047     }
8048
8049   if (vlan_id_set == 0)
8050     {
8051       errmsg ("missing vlan_id");
8052       return -99;
8053     }
8054   M (CREATE_VLAN_SUBIF, mp);
8055
8056   mp->sw_if_index = ntohl (sw_if_index);
8057   mp->vlan_id = ntohl (vlan_id);
8058
8059   S (mp);
8060   W (ret);
8061   return ret;
8062 }
8063
8064 #define foreach_create_subif_bit                \
8065 _(no_tags)                                      \
8066 _(one_tag)                                      \
8067 _(two_tags)                                     \
8068 _(dot1ad)                                       \
8069 _(exact_match)                                  \
8070 _(default_sub)                                  \
8071 _(outer_vlan_id_any)                            \
8072 _(inner_vlan_id_any)
8073
8074 static int
8075 api_create_subif (vat_main_t * vam)
8076 {
8077   unformat_input_t *i = vam->input;
8078   vl_api_create_subif_t *mp;
8079   u32 sw_if_index;
8080   u8 sw_if_index_set = 0;
8081   u32 sub_id;
8082   u8 sub_id_set = 0;
8083   u32 no_tags = 0;
8084   u32 one_tag = 0;
8085   u32 two_tags = 0;
8086   u32 dot1ad = 0;
8087   u32 exact_match = 0;
8088   u32 default_sub = 0;
8089   u32 outer_vlan_id_any = 0;
8090   u32 inner_vlan_id_any = 0;
8091   u32 tmp;
8092   u16 outer_vlan_id = 0;
8093   u16 inner_vlan_id = 0;
8094   int ret;
8095
8096   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8097     {
8098       if (unformat (i, "sw_if_index %d", &sw_if_index))
8099         sw_if_index_set = 1;
8100       else
8101         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8102         sw_if_index_set = 1;
8103       else if (unformat (i, "sub_id %d", &sub_id))
8104         sub_id_set = 1;
8105       else if (unformat (i, "outer_vlan_id %d", &tmp))
8106         outer_vlan_id = tmp;
8107       else if (unformat (i, "inner_vlan_id %d", &tmp))
8108         inner_vlan_id = tmp;
8109
8110 #define _(a) else if (unformat (i, #a)) a = 1 ;
8111       foreach_create_subif_bit
8112 #undef _
8113         else
8114         {
8115           clib_warning ("parse error '%U'", format_unformat_error, i);
8116           return -99;
8117         }
8118     }
8119
8120   if (sw_if_index_set == 0)
8121     {
8122       errmsg ("missing interface name or sw_if_index");
8123       return -99;
8124     }
8125
8126   if (sub_id_set == 0)
8127     {
8128       errmsg ("missing sub_id");
8129       return -99;
8130     }
8131   M (CREATE_SUBIF, mp);
8132
8133   mp->sw_if_index = ntohl (sw_if_index);
8134   mp->sub_id = ntohl (sub_id);
8135
8136 #define _(a) mp->a = a;
8137   foreach_create_subif_bit;
8138 #undef _
8139
8140   mp->outer_vlan_id = ntohs (outer_vlan_id);
8141   mp->inner_vlan_id = ntohs (inner_vlan_id);
8142
8143   S (mp);
8144   W (ret);
8145   return ret;
8146 }
8147
8148 static int
8149 api_oam_add_del (vat_main_t * vam)
8150 {
8151   unformat_input_t *i = vam->input;
8152   vl_api_oam_add_del_t *mp;
8153   u32 vrf_id = 0;
8154   u8 is_add = 1;
8155   ip4_address_t src, dst;
8156   u8 src_set = 0;
8157   u8 dst_set = 0;
8158   int ret;
8159
8160   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8161     {
8162       if (unformat (i, "vrf %d", &vrf_id))
8163         ;
8164       else if (unformat (i, "src %U", unformat_ip4_address, &src))
8165         src_set = 1;
8166       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
8167         dst_set = 1;
8168       else if (unformat (i, "del"))
8169         is_add = 0;
8170       else
8171         {
8172           clib_warning ("parse error '%U'", format_unformat_error, i);
8173           return -99;
8174         }
8175     }
8176
8177   if (src_set == 0)
8178     {
8179       errmsg ("missing src addr");
8180       return -99;
8181     }
8182
8183   if (dst_set == 0)
8184     {
8185       errmsg ("missing dst addr");
8186       return -99;
8187     }
8188
8189   M (OAM_ADD_DEL, mp);
8190
8191   mp->vrf_id = ntohl (vrf_id);
8192   mp->is_add = is_add;
8193   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
8194   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
8195
8196   S (mp);
8197   W (ret);
8198   return ret;
8199 }
8200
8201 static int
8202 api_reset_fib (vat_main_t * vam)
8203 {
8204   unformat_input_t *i = vam->input;
8205   vl_api_reset_fib_t *mp;
8206   u32 vrf_id = 0;
8207   u8 is_ipv6 = 0;
8208   u8 vrf_id_set = 0;
8209
8210   int ret;
8211   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8212     {
8213       if (unformat (i, "vrf %d", &vrf_id))
8214         vrf_id_set = 1;
8215       else if (unformat (i, "ipv6"))
8216         is_ipv6 = 1;
8217       else
8218         {
8219           clib_warning ("parse error '%U'", format_unformat_error, i);
8220           return -99;
8221         }
8222     }
8223
8224   if (vrf_id_set == 0)
8225     {
8226       errmsg ("missing vrf id");
8227       return -99;
8228     }
8229
8230   M (RESET_FIB, mp);
8231
8232   mp->vrf_id = ntohl (vrf_id);
8233   mp->is_ipv6 = is_ipv6;
8234
8235   S (mp);
8236   W (ret);
8237   return ret;
8238 }
8239
8240 static int
8241 api_dhcp_proxy_config (vat_main_t * vam)
8242 {
8243   unformat_input_t *i = vam->input;
8244   vl_api_dhcp_proxy_config_t *mp;
8245   u32 rx_vrf_id = 0;
8246   u32 server_vrf_id = 0;
8247   u8 is_add = 1;
8248   u8 v4_address_set = 0;
8249   u8 v6_address_set = 0;
8250   ip4_address_t v4address;
8251   ip6_address_t v6address;
8252   u8 v4_src_address_set = 0;
8253   u8 v6_src_address_set = 0;
8254   ip4_address_t v4srcaddress;
8255   ip6_address_t v6srcaddress;
8256   int ret;
8257
8258   /* Parse args required to build the message */
8259   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8260     {
8261       if (unformat (i, "del"))
8262         is_add = 0;
8263       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
8264         ;
8265       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
8266         ;
8267       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
8268         v4_address_set = 1;
8269       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
8270         v6_address_set = 1;
8271       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
8272         v4_src_address_set = 1;
8273       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
8274         v6_src_address_set = 1;
8275       else
8276         break;
8277     }
8278
8279   if (v4_address_set && v6_address_set)
8280     {
8281       errmsg ("both v4 and v6 server addresses set");
8282       return -99;
8283     }
8284   if (!v4_address_set && !v6_address_set)
8285     {
8286       errmsg ("no server addresses set");
8287       return -99;
8288     }
8289
8290   if (v4_src_address_set && v6_src_address_set)
8291     {
8292       errmsg ("both v4 and v6  src addresses set");
8293       return -99;
8294     }
8295   if (!v4_src_address_set && !v6_src_address_set)
8296     {
8297       errmsg ("no src addresses set");
8298       return -99;
8299     }
8300
8301   if (!(v4_src_address_set && v4_address_set) &&
8302       !(v6_src_address_set && v6_address_set))
8303     {
8304       errmsg ("no matching server and src addresses set");
8305       return -99;
8306     }
8307
8308   /* Construct the API message */
8309   M (DHCP_PROXY_CONFIG, mp);
8310
8311   mp->is_add = is_add;
8312   mp->rx_vrf_id = ntohl (rx_vrf_id);
8313   mp->server_vrf_id = ntohl (server_vrf_id);
8314   if (v6_address_set)
8315     {
8316       mp->is_ipv6 = 1;
8317       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
8318       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
8319     }
8320   else
8321     {
8322       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
8323       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
8324     }
8325
8326   /* send it... */
8327   S (mp);
8328
8329   /* Wait for a reply, return good/bad news  */
8330   W (ret);
8331   return ret;
8332 }
8333
8334 #define vl_api_dhcp_proxy_details_t_endian vl_noop_handler
8335 #define vl_api_dhcp_proxy_details_t_print vl_noop_handler
8336
8337 static void
8338 vl_api_dhcp_proxy_details_t_handler (vl_api_dhcp_proxy_details_t * mp)
8339 {
8340   vat_main_t *vam = &vat_main;
8341   u32 i, count = mp->count;
8342   vl_api_dhcp_server_t *s;
8343
8344   if (mp->is_ipv6)
8345     print (vam->ofp,
8346            "RX Table-ID %d, Source Address %U, VSS FIB-ID %d, VSS OUI %d",
8347            ntohl (mp->rx_vrf_id),
8348            format_ip6_address, mp->dhcp_src_address,
8349            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
8350   else
8351     print (vam->ofp,
8352            "RX Table-ID %d, Source Address %U, VSS FIB-ID %d, VSS OUI %d",
8353            ntohl (mp->rx_vrf_id),
8354            format_ip4_address, mp->dhcp_src_address,
8355            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
8356
8357   for (i = 0; i < count; i++)
8358     {
8359       s = &mp->servers[i];
8360
8361       if (mp->is_ipv6)
8362         print (vam->ofp,
8363                " Server Table-ID %d, Server Address %U",
8364                ntohl (s->server_vrf_id), format_ip6_address, s->dhcp_server);
8365       else
8366         print (vam->ofp,
8367                " Server Table-ID %d, Server Address %U",
8368                ntohl (s->server_vrf_id), format_ip4_address, s->dhcp_server);
8369     }
8370 }
8371
8372 static void vl_api_dhcp_proxy_details_t_handler_json
8373   (vl_api_dhcp_proxy_details_t * mp)
8374 {
8375   vat_main_t *vam = &vat_main;
8376   vat_json_node_t *node = NULL;
8377   u32 i, count = mp->count;
8378   struct in_addr ip4;
8379   struct in6_addr ip6;
8380   vl_api_dhcp_server_t *s;
8381
8382   if (VAT_JSON_ARRAY != vam->json_tree.type)
8383     {
8384       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
8385       vat_json_init_array (&vam->json_tree);
8386     }
8387   node = vat_json_array_add (&vam->json_tree);
8388
8389   vat_json_init_object (node);
8390   vat_json_object_add_uint (node, "rx-table-id", ntohl (mp->rx_vrf_id));
8391   vat_json_object_add_uint (node, "vss-fib-id", ntohl (mp->vss_fib_id));
8392   vat_json_object_add_uint (node, "vss-oui", ntohl (mp->vss_oui));
8393
8394   if (mp->is_ipv6)
8395     {
8396       clib_memcpy (&ip6, &mp->dhcp_src_address, sizeof (ip6));
8397       vat_json_object_add_ip6 (node, "src_address", ip6);
8398     }
8399   else
8400     {
8401       clib_memcpy (&ip4, &mp->dhcp_src_address, sizeof (ip4));
8402       vat_json_object_add_ip4 (node, "src_address", ip4);
8403     }
8404
8405   for (i = 0; i < count; i++)
8406     {
8407       s = &mp->servers[i];
8408
8409       vat_json_object_add_uint (node, "server-table-id",
8410                                 ntohl (s->server_vrf_id));
8411
8412       if (mp->is_ipv6)
8413         {
8414           clib_memcpy (&ip4, &s->dhcp_server, sizeof (ip4));
8415           vat_json_object_add_ip4 (node, "src_address", ip4);
8416         }
8417       else
8418         {
8419           clib_memcpy (&ip6, &s->dhcp_server, sizeof (ip6));
8420           vat_json_object_add_ip6 (node, "server_address", ip6);
8421         }
8422     }
8423 }
8424
8425 static int
8426 api_dhcp_proxy_dump (vat_main_t * vam)
8427 {
8428   unformat_input_t *i = vam->input;
8429   vl_api_control_ping_t *mp_ping;
8430   vl_api_dhcp_proxy_dump_t *mp;
8431   u8 is_ipv6 = 0;
8432   int ret;
8433
8434   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8435     {
8436       if (unformat (i, "ipv6"))
8437         is_ipv6 = 1;
8438       else
8439         {
8440           clib_warning ("parse error '%U'", format_unformat_error, i);
8441           return -99;
8442         }
8443     }
8444
8445   M (DHCP_PROXY_DUMP, mp);
8446
8447   mp->is_ip6 = is_ipv6;
8448   S (mp);
8449
8450   /* Use a control ping for synchronization */
8451   M (CONTROL_PING, mp_ping);
8452   S (mp_ping);
8453
8454   W (ret);
8455   return ret;
8456 }
8457
8458 static int
8459 api_dhcp_proxy_set_vss (vat_main_t * vam)
8460 {
8461   unformat_input_t *i = vam->input;
8462   vl_api_dhcp_proxy_set_vss_t *mp;
8463   u8 is_ipv6 = 0;
8464   u8 is_add = 1;
8465   u32 tbl_id;
8466   u8 tbl_id_set = 0;
8467   u32 oui;
8468   u8 oui_set = 0;
8469   u32 fib_id;
8470   u8 fib_id_set = 0;
8471   int ret;
8472
8473   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8474     {
8475       if (unformat (i, "tbl_id %d", &tbl_id))
8476         tbl_id_set = 1;
8477       if (unformat (i, "fib_id %d", &fib_id))
8478         fib_id_set = 1;
8479       if (unformat (i, "oui %d", &oui))
8480         oui_set = 1;
8481       else if (unformat (i, "ipv6"))
8482         is_ipv6 = 1;
8483       else if (unformat (i, "del"))
8484         is_add = 0;
8485       else
8486         {
8487           clib_warning ("parse error '%U'", format_unformat_error, i);
8488           return -99;
8489         }
8490     }
8491
8492   if (tbl_id_set == 0)
8493     {
8494       errmsg ("missing tbl id");
8495       return -99;
8496     }
8497
8498   if (fib_id_set == 0)
8499     {
8500       errmsg ("missing fib id");
8501       return -99;
8502     }
8503   if (oui_set == 0)
8504     {
8505       errmsg ("missing oui");
8506       return -99;
8507     }
8508
8509   M (DHCP_PROXY_SET_VSS, mp);
8510   mp->tbl_id = ntohl (tbl_id);
8511   mp->fib_id = ntohl (fib_id);
8512   mp->oui = ntohl (oui);
8513   mp->is_ipv6 = is_ipv6;
8514   mp->is_add = is_add;
8515
8516   S (mp);
8517   W (ret);
8518   return ret;
8519 }
8520
8521 static int
8522 api_dhcp_client_config (vat_main_t * vam)
8523 {
8524   unformat_input_t *i = vam->input;
8525   vl_api_dhcp_client_config_t *mp;
8526   u32 sw_if_index;
8527   u8 sw_if_index_set = 0;
8528   u8 is_add = 1;
8529   u8 *hostname = 0;
8530   u8 disable_event = 0;
8531   int ret;
8532
8533   /* Parse args required to build the message */
8534   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8535     {
8536       if (unformat (i, "del"))
8537         is_add = 0;
8538       else
8539         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8540         sw_if_index_set = 1;
8541       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8542         sw_if_index_set = 1;
8543       else if (unformat (i, "hostname %s", &hostname))
8544         ;
8545       else if (unformat (i, "disable_event"))
8546         disable_event = 1;
8547       else
8548         break;
8549     }
8550
8551   if (sw_if_index_set == 0)
8552     {
8553       errmsg ("missing interface name or sw_if_index");
8554       return -99;
8555     }
8556
8557   if (vec_len (hostname) > 63)
8558     {
8559       errmsg ("hostname too long");
8560     }
8561   vec_add1 (hostname, 0);
8562
8563   /* Construct the API message */
8564   M (DHCP_CLIENT_CONFIG, mp);
8565
8566   mp->sw_if_index = htonl (sw_if_index);
8567   clib_memcpy (mp->hostname, hostname, vec_len (hostname));
8568   vec_free (hostname);
8569   mp->is_add = is_add;
8570   mp->want_dhcp_event = disable_event ? 0 : 1;
8571   mp->pid = htonl (getpid ());
8572
8573   /* send it... */
8574   S (mp);
8575
8576   /* Wait for a reply, return good/bad news  */
8577   W (ret);
8578   return ret;
8579 }
8580
8581 static int
8582 api_set_ip_flow_hash (vat_main_t * vam)
8583 {
8584   unformat_input_t *i = vam->input;
8585   vl_api_set_ip_flow_hash_t *mp;
8586   u32 vrf_id = 0;
8587   u8 is_ipv6 = 0;
8588   u8 vrf_id_set = 0;
8589   u8 src = 0;
8590   u8 dst = 0;
8591   u8 sport = 0;
8592   u8 dport = 0;
8593   u8 proto = 0;
8594   u8 reverse = 0;
8595   int ret;
8596
8597   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8598     {
8599       if (unformat (i, "vrf %d", &vrf_id))
8600         vrf_id_set = 1;
8601       else if (unformat (i, "ipv6"))
8602         is_ipv6 = 1;
8603       else if (unformat (i, "src"))
8604         src = 1;
8605       else if (unformat (i, "dst"))
8606         dst = 1;
8607       else if (unformat (i, "sport"))
8608         sport = 1;
8609       else if (unformat (i, "dport"))
8610         dport = 1;
8611       else if (unformat (i, "proto"))
8612         proto = 1;
8613       else if (unformat (i, "reverse"))
8614         reverse = 1;
8615
8616       else
8617         {
8618           clib_warning ("parse error '%U'", format_unformat_error, i);
8619           return -99;
8620         }
8621     }
8622
8623   if (vrf_id_set == 0)
8624     {
8625       errmsg ("missing vrf id");
8626       return -99;
8627     }
8628
8629   M (SET_IP_FLOW_HASH, mp);
8630   mp->src = src;
8631   mp->dst = dst;
8632   mp->sport = sport;
8633   mp->dport = dport;
8634   mp->proto = proto;
8635   mp->reverse = reverse;
8636   mp->vrf_id = ntohl (vrf_id);
8637   mp->is_ipv6 = is_ipv6;
8638
8639   S (mp);
8640   W (ret);
8641   return ret;
8642 }
8643
8644 static int
8645 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
8646 {
8647   unformat_input_t *i = vam->input;
8648   vl_api_sw_interface_ip6_enable_disable_t *mp;
8649   u32 sw_if_index;
8650   u8 sw_if_index_set = 0;
8651   u8 enable = 0;
8652   int ret;
8653
8654   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8655     {
8656       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8657         sw_if_index_set = 1;
8658       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8659         sw_if_index_set = 1;
8660       else if (unformat (i, "enable"))
8661         enable = 1;
8662       else if (unformat (i, "disable"))
8663         enable = 0;
8664       else
8665         {
8666           clib_warning ("parse error '%U'", format_unformat_error, i);
8667           return -99;
8668         }
8669     }
8670
8671   if (sw_if_index_set == 0)
8672     {
8673       errmsg ("missing interface name or sw_if_index");
8674       return -99;
8675     }
8676
8677   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
8678
8679   mp->sw_if_index = ntohl (sw_if_index);
8680   mp->enable = enable;
8681
8682   S (mp);
8683   W (ret);
8684   return ret;
8685 }
8686
8687 static int
8688 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
8689 {
8690   unformat_input_t *i = vam->input;
8691   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
8692   u32 sw_if_index;
8693   u8 sw_if_index_set = 0;
8694   u8 v6_address_set = 0;
8695   ip6_address_t v6address;
8696   int ret;
8697
8698   /* Parse args required to build the message */
8699   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8700     {
8701       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8702         sw_if_index_set = 1;
8703       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8704         sw_if_index_set = 1;
8705       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
8706         v6_address_set = 1;
8707       else
8708         break;
8709     }
8710
8711   if (sw_if_index_set == 0)
8712     {
8713       errmsg ("missing interface name or sw_if_index");
8714       return -99;
8715     }
8716   if (!v6_address_set)
8717     {
8718       errmsg ("no address set");
8719       return -99;
8720     }
8721
8722   /* Construct the API message */
8723   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS, mp);
8724
8725   mp->sw_if_index = ntohl (sw_if_index);
8726   clib_memcpy (mp->address, &v6address, sizeof (v6address));
8727
8728   /* send it... */
8729   S (mp);
8730
8731   /* Wait for a reply, return good/bad news  */
8732   W (ret);
8733   return ret;
8734 }
8735
8736 static int
8737 api_ip6nd_proxy_add_del (vat_main_t * vam)
8738 {
8739   unformat_input_t *i = vam->input;
8740   vl_api_ip6nd_proxy_add_del_t *mp;
8741   u32 sw_if_index = ~0;
8742   u8 v6_address_set = 0;
8743   ip6_address_t v6address;
8744   u8 is_del = 0;
8745   int ret;
8746
8747   /* Parse args required to build the message */
8748   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8749     {
8750       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8751         ;
8752       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8753         ;
8754       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
8755         v6_address_set = 1;
8756       if (unformat (i, "del"))
8757         is_del = 1;
8758       else
8759         {
8760           clib_warning ("parse error '%U'", format_unformat_error, i);
8761           return -99;
8762         }
8763     }
8764
8765   if (sw_if_index == ~0)
8766     {
8767       errmsg ("missing interface name or sw_if_index");
8768       return -99;
8769     }
8770   if (!v6_address_set)
8771     {
8772       errmsg ("no address set");
8773       return -99;
8774     }
8775
8776   /* Construct the API message */
8777   M (IP6ND_PROXY_ADD_DEL, mp);
8778
8779   mp->is_del = is_del;
8780   mp->sw_if_index = ntohl (sw_if_index);
8781   clib_memcpy (mp->address, &v6address, sizeof (v6address));
8782
8783   /* send it... */
8784   S (mp);
8785
8786   /* Wait for a reply, return good/bad news  */
8787   W (ret);
8788   return ret;
8789 }
8790
8791 static int
8792 api_ip6nd_proxy_dump (vat_main_t * vam)
8793 {
8794   vl_api_ip6nd_proxy_dump_t *mp;
8795   vl_api_control_ping_t *mp_ping;
8796   int ret;
8797
8798   M (IP6ND_PROXY_DUMP, mp);
8799
8800   S (mp);
8801
8802   /* Use a control ping for synchronization */
8803   M (CONTROL_PING, mp_ping);
8804   S (mp_ping);
8805
8806   W (ret);
8807   return ret;
8808 }
8809
8810 static void vl_api_ip6nd_proxy_details_t_handler
8811   (vl_api_ip6nd_proxy_details_t * mp)
8812 {
8813   vat_main_t *vam = &vat_main;
8814
8815   print (vam->ofp, "host %U sw_if_index %d",
8816          format_ip6_address, mp->address, ntohl (mp->sw_if_index));
8817 }
8818
8819 static void vl_api_ip6nd_proxy_details_t_handler_json
8820   (vl_api_ip6nd_proxy_details_t * mp)
8821 {
8822   vat_main_t *vam = &vat_main;
8823   struct in6_addr ip6;
8824   vat_json_node_t *node = NULL;
8825
8826   if (VAT_JSON_ARRAY != vam->json_tree.type)
8827     {
8828       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
8829       vat_json_init_array (&vam->json_tree);
8830     }
8831   node = vat_json_array_add (&vam->json_tree);
8832
8833   vat_json_init_object (node);
8834   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
8835
8836   clib_memcpy (&ip6, mp->address, sizeof (ip6));
8837   vat_json_object_add_ip6 (node, "host", ip6);
8838 }
8839
8840 static int
8841 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
8842 {
8843   unformat_input_t *i = vam->input;
8844   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
8845   u32 sw_if_index;
8846   u8 sw_if_index_set = 0;
8847   u32 address_length = 0;
8848   u8 v6_address_set = 0;
8849   ip6_address_t v6address;
8850   u8 use_default = 0;
8851   u8 no_advertise = 0;
8852   u8 off_link = 0;
8853   u8 no_autoconfig = 0;
8854   u8 no_onlink = 0;
8855   u8 is_no = 0;
8856   u32 val_lifetime = 0;
8857   u32 pref_lifetime = 0;
8858   int ret;
8859
8860   /* Parse args required to build the message */
8861   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8862     {
8863       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8864         sw_if_index_set = 1;
8865       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8866         sw_if_index_set = 1;
8867       else if (unformat (i, "%U/%d",
8868                          unformat_ip6_address, &v6address, &address_length))
8869         v6_address_set = 1;
8870       else if (unformat (i, "val_life %d", &val_lifetime))
8871         ;
8872       else if (unformat (i, "pref_life %d", &pref_lifetime))
8873         ;
8874       else if (unformat (i, "def"))
8875         use_default = 1;
8876       else if (unformat (i, "noadv"))
8877         no_advertise = 1;
8878       else if (unformat (i, "offl"))
8879         off_link = 1;
8880       else if (unformat (i, "noauto"))
8881         no_autoconfig = 1;
8882       else if (unformat (i, "nolink"))
8883         no_onlink = 1;
8884       else if (unformat (i, "isno"))
8885         is_no = 1;
8886       else
8887         {
8888           clib_warning ("parse error '%U'", format_unformat_error, i);
8889           return -99;
8890         }
8891     }
8892
8893   if (sw_if_index_set == 0)
8894     {
8895       errmsg ("missing interface name or sw_if_index");
8896       return -99;
8897     }
8898   if (!v6_address_set)
8899     {
8900       errmsg ("no address set");
8901       return -99;
8902     }
8903
8904   /* Construct the API message */
8905   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
8906
8907   mp->sw_if_index = ntohl (sw_if_index);
8908   clib_memcpy (mp->address, &v6address, sizeof (v6address));
8909   mp->address_length = address_length;
8910   mp->use_default = use_default;
8911   mp->no_advertise = no_advertise;
8912   mp->off_link = off_link;
8913   mp->no_autoconfig = no_autoconfig;
8914   mp->no_onlink = no_onlink;
8915   mp->is_no = is_no;
8916   mp->val_lifetime = ntohl (val_lifetime);
8917   mp->pref_lifetime = ntohl (pref_lifetime);
8918
8919   /* send it... */
8920   S (mp);
8921
8922   /* Wait for a reply, return good/bad news  */
8923   W (ret);
8924   return ret;
8925 }
8926
8927 static int
8928 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
8929 {
8930   unformat_input_t *i = vam->input;
8931   vl_api_sw_interface_ip6nd_ra_config_t *mp;
8932   u32 sw_if_index;
8933   u8 sw_if_index_set = 0;
8934   u8 suppress = 0;
8935   u8 managed = 0;
8936   u8 other = 0;
8937   u8 ll_option = 0;
8938   u8 send_unicast = 0;
8939   u8 cease = 0;
8940   u8 is_no = 0;
8941   u8 default_router = 0;
8942   u32 max_interval = 0;
8943   u32 min_interval = 0;
8944   u32 lifetime = 0;
8945   u32 initial_count = 0;
8946   u32 initial_interval = 0;
8947   int ret;
8948
8949
8950   /* Parse args required to build the message */
8951   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8952     {
8953       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8954         sw_if_index_set = 1;
8955       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8956         sw_if_index_set = 1;
8957       else if (unformat (i, "maxint %d", &max_interval))
8958         ;
8959       else if (unformat (i, "minint %d", &min_interval))
8960         ;
8961       else if (unformat (i, "life %d", &lifetime))
8962         ;
8963       else if (unformat (i, "count %d", &initial_count))
8964         ;
8965       else if (unformat (i, "interval %d", &initial_interval))
8966         ;
8967       else if (unformat (i, "suppress") || unformat (i, "surpress"))
8968         suppress = 1;
8969       else if (unformat (i, "managed"))
8970         managed = 1;
8971       else if (unformat (i, "other"))
8972         other = 1;
8973       else if (unformat (i, "ll"))
8974         ll_option = 1;
8975       else if (unformat (i, "send"))
8976         send_unicast = 1;
8977       else if (unformat (i, "cease"))
8978         cease = 1;
8979       else if (unformat (i, "isno"))
8980         is_no = 1;
8981       else if (unformat (i, "def"))
8982         default_router = 1;
8983       else
8984         {
8985           clib_warning ("parse error '%U'", format_unformat_error, i);
8986           return -99;
8987         }
8988     }
8989
8990   if (sw_if_index_set == 0)
8991     {
8992       errmsg ("missing interface name or sw_if_index");
8993       return -99;
8994     }
8995
8996   /* Construct the API message */
8997   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
8998
8999   mp->sw_if_index = ntohl (sw_if_index);
9000   mp->max_interval = ntohl (max_interval);
9001   mp->min_interval = ntohl (min_interval);
9002   mp->lifetime = ntohl (lifetime);
9003   mp->initial_count = ntohl (initial_count);
9004   mp->initial_interval = ntohl (initial_interval);
9005   mp->suppress = suppress;
9006   mp->managed = managed;
9007   mp->other = other;
9008   mp->ll_option = ll_option;
9009   mp->send_unicast = send_unicast;
9010   mp->cease = cease;
9011   mp->is_no = is_no;
9012   mp->default_router = default_router;
9013
9014   /* send it... */
9015   S (mp);
9016
9017   /* Wait for a reply, return good/bad news  */
9018   W (ret);
9019   return ret;
9020 }
9021
9022 static int
9023 api_set_arp_neighbor_limit (vat_main_t * vam)
9024 {
9025   unformat_input_t *i = vam->input;
9026   vl_api_set_arp_neighbor_limit_t *mp;
9027   u32 arp_nbr_limit;
9028   u8 limit_set = 0;
9029   u8 is_ipv6 = 0;
9030   int ret;
9031
9032   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9033     {
9034       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
9035         limit_set = 1;
9036       else if (unformat (i, "ipv6"))
9037         is_ipv6 = 1;
9038       else
9039         {
9040           clib_warning ("parse error '%U'", format_unformat_error, i);
9041           return -99;
9042         }
9043     }
9044
9045   if (limit_set == 0)
9046     {
9047       errmsg ("missing limit value");
9048       return -99;
9049     }
9050
9051   M (SET_ARP_NEIGHBOR_LIMIT, mp);
9052
9053   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
9054   mp->is_ipv6 = is_ipv6;
9055
9056   S (mp);
9057   W (ret);
9058   return ret;
9059 }
9060
9061 static int
9062 api_l2_patch_add_del (vat_main_t * vam)
9063 {
9064   unformat_input_t *i = vam->input;
9065   vl_api_l2_patch_add_del_t *mp;
9066   u32 rx_sw_if_index;
9067   u8 rx_sw_if_index_set = 0;
9068   u32 tx_sw_if_index;
9069   u8 tx_sw_if_index_set = 0;
9070   u8 is_add = 1;
9071   int ret;
9072
9073   /* Parse args required to build the message */
9074   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9075     {
9076       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
9077         rx_sw_if_index_set = 1;
9078       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
9079         tx_sw_if_index_set = 1;
9080       else if (unformat (i, "rx"))
9081         {
9082           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9083             {
9084               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
9085                             &rx_sw_if_index))
9086                 rx_sw_if_index_set = 1;
9087             }
9088           else
9089             break;
9090         }
9091       else if (unformat (i, "tx"))
9092         {
9093           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9094             {
9095               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
9096                             &tx_sw_if_index))
9097                 tx_sw_if_index_set = 1;
9098             }
9099           else
9100             break;
9101         }
9102       else if (unformat (i, "del"))
9103         is_add = 0;
9104       else
9105         break;
9106     }
9107
9108   if (rx_sw_if_index_set == 0)
9109     {
9110       errmsg ("missing rx interface name or rx_sw_if_index");
9111       return -99;
9112     }
9113
9114   if (tx_sw_if_index_set == 0)
9115     {
9116       errmsg ("missing tx interface name or tx_sw_if_index");
9117       return -99;
9118     }
9119
9120   M (L2_PATCH_ADD_DEL, mp);
9121
9122   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
9123   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
9124   mp->is_add = is_add;
9125
9126   S (mp);
9127   W (ret);
9128   return ret;
9129 }
9130
9131 u8 is_del;
9132 u8 localsid_addr[16];
9133 u8 end_psp;
9134 u8 behavior;
9135 u32 sw_if_index;
9136 u32 vlan_index;
9137 u32 fib_table;
9138 u8 nh_addr[16];
9139
9140 static int
9141 api_sr_localsid_add_del (vat_main_t * vam)
9142 {
9143   unformat_input_t *i = vam->input;
9144   vl_api_sr_localsid_add_del_t *mp;
9145
9146   u8 is_del;
9147   ip6_address_t localsid;
9148   u8 end_psp = 0;
9149   u8 behavior = ~0;
9150   u32 sw_if_index;
9151   u32 fib_table = ~(u32) 0;
9152   ip6_address_t next_hop;
9153
9154   bool nexthop_set = 0;
9155
9156   int ret;
9157
9158   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9159     {
9160       if (unformat (i, "del"))
9161         is_del = 1;
9162       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
9163       else if (unformat (i, "next-hop %U", unformat_ip6_address, &next_hop))
9164         nexthop_set = 1;
9165       else if (unformat (i, "behavior %u", &behavior));
9166       else if (unformat (i, "sw_if_index %u", &sw_if_index));
9167       else if (unformat (i, "fib-table %u", &fib_table));
9168       else if (unformat (i, "end.psp %u", &behavior));
9169       else
9170         break;
9171     }
9172
9173   M (SR_LOCALSID_ADD_DEL, mp);
9174
9175   clib_memcpy (mp->localsid_addr, &localsid, sizeof (mp->localsid_addr));
9176   if (nexthop_set)
9177     clib_memcpy (mp->nh_addr, &next_hop, sizeof (mp->nh_addr));
9178   mp->behavior = behavior;
9179   mp->sw_if_index = ntohl (sw_if_index);
9180   mp->fib_table = ntohl (fib_table);
9181   mp->end_psp = end_psp;
9182   mp->is_del = is_del;
9183
9184   S (mp);
9185   W (ret);
9186   return ret;
9187 }
9188
9189 static int
9190 api_ioam_enable (vat_main_t * vam)
9191 {
9192   unformat_input_t *input = vam->input;
9193   vl_api_ioam_enable_t *mp;
9194   u32 id = 0;
9195   int has_trace_option = 0;
9196   int has_pot_option = 0;
9197   int has_seqno_option = 0;
9198   int has_analyse_option = 0;
9199   int ret;
9200
9201   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9202     {
9203       if (unformat (input, "trace"))
9204         has_trace_option = 1;
9205       else if (unformat (input, "pot"))
9206         has_pot_option = 1;
9207       else if (unformat (input, "seqno"))
9208         has_seqno_option = 1;
9209       else if (unformat (input, "analyse"))
9210         has_analyse_option = 1;
9211       else
9212         break;
9213     }
9214   M (IOAM_ENABLE, mp);
9215   mp->id = htons (id);
9216   mp->seqno = has_seqno_option;
9217   mp->analyse = has_analyse_option;
9218   mp->pot_enable = has_pot_option;
9219   mp->trace_enable = has_trace_option;
9220
9221   S (mp);
9222   W (ret);
9223   return ret;
9224 }
9225
9226
9227 static int
9228 api_ioam_disable (vat_main_t * vam)
9229 {
9230   vl_api_ioam_disable_t *mp;
9231   int ret;
9232
9233   M (IOAM_DISABLE, mp);
9234   S (mp);
9235   W (ret);
9236   return ret;
9237 }
9238
9239 #define foreach_tcp_proto_field                 \
9240 _(src_port)                                     \
9241 _(dst_port)
9242
9243 #define foreach_udp_proto_field                 \
9244 _(src_port)                                     \
9245 _(dst_port)
9246
9247 #define foreach_ip4_proto_field                 \
9248 _(src_address)                                  \
9249 _(dst_address)                                  \
9250 _(tos)                                          \
9251 _(length)                                       \
9252 _(fragment_id)                                  \
9253 _(ttl)                                          \
9254 _(protocol)                                     \
9255 _(checksum)
9256
9257 typedef struct
9258 {
9259   u16 src_port, dst_port;
9260 } tcpudp_header_t;
9261
9262 #if VPP_API_TEST_BUILTIN == 0
9263 uword
9264 unformat_tcp_mask (unformat_input_t * input, va_list * args)
9265 {
9266   u8 **maskp = va_arg (*args, u8 **);
9267   u8 *mask = 0;
9268   u8 found_something = 0;
9269   tcp_header_t *tcp;
9270
9271 #define _(a) u8 a=0;
9272   foreach_tcp_proto_field;
9273 #undef _
9274
9275   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9276     {
9277       if (0);
9278 #define _(a) else if (unformat (input, #a)) a=1;
9279       foreach_tcp_proto_field
9280 #undef _
9281         else
9282         break;
9283     }
9284
9285 #define _(a) found_something += a;
9286   foreach_tcp_proto_field;
9287 #undef _
9288
9289   if (found_something == 0)
9290     return 0;
9291
9292   vec_validate (mask, sizeof (*tcp) - 1);
9293
9294   tcp = (tcp_header_t *) mask;
9295
9296 #define _(a) if (a) memset (&tcp->a, 0xff, sizeof (tcp->a));
9297   foreach_tcp_proto_field;
9298 #undef _
9299
9300   *maskp = mask;
9301   return 1;
9302 }
9303
9304 uword
9305 unformat_udp_mask (unformat_input_t * input, va_list * args)
9306 {
9307   u8 **maskp = va_arg (*args, u8 **);
9308   u8 *mask = 0;
9309   u8 found_something = 0;
9310   udp_header_t *udp;
9311
9312 #define _(a) u8 a=0;
9313   foreach_udp_proto_field;
9314 #undef _
9315
9316   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9317     {
9318       if (0);
9319 #define _(a) else if (unformat (input, #a)) a=1;
9320       foreach_udp_proto_field
9321 #undef _
9322         else
9323         break;
9324     }
9325
9326 #define _(a) found_something += a;
9327   foreach_udp_proto_field;
9328 #undef _
9329
9330   if (found_something == 0)
9331     return 0;
9332
9333   vec_validate (mask, sizeof (*udp) - 1);
9334
9335   udp = (udp_header_t *) mask;
9336
9337 #define _(a) if (a) memset (&udp->a, 0xff, sizeof (udp->a));
9338   foreach_udp_proto_field;
9339 #undef _
9340
9341   *maskp = mask;
9342   return 1;
9343 }
9344
9345 uword
9346 unformat_l4_mask (unformat_input_t * input, va_list * args)
9347 {
9348   u8 **maskp = va_arg (*args, u8 **);
9349   u16 src_port = 0, dst_port = 0;
9350   tcpudp_header_t *tcpudp;
9351
9352   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9353     {
9354       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
9355         return 1;
9356       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
9357         return 1;
9358       else if (unformat (input, "src_port"))
9359         src_port = 0xFFFF;
9360       else if (unformat (input, "dst_port"))
9361         dst_port = 0xFFFF;
9362       else
9363         return 0;
9364     }
9365
9366   if (!src_port && !dst_port)
9367     return 0;
9368
9369   u8 *mask = 0;
9370   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
9371
9372   tcpudp = (tcpudp_header_t *) mask;
9373   tcpudp->src_port = src_port;
9374   tcpudp->dst_port = dst_port;
9375
9376   *maskp = mask;
9377
9378   return 1;
9379 }
9380
9381 uword
9382 unformat_ip4_mask (unformat_input_t * input, va_list * args)
9383 {
9384   u8 **maskp = va_arg (*args, u8 **);
9385   u8 *mask = 0;
9386   u8 found_something = 0;
9387   ip4_header_t *ip;
9388
9389 #define _(a) u8 a=0;
9390   foreach_ip4_proto_field;
9391 #undef _
9392   u8 version = 0;
9393   u8 hdr_length = 0;
9394
9395
9396   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9397     {
9398       if (unformat (input, "version"))
9399         version = 1;
9400       else if (unformat (input, "hdr_length"))
9401         hdr_length = 1;
9402       else if (unformat (input, "src"))
9403         src_address = 1;
9404       else if (unformat (input, "dst"))
9405         dst_address = 1;
9406       else if (unformat (input, "proto"))
9407         protocol = 1;
9408
9409 #define _(a) else if (unformat (input, #a)) a=1;
9410       foreach_ip4_proto_field
9411 #undef _
9412         else
9413         break;
9414     }
9415
9416 #define _(a) found_something += a;
9417   foreach_ip4_proto_field;
9418 #undef _
9419
9420   if (found_something == 0)
9421     return 0;
9422
9423   vec_validate (mask, sizeof (*ip) - 1);
9424
9425   ip = (ip4_header_t *) mask;
9426
9427 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
9428   foreach_ip4_proto_field;
9429 #undef _
9430
9431   ip->ip_version_and_header_length = 0;
9432
9433   if (version)
9434     ip->ip_version_and_header_length |= 0xF0;
9435
9436   if (hdr_length)
9437     ip->ip_version_and_header_length |= 0x0F;
9438
9439   *maskp = mask;
9440   return 1;
9441 }
9442
9443 #define foreach_ip6_proto_field                 \
9444 _(src_address)                                  \
9445 _(dst_address)                                  \
9446 _(payload_length)                               \
9447 _(hop_limit)                                    \
9448 _(protocol)
9449
9450 uword
9451 unformat_ip6_mask (unformat_input_t * input, va_list * args)
9452 {
9453   u8 **maskp = va_arg (*args, u8 **);
9454   u8 *mask = 0;
9455   u8 found_something = 0;
9456   ip6_header_t *ip;
9457   u32 ip_version_traffic_class_and_flow_label;
9458
9459 #define _(a) u8 a=0;
9460   foreach_ip6_proto_field;
9461 #undef _
9462   u8 version = 0;
9463   u8 traffic_class = 0;
9464   u8 flow_label = 0;
9465
9466   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9467     {
9468       if (unformat (input, "version"))
9469         version = 1;
9470       else if (unformat (input, "traffic-class"))
9471         traffic_class = 1;
9472       else if (unformat (input, "flow-label"))
9473         flow_label = 1;
9474       else if (unformat (input, "src"))
9475         src_address = 1;
9476       else if (unformat (input, "dst"))
9477         dst_address = 1;
9478       else if (unformat (input, "proto"))
9479         protocol = 1;
9480
9481 #define _(a) else if (unformat (input, #a)) a=1;
9482       foreach_ip6_proto_field
9483 #undef _
9484         else
9485         break;
9486     }
9487
9488 #define _(a) found_something += a;
9489   foreach_ip6_proto_field;
9490 #undef _
9491
9492   if (found_something == 0)
9493     return 0;
9494
9495   vec_validate (mask, sizeof (*ip) - 1);
9496
9497   ip = (ip6_header_t *) mask;
9498
9499 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
9500   foreach_ip6_proto_field;
9501 #undef _
9502
9503   ip_version_traffic_class_and_flow_label = 0;
9504
9505   if (version)
9506     ip_version_traffic_class_and_flow_label |= 0xF0000000;
9507
9508   if (traffic_class)
9509     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
9510
9511   if (flow_label)
9512     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
9513
9514   ip->ip_version_traffic_class_and_flow_label =
9515     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
9516
9517   *maskp = mask;
9518   return 1;
9519 }
9520
9521 uword
9522 unformat_l3_mask (unformat_input_t * input, va_list * args)
9523 {
9524   u8 **maskp = va_arg (*args, u8 **);
9525
9526   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9527     {
9528       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
9529         return 1;
9530       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
9531         return 1;
9532       else
9533         break;
9534     }
9535   return 0;
9536 }
9537
9538 uword
9539 unformat_l2_mask (unformat_input_t * input, va_list * args)
9540 {
9541   u8 **maskp = va_arg (*args, u8 **);
9542   u8 *mask = 0;
9543   u8 src = 0;
9544   u8 dst = 0;
9545   u8 proto = 0;
9546   u8 tag1 = 0;
9547   u8 tag2 = 0;
9548   u8 ignore_tag1 = 0;
9549   u8 ignore_tag2 = 0;
9550   u8 cos1 = 0;
9551   u8 cos2 = 0;
9552   u8 dot1q = 0;
9553   u8 dot1ad = 0;
9554   int len = 14;
9555
9556   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9557     {
9558       if (unformat (input, "src"))
9559         src = 1;
9560       else if (unformat (input, "dst"))
9561         dst = 1;
9562       else if (unformat (input, "proto"))
9563         proto = 1;
9564       else if (unformat (input, "tag1"))
9565         tag1 = 1;
9566       else if (unformat (input, "tag2"))
9567         tag2 = 1;
9568       else if (unformat (input, "ignore-tag1"))
9569         ignore_tag1 = 1;
9570       else if (unformat (input, "ignore-tag2"))
9571         ignore_tag2 = 1;
9572       else if (unformat (input, "cos1"))
9573         cos1 = 1;
9574       else if (unformat (input, "cos2"))
9575         cos2 = 1;
9576       else if (unformat (input, "dot1q"))
9577         dot1q = 1;
9578       else if (unformat (input, "dot1ad"))
9579         dot1ad = 1;
9580       else
9581         break;
9582     }
9583   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
9584        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
9585     return 0;
9586
9587   if (tag1 || ignore_tag1 || cos1 || dot1q)
9588     len = 18;
9589   if (tag2 || ignore_tag2 || cos2 || dot1ad)
9590     len = 22;
9591
9592   vec_validate (mask, len - 1);
9593
9594   if (dst)
9595     memset (mask, 0xff, 6);
9596
9597   if (src)
9598     memset (mask + 6, 0xff, 6);
9599
9600   if (tag2 || dot1ad)
9601     {
9602       /* inner vlan tag */
9603       if (tag2)
9604         {
9605           mask[19] = 0xff;
9606           mask[18] = 0x0f;
9607         }
9608       if (cos2)
9609         mask[18] |= 0xe0;
9610       if (proto)
9611         mask[21] = mask[20] = 0xff;
9612       if (tag1)
9613         {
9614           mask[15] = 0xff;
9615           mask[14] = 0x0f;
9616         }
9617       if (cos1)
9618         mask[14] |= 0xe0;
9619       *maskp = mask;
9620       return 1;
9621     }
9622   if (tag1 | dot1q)
9623     {
9624       if (tag1)
9625         {
9626           mask[15] = 0xff;
9627           mask[14] = 0x0f;
9628         }
9629       if (cos1)
9630         mask[14] |= 0xe0;
9631       if (proto)
9632         mask[16] = mask[17] = 0xff;
9633
9634       *maskp = mask;
9635       return 1;
9636     }
9637   if (cos2)
9638     mask[18] |= 0xe0;
9639   if (cos1)
9640     mask[14] |= 0xe0;
9641   if (proto)
9642     mask[12] = mask[13] = 0xff;
9643
9644   *maskp = mask;
9645   return 1;
9646 }
9647
9648 uword
9649 unformat_classify_mask (unformat_input_t * input, va_list * args)
9650 {
9651   u8 **maskp = va_arg (*args, u8 **);
9652   u32 *skipp = va_arg (*args, u32 *);
9653   u32 *matchp = va_arg (*args, u32 *);
9654   u32 match;
9655   u8 *mask = 0;
9656   u8 *l2 = 0;
9657   u8 *l3 = 0;
9658   u8 *l4 = 0;
9659   int i;
9660
9661   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9662     {
9663       if (unformat (input, "hex %U", unformat_hex_string, &mask))
9664         ;
9665       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
9666         ;
9667       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
9668         ;
9669       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
9670         ;
9671       else
9672         break;
9673     }
9674
9675   if (l4 && !l3)
9676     {
9677       vec_free (mask);
9678       vec_free (l2);
9679       vec_free (l4);
9680       return 0;
9681     }
9682
9683   if (mask || l2 || l3 || l4)
9684     {
9685       if (l2 || l3 || l4)
9686         {
9687           /* "With a free Ethernet header in every package" */
9688           if (l2 == 0)
9689             vec_validate (l2, 13);
9690           mask = l2;
9691           if (vec_len (l3))
9692             {
9693               vec_append (mask, l3);
9694               vec_free (l3);
9695             }
9696           if (vec_len (l4))
9697             {
9698               vec_append (mask, l4);
9699               vec_free (l4);
9700             }
9701         }
9702
9703       /* Scan forward looking for the first significant mask octet */
9704       for (i = 0; i < vec_len (mask); i++)
9705         if (mask[i])
9706           break;
9707
9708       /* compute (skip, match) params */
9709       *skipp = i / sizeof (u32x4);
9710       vec_delete (mask, *skipp * sizeof (u32x4), 0);
9711
9712       /* Pad mask to an even multiple of the vector size */
9713       while (vec_len (mask) % sizeof (u32x4))
9714         vec_add1 (mask, 0);
9715
9716       match = vec_len (mask) / sizeof (u32x4);
9717
9718       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
9719         {
9720           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
9721           if (*tmp || *(tmp + 1))
9722             break;
9723           match--;
9724         }
9725       if (match == 0)
9726         clib_warning ("BUG: match 0");
9727
9728       _vec_len (mask) = match * sizeof (u32x4);
9729
9730       *matchp = match;
9731       *maskp = mask;
9732
9733       return 1;
9734     }
9735
9736   return 0;
9737 }
9738 #endif /* VPP_API_TEST_BUILTIN */
9739
9740 #define foreach_l2_next                         \
9741 _(drop, DROP)                                   \
9742 _(ethernet, ETHERNET_INPUT)                     \
9743 _(ip4, IP4_INPUT)                               \
9744 _(ip6, IP6_INPUT)
9745
9746 uword
9747 unformat_l2_next_index (unformat_input_t * input, va_list * args)
9748 {
9749   u32 *miss_next_indexp = va_arg (*args, u32 *);
9750   u32 next_index = 0;
9751   u32 tmp;
9752
9753 #define _(n,N) \
9754   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
9755   foreach_l2_next;
9756 #undef _
9757
9758   if (unformat (input, "%d", &tmp))
9759     {
9760       next_index = tmp;
9761       goto out;
9762     }
9763
9764   return 0;
9765
9766 out:
9767   *miss_next_indexp = next_index;
9768   return 1;
9769 }
9770
9771 #define foreach_ip_next                         \
9772 _(drop, DROP)                                   \
9773 _(local, LOCAL)                                 \
9774 _(rewrite, REWRITE)
9775
9776 uword
9777 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
9778 {
9779   u32 *miss_next_indexp = va_arg (*args, u32 *);
9780   u32 next_index = 0;
9781   u32 tmp;
9782
9783 #define _(n,N) \
9784   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
9785   foreach_ip_next;
9786 #undef _
9787
9788   if (unformat (input, "%d", &tmp))
9789     {
9790       next_index = tmp;
9791       goto out;
9792     }
9793
9794   return 0;
9795
9796 out:
9797   *miss_next_indexp = next_index;
9798   return 1;
9799 }
9800
9801 #define foreach_acl_next                        \
9802 _(deny, DENY)
9803
9804 uword
9805 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
9806 {
9807   u32 *miss_next_indexp = va_arg (*args, u32 *);
9808   u32 next_index = 0;
9809   u32 tmp;
9810
9811 #define _(n,N) \
9812   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
9813   foreach_acl_next;
9814 #undef _
9815
9816   if (unformat (input, "permit"))
9817     {
9818       next_index = ~0;
9819       goto out;
9820     }
9821   else if (unformat (input, "%d", &tmp))
9822     {
9823       next_index = tmp;
9824       goto out;
9825     }
9826
9827   return 0;
9828
9829 out:
9830   *miss_next_indexp = next_index;
9831   return 1;
9832 }
9833
9834 uword
9835 unformat_policer_precolor (unformat_input_t * input, va_list * args)
9836 {
9837   u32 *r = va_arg (*args, u32 *);
9838
9839   if (unformat (input, "conform-color"))
9840     *r = POLICE_CONFORM;
9841   else if (unformat (input, "exceed-color"))
9842     *r = POLICE_EXCEED;
9843   else
9844     return 0;
9845
9846   return 1;
9847 }
9848
9849 static int
9850 api_classify_add_del_table (vat_main_t * vam)
9851 {
9852   unformat_input_t *i = vam->input;
9853   vl_api_classify_add_del_table_t *mp;
9854
9855   u32 nbuckets = 2;
9856   u32 skip = ~0;
9857   u32 match = ~0;
9858   int is_add = 1;
9859   int del_chain = 0;
9860   u32 table_index = ~0;
9861   u32 next_table_index = ~0;
9862   u32 miss_next_index = ~0;
9863   u32 memory_size = 32 << 20;
9864   u8 *mask = 0;
9865   u32 current_data_flag = 0;
9866   int current_data_offset = 0;
9867   int ret;
9868
9869   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9870     {
9871       if (unformat (i, "del"))
9872         is_add = 0;
9873       else if (unformat (i, "del-chain"))
9874         {
9875           is_add = 0;
9876           del_chain = 1;
9877         }
9878       else if (unformat (i, "buckets %d", &nbuckets))
9879         ;
9880       else if (unformat (i, "memory_size %d", &memory_size))
9881         ;
9882       else if (unformat (i, "skip %d", &skip))
9883         ;
9884       else if (unformat (i, "match %d", &match))
9885         ;
9886       else if (unformat (i, "table %d", &table_index))
9887         ;
9888       else if (unformat (i, "mask %U", unformat_classify_mask,
9889                          &mask, &skip, &match))
9890         ;
9891       else if (unformat (i, "next-table %d", &next_table_index))
9892         ;
9893       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
9894                          &miss_next_index))
9895         ;
9896       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
9897                          &miss_next_index))
9898         ;
9899       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
9900                          &miss_next_index))
9901         ;
9902       else if (unformat (i, "current-data-flag %d", &current_data_flag))
9903         ;
9904       else if (unformat (i, "current-data-offset %d", &current_data_offset))
9905         ;
9906       else
9907         break;
9908     }
9909
9910   if (is_add && mask == 0)
9911     {
9912       errmsg ("Mask required");
9913       return -99;
9914     }
9915
9916   if (is_add && skip == ~0)
9917     {
9918       errmsg ("skip count required");
9919       return -99;
9920     }
9921
9922   if (is_add && match == ~0)
9923     {
9924       errmsg ("match count required");
9925       return -99;
9926     }
9927
9928   if (!is_add && table_index == ~0)
9929     {
9930       errmsg ("table index required for delete");
9931       return -99;
9932     }
9933
9934   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
9935
9936   mp->is_add = is_add;
9937   mp->del_chain = del_chain;
9938   mp->table_index = ntohl (table_index);
9939   mp->nbuckets = ntohl (nbuckets);
9940   mp->memory_size = ntohl (memory_size);
9941   mp->skip_n_vectors = ntohl (skip);
9942   mp->match_n_vectors = ntohl (match);
9943   mp->next_table_index = ntohl (next_table_index);
9944   mp->miss_next_index = ntohl (miss_next_index);
9945   mp->current_data_flag = ntohl (current_data_flag);
9946   mp->current_data_offset = ntohl (current_data_offset);
9947   clib_memcpy (mp->mask, mask, vec_len (mask));
9948
9949   vec_free (mask);
9950
9951   S (mp);
9952   W (ret);
9953   return ret;
9954 }
9955
9956 #if VPP_API_TEST_BUILTIN == 0
9957 uword
9958 unformat_l4_match (unformat_input_t * input, va_list * args)
9959 {
9960   u8 **matchp = va_arg (*args, u8 **);
9961
9962   u8 *proto_header = 0;
9963   int src_port = 0;
9964   int dst_port = 0;
9965
9966   tcpudp_header_t h;
9967
9968   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9969     {
9970       if (unformat (input, "src_port %d", &src_port))
9971         ;
9972       else if (unformat (input, "dst_port %d", &dst_port))
9973         ;
9974       else
9975         return 0;
9976     }
9977
9978   h.src_port = clib_host_to_net_u16 (src_port);
9979   h.dst_port = clib_host_to_net_u16 (dst_port);
9980   vec_validate (proto_header, sizeof (h) - 1);
9981   memcpy (proto_header, &h, sizeof (h));
9982
9983   *matchp = proto_header;
9984
9985   return 1;
9986 }
9987
9988 uword
9989 unformat_ip4_match (unformat_input_t * input, va_list * args)
9990 {
9991   u8 **matchp = va_arg (*args, u8 **);
9992   u8 *match = 0;
9993   ip4_header_t *ip;
9994   int version = 0;
9995   u32 version_val;
9996   int hdr_length = 0;
9997   u32 hdr_length_val;
9998   int src = 0, dst = 0;
9999   ip4_address_t src_val, dst_val;
10000   int proto = 0;
10001   u32 proto_val;
10002   int tos = 0;
10003   u32 tos_val;
10004   int length = 0;
10005   u32 length_val;
10006   int fragment_id = 0;
10007   u32 fragment_id_val;
10008   int ttl = 0;
10009   int ttl_val;
10010   int checksum = 0;
10011   u32 checksum_val;
10012
10013   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10014     {
10015       if (unformat (input, "version %d", &version_val))
10016         version = 1;
10017       else if (unformat (input, "hdr_length %d", &hdr_length_val))
10018         hdr_length = 1;
10019       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
10020         src = 1;
10021       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
10022         dst = 1;
10023       else if (unformat (input, "proto %d", &proto_val))
10024         proto = 1;
10025       else if (unformat (input, "tos %d", &tos_val))
10026         tos = 1;
10027       else if (unformat (input, "length %d", &length_val))
10028         length = 1;
10029       else if (unformat (input, "fragment_id %d", &fragment_id_val))
10030         fragment_id = 1;
10031       else if (unformat (input, "ttl %d", &ttl_val))
10032         ttl = 1;
10033       else if (unformat (input, "checksum %d", &checksum_val))
10034         checksum = 1;
10035       else
10036         break;
10037     }
10038
10039   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
10040       + ttl + checksum == 0)
10041     return 0;
10042
10043   /*
10044    * Aligned because we use the real comparison functions
10045    */
10046   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
10047
10048   ip = (ip4_header_t *) match;
10049
10050   /* These are realistically matched in practice */
10051   if (src)
10052     ip->src_address.as_u32 = src_val.as_u32;
10053
10054   if (dst)
10055     ip->dst_address.as_u32 = dst_val.as_u32;
10056
10057   if (proto)
10058     ip->protocol = proto_val;
10059
10060
10061   /* These are not, but they're included for completeness */
10062   if (version)
10063     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
10064
10065   if (hdr_length)
10066     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
10067
10068   if (tos)
10069     ip->tos = tos_val;
10070
10071   if (length)
10072     ip->length = clib_host_to_net_u16 (length_val);
10073
10074   if (ttl)
10075     ip->ttl = ttl_val;
10076
10077   if (checksum)
10078     ip->checksum = clib_host_to_net_u16 (checksum_val);
10079
10080   *matchp = match;
10081   return 1;
10082 }
10083
10084 uword
10085 unformat_ip6_match (unformat_input_t * input, va_list * args)
10086 {
10087   u8 **matchp = va_arg (*args, u8 **);
10088   u8 *match = 0;
10089   ip6_header_t *ip;
10090   int version = 0;
10091   u32 version_val;
10092   u8 traffic_class = 0;
10093   u32 traffic_class_val = 0;
10094   u8 flow_label = 0;
10095   u8 flow_label_val;
10096   int src = 0, dst = 0;
10097   ip6_address_t src_val, dst_val;
10098   int proto = 0;
10099   u32 proto_val;
10100   int payload_length = 0;
10101   u32 payload_length_val;
10102   int hop_limit = 0;
10103   int hop_limit_val;
10104   u32 ip_version_traffic_class_and_flow_label;
10105
10106   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10107     {
10108       if (unformat (input, "version %d", &version_val))
10109         version = 1;
10110       else if (unformat (input, "traffic_class %d", &traffic_class_val))
10111         traffic_class = 1;
10112       else if (unformat (input, "flow_label %d", &flow_label_val))
10113         flow_label = 1;
10114       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
10115         src = 1;
10116       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
10117         dst = 1;
10118       else if (unformat (input, "proto %d", &proto_val))
10119         proto = 1;
10120       else if (unformat (input, "payload_length %d", &payload_length_val))
10121         payload_length = 1;
10122       else if (unformat (input, "hop_limit %d", &hop_limit_val))
10123         hop_limit = 1;
10124       else
10125         break;
10126     }
10127
10128   if (version + traffic_class + flow_label + src + dst + proto +
10129       payload_length + hop_limit == 0)
10130     return 0;
10131
10132   /*
10133    * Aligned because we use the real comparison functions
10134    */
10135   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
10136
10137   ip = (ip6_header_t *) match;
10138
10139   if (src)
10140     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
10141
10142   if (dst)
10143     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
10144
10145   if (proto)
10146     ip->protocol = proto_val;
10147
10148   ip_version_traffic_class_and_flow_label = 0;
10149
10150   if (version)
10151     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
10152
10153   if (traffic_class)
10154     ip_version_traffic_class_and_flow_label |=
10155       (traffic_class_val & 0xFF) << 20;
10156
10157   if (flow_label)
10158     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
10159
10160   ip->ip_version_traffic_class_and_flow_label =
10161     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
10162
10163   if (payload_length)
10164     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
10165
10166   if (hop_limit)
10167     ip->hop_limit = hop_limit_val;
10168
10169   *matchp = match;
10170   return 1;
10171 }
10172
10173 uword
10174 unformat_l3_match (unformat_input_t * input, va_list * args)
10175 {
10176   u8 **matchp = va_arg (*args, u8 **);
10177
10178   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10179     {
10180       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
10181         return 1;
10182       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
10183         return 1;
10184       else
10185         break;
10186     }
10187   return 0;
10188 }
10189
10190 uword
10191 unformat_vlan_tag (unformat_input_t * input, va_list * args)
10192 {
10193   u8 *tagp = va_arg (*args, u8 *);
10194   u32 tag;
10195
10196   if (unformat (input, "%d", &tag))
10197     {
10198       tagp[0] = (tag >> 8) & 0x0F;
10199       tagp[1] = tag & 0xFF;
10200       return 1;
10201     }
10202
10203   return 0;
10204 }
10205
10206 uword
10207 unformat_l2_match (unformat_input_t * input, va_list * args)
10208 {
10209   u8 **matchp = va_arg (*args, u8 **);
10210   u8 *match = 0;
10211   u8 src = 0;
10212   u8 src_val[6];
10213   u8 dst = 0;
10214   u8 dst_val[6];
10215   u8 proto = 0;
10216   u16 proto_val;
10217   u8 tag1 = 0;
10218   u8 tag1_val[2];
10219   u8 tag2 = 0;
10220   u8 tag2_val[2];
10221   int len = 14;
10222   u8 ignore_tag1 = 0;
10223   u8 ignore_tag2 = 0;
10224   u8 cos1 = 0;
10225   u8 cos2 = 0;
10226   u32 cos1_val = 0;
10227   u32 cos2_val = 0;
10228
10229   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10230     {
10231       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
10232         src = 1;
10233       else
10234         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
10235         dst = 1;
10236       else if (unformat (input, "proto %U",
10237                          unformat_ethernet_type_host_byte_order, &proto_val))
10238         proto = 1;
10239       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
10240         tag1 = 1;
10241       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
10242         tag2 = 1;
10243       else if (unformat (input, "ignore-tag1"))
10244         ignore_tag1 = 1;
10245       else if (unformat (input, "ignore-tag2"))
10246         ignore_tag2 = 1;
10247       else if (unformat (input, "cos1 %d", &cos1_val))
10248         cos1 = 1;
10249       else if (unformat (input, "cos2 %d", &cos2_val))
10250         cos2 = 1;
10251       else
10252         break;
10253     }
10254   if ((src + dst + proto + tag1 + tag2 +
10255        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
10256     return 0;
10257
10258   if (tag1 || ignore_tag1 || cos1)
10259     len = 18;
10260   if (tag2 || ignore_tag2 || cos2)
10261     len = 22;
10262
10263   vec_validate_aligned (match, len - 1, sizeof (u32x4));
10264
10265   if (dst)
10266     clib_memcpy (match, dst_val, 6);
10267
10268   if (src)
10269     clib_memcpy (match + 6, src_val, 6);
10270
10271   if (tag2)
10272     {
10273       /* inner vlan tag */
10274       match[19] = tag2_val[1];
10275       match[18] = tag2_val[0];
10276       if (cos2)
10277         match[18] |= (cos2_val & 0x7) << 5;
10278       if (proto)
10279         {
10280           match[21] = proto_val & 0xff;
10281           match[20] = proto_val >> 8;
10282         }
10283       if (tag1)
10284         {
10285           match[15] = tag1_val[1];
10286           match[14] = tag1_val[0];
10287         }
10288       if (cos1)
10289         match[14] |= (cos1_val & 0x7) << 5;
10290       *matchp = match;
10291       return 1;
10292     }
10293   if (tag1)
10294     {
10295       match[15] = tag1_val[1];
10296       match[14] = tag1_val[0];
10297       if (proto)
10298         {
10299           match[17] = proto_val & 0xff;
10300           match[16] = proto_val >> 8;
10301         }
10302       if (cos1)
10303         match[14] |= (cos1_val & 0x7) << 5;
10304
10305       *matchp = match;
10306       return 1;
10307     }
10308   if (cos2)
10309     match[18] |= (cos2_val & 0x7) << 5;
10310   if (cos1)
10311     match[14] |= (cos1_val & 0x7) << 5;
10312   if (proto)
10313     {
10314       match[13] = proto_val & 0xff;
10315       match[12] = proto_val >> 8;
10316     }
10317
10318   *matchp = match;
10319   return 1;
10320 }
10321 #endif
10322
10323 uword
10324 api_unformat_classify_match (unformat_input_t * input, va_list * args)
10325 {
10326   u8 **matchp = va_arg (*args, u8 **);
10327   u32 skip_n_vectors = va_arg (*args, u32);
10328   u32 match_n_vectors = va_arg (*args, u32);
10329
10330   u8 *match = 0;
10331   u8 *l2 = 0;
10332   u8 *l3 = 0;
10333   u8 *l4 = 0;
10334
10335   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10336     {
10337       if (unformat (input, "hex %U", unformat_hex_string, &match))
10338         ;
10339       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
10340         ;
10341       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
10342         ;
10343       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
10344         ;
10345       else
10346         break;
10347     }
10348
10349   if (l4 && !l3)
10350     {
10351       vec_free (match);
10352       vec_free (l2);
10353       vec_free (l4);
10354       return 0;
10355     }
10356
10357   if (match || l2 || l3 || l4)
10358     {
10359       if (l2 || l3 || l4)
10360         {
10361           /* "Win a free Ethernet header in every packet" */
10362           if (l2 == 0)
10363             vec_validate_aligned (l2, 13, sizeof (u32x4));
10364           match = l2;
10365           if (vec_len (l3))
10366             {
10367               vec_append_aligned (match, l3, sizeof (u32x4));
10368               vec_free (l3);
10369             }
10370           if (vec_len (l4))
10371             {
10372               vec_append_aligned (match, l4, sizeof (u32x4));
10373               vec_free (l4);
10374             }
10375         }
10376
10377       /* Make sure the vector is big enough even if key is all 0's */
10378       vec_validate_aligned
10379         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
10380          sizeof (u32x4));
10381
10382       /* Set size, include skipped vectors */
10383       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
10384
10385       *matchp = match;
10386
10387       return 1;
10388     }
10389
10390   return 0;
10391 }
10392
10393 static int
10394 api_classify_add_del_session (vat_main_t * vam)
10395 {
10396   unformat_input_t *i = vam->input;
10397   vl_api_classify_add_del_session_t *mp;
10398   int is_add = 1;
10399   u32 table_index = ~0;
10400   u32 hit_next_index = ~0;
10401   u32 opaque_index = ~0;
10402   u8 *match = 0;
10403   i32 advance = 0;
10404   u32 skip_n_vectors = 0;
10405   u32 match_n_vectors = 0;
10406   u32 action = 0;
10407   u32 metadata = 0;
10408   int ret;
10409
10410   /*
10411    * Warning: you have to supply skip_n and match_n
10412    * because the API client cant simply look at the classify
10413    * table object.
10414    */
10415
10416   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10417     {
10418       if (unformat (i, "del"))
10419         is_add = 0;
10420       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
10421                          &hit_next_index))
10422         ;
10423       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
10424                          &hit_next_index))
10425         ;
10426       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
10427                          &hit_next_index))
10428         ;
10429       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
10430         ;
10431       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
10432         ;
10433       else if (unformat (i, "opaque-index %d", &opaque_index))
10434         ;
10435       else if (unformat (i, "skip_n %d", &skip_n_vectors))
10436         ;
10437       else if (unformat (i, "match_n %d", &match_n_vectors))
10438         ;
10439       else if (unformat (i, "match %U", api_unformat_classify_match,
10440                          &match, skip_n_vectors, match_n_vectors))
10441         ;
10442       else if (unformat (i, "advance %d", &advance))
10443         ;
10444       else if (unformat (i, "table-index %d", &table_index))
10445         ;
10446       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
10447         action = 1;
10448       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
10449         action = 2;
10450       else if (unformat (i, "action %d", &action))
10451         ;
10452       else if (unformat (i, "metadata %d", &metadata))
10453         ;
10454       else
10455         break;
10456     }
10457
10458   if (table_index == ~0)
10459     {
10460       errmsg ("Table index required");
10461       return -99;
10462     }
10463
10464   if (is_add && match == 0)
10465     {
10466       errmsg ("Match value required");
10467       return -99;
10468     }
10469
10470   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
10471
10472   mp->is_add = is_add;
10473   mp->table_index = ntohl (table_index);
10474   mp->hit_next_index = ntohl (hit_next_index);
10475   mp->opaque_index = ntohl (opaque_index);
10476   mp->advance = ntohl (advance);
10477   mp->action = action;
10478   mp->metadata = ntohl (metadata);
10479   clib_memcpy (mp->match, match, vec_len (match));
10480   vec_free (match);
10481
10482   S (mp);
10483   W (ret);
10484   return ret;
10485 }
10486
10487 static int
10488 api_classify_set_interface_ip_table (vat_main_t * vam)
10489 {
10490   unformat_input_t *i = vam->input;
10491   vl_api_classify_set_interface_ip_table_t *mp;
10492   u32 sw_if_index;
10493   int sw_if_index_set;
10494   u32 table_index = ~0;
10495   u8 is_ipv6 = 0;
10496   int ret;
10497
10498   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10499     {
10500       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10501         sw_if_index_set = 1;
10502       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10503         sw_if_index_set = 1;
10504       else if (unformat (i, "table %d", &table_index))
10505         ;
10506       else
10507         {
10508           clib_warning ("parse error '%U'", format_unformat_error, i);
10509           return -99;
10510         }
10511     }
10512
10513   if (sw_if_index_set == 0)
10514     {
10515       errmsg ("missing interface name or sw_if_index");
10516       return -99;
10517     }
10518
10519
10520   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
10521
10522   mp->sw_if_index = ntohl (sw_if_index);
10523   mp->table_index = ntohl (table_index);
10524   mp->is_ipv6 = is_ipv6;
10525
10526   S (mp);
10527   W (ret);
10528   return ret;
10529 }
10530
10531 static int
10532 api_classify_set_interface_l2_tables (vat_main_t * vam)
10533 {
10534   unformat_input_t *i = vam->input;
10535   vl_api_classify_set_interface_l2_tables_t *mp;
10536   u32 sw_if_index;
10537   int sw_if_index_set;
10538   u32 ip4_table_index = ~0;
10539   u32 ip6_table_index = ~0;
10540   u32 other_table_index = ~0;
10541   u32 is_input = 1;
10542   int ret;
10543
10544   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10545     {
10546       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10547         sw_if_index_set = 1;
10548       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10549         sw_if_index_set = 1;
10550       else if (unformat (i, "ip4-table %d", &ip4_table_index))
10551         ;
10552       else if (unformat (i, "ip6-table %d", &ip6_table_index))
10553         ;
10554       else if (unformat (i, "other-table %d", &other_table_index))
10555         ;
10556       else if (unformat (i, "is-input %d", &is_input))
10557         ;
10558       else
10559         {
10560           clib_warning ("parse error '%U'", format_unformat_error, i);
10561           return -99;
10562         }
10563     }
10564
10565   if (sw_if_index_set == 0)
10566     {
10567       errmsg ("missing interface name or sw_if_index");
10568       return -99;
10569     }
10570
10571
10572   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
10573
10574   mp->sw_if_index = ntohl (sw_if_index);
10575   mp->ip4_table_index = ntohl (ip4_table_index);
10576   mp->ip6_table_index = ntohl (ip6_table_index);
10577   mp->other_table_index = ntohl (other_table_index);
10578   mp->is_input = (u8) is_input;
10579
10580   S (mp);
10581   W (ret);
10582   return ret;
10583 }
10584
10585 static int
10586 api_set_ipfix_exporter (vat_main_t * vam)
10587 {
10588   unformat_input_t *i = vam->input;
10589   vl_api_set_ipfix_exporter_t *mp;
10590   ip4_address_t collector_address;
10591   u8 collector_address_set = 0;
10592   u32 collector_port = ~0;
10593   ip4_address_t src_address;
10594   u8 src_address_set = 0;
10595   u32 vrf_id = ~0;
10596   u32 path_mtu = ~0;
10597   u32 template_interval = ~0;
10598   u8 udp_checksum = 0;
10599   int ret;
10600
10601   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10602     {
10603       if (unformat (i, "collector_address %U", unformat_ip4_address,
10604                     &collector_address))
10605         collector_address_set = 1;
10606       else if (unformat (i, "collector_port %d", &collector_port))
10607         ;
10608       else if (unformat (i, "src_address %U", unformat_ip4_address,
10609                          &src_address))
10610         src_address_set = 1;
10611       else if (unformat (i, "vrf_id %d", &vrf_id))
10612         ;
10613       else if (unformat (i, "path_mtu %d", &path_mtu))
10614         ;
10615       else if (unformat (i, "template_interval %d", &template_interval))
10616         ;
10617       else if (unformat (i, "udp_checksum"))
10618         udp_checksum = 1;
10619       else
10620         break;
10621     }
10622
10623   if (collector_address_set == 0)
10624     {
10625       errmsg ("collector_address required");
10626       return -99;
10627     }
10628
10629   if (src_address_set == 0)
10630     {
10631       errmsg ("src_address required");
10632       return -99;
10633     }
10634
10635   M (SET_IPFIX_EXPORTER, mp);
10636
10637   memcpy (mp->collector_address, collector_address.data,
10638           sizeof (collector_address.data));
10639   mp->collector_port = htons ((u16) collector_port);
10640   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
10641   mp->vrf_id = htonl (vrf_id);
10642   mp->path_mtu = htonl (path_mtu);
10643   mp->template_interval = htonl (template_interval);
10644   mp->udp_checksum = udp_checksum;
10645
10646   S (mp);
10647   W (ret);
10648   return ret;
10649 }
10650
10651 static int
10652 api_set_ipfix_classify_stream (vat_main_t * vam)
10653 {
10654   unformat_input_t *i = vam->input;
10655   vl_api_set_ipfix_classify_stream_t *mp;
10656   u32 domain_id = 0;
10657   u32 src_port = UDP_DST_PORT_ipfix;
10658   int ret;
10659
10660   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10661     {
10662       if (unformat (i, "domain %d", &domain_id))
10663         ;
10664       else if (unformat (i, "src_port %d", &src_port))
10665         ;
10666       else
10667         {
10668           errmsg ("unknown input `%U'", format_unformat_error, i);
10669           return -99;
10670         }
10671     }
10672
10673   M (SET_IPFIX_CLASSIFY_STREAM, mp);
10674
10675   mp->domain_id = htonl (domain_id);
10676   mp->src_port = htons ((u16) src_port);
10677
10678   S (mp);
10679   W (ret);
10680   return ret;
10681 }
10682
10683 static int
10684 api_ipfix_classify_table_add_del (vat_main_t * vam)
10685 {
10686   unformat_input_t *i = vam->input;
10687   vl_api_ipfix_classify_table_add_del_t *mp;
10688   int is_add = -1;
10689   u32 classify_table_index = ~0;
10690   u8 ip_version = 0;
10691   u8 transport_protocol = 255;
10692   int ret;
10693
10694   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10695     {
10696       if (unformat (i, "add"))
10697         is_add = 1;
10698       else if (unformat (i, "del"))
10699         is_add = 0;
10700       else if (unformat (i, "table %d", &classify_table_index))
10701         ;
10702       else if (unformat (i, "ip4"))
10703         ip_version = 4;
10704       else if (unformat (i, "ip6"))
10705         ip_version = 6;
10706       else if (unformat (i, "tcp"))
10707         transport_protocol = 6;
10708       else if (unformat (i, "udp"))
10709         transport_protocol = 17;
10710       else
10711         {
10712           errmsg ("unknown input `%U'", format_unformat_error, i);
10713           return -99;
10714         }
10715     }
10716
10717   if (is_add == -1)
10718     {
10719       errmsg ("expecting: add|del");
10720       return -99;
10721     }
10722   if (classify_table_index == ~0)
10723     {
10724       errmsg ("classifier table not specified");
10725       return -99;
10726     }
10727   if (ip_version == 0)
10728     {
10729       errmsg ("IP version not specified");
10730       return -99;
10731     }
10732
10733   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
10734
10735   mp->is_add = is_add;
10736   mp->table_id = htonl (classify_table_index);
10737   mp->ip_version = ip_version;
10738   mp->transport_protocol = transport_protocol;
10739
10740   S (mp);
10741   W (ret);
10742   return ret;
10743 }
10744
10745 static int
10746 api_get_node_index (vat_main_t * vam)
10747 {
10748   unformat_input_t *i = vam->input;
10749   vl_api_get_node_index_t *mp;
10750   u8 *name = 0;
10751   int ret;
10752
10753   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10754     {
10755       if (unformat (i, "node %s", &name))
10756         ;
10757       else
10758         break;
10759     }
10760   if (name == 0)
10761     {
10762       errmsg ("node name required");
10763       return -99;
10764     }
10765   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
10766     {
10767       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10768       return -99;
10769     }
10770
10771   M (GET_NODE_INDEX, mp);
10772   clib_memcpy (mp->node_name, name, vec_len (name));
10773   vec_free (name);
10774
10775   S (mp);
10776   W (ret);
10777   return ret;
10778 }
10779
10780 static int
10781 api_get_next_index (vat_main_t * vam)
10782 {
10783   unformat_input_t *i = vam->input;
10784   vl_api_get_next_index_t *mp;
10785   u8 *node_name = 0, *next_node_name = 0;
10786   int ret;
10787
10788   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10789     {
10790       if (unformat (i, "node-name %s", &node_name))
10791         ;
10792       else if (unformat (i, "next-node-name %s", &next_node_name))
10793         break;
10794     }
10795
10796   if (node_name == 0)
10797     {
10798       errmsg ("node name required");
10799       return -99;
10800     }
10801   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
10802     {
10803       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10804       return -99;
10805     }
10806
10807   if (next_node_name == 0)
10808     {
10809       errmsg ("next node name required");
10810       return -99;
10811     }
10812   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
10813     {
10814       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
10815       return -99;
10816     }
10817
10818   M (GET_NEXT_INDEX, mp);
10819   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
10820   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
10821   vec_free (node_name);
10822   vec_free (next_node_name);
10823
10824   S (mp);
10825   W (ret);
10826   return ret;
10827 }
10828
10829 static int
10830 api_add_node_next (vat_main_t * vam)
10831 {
10832   unformat_input_t *i = vam->input;
10833   vl_api_add_node_next_t *mp;
10834   u8 *name = 0;
10835   u8 *next = 0;
10836   int ret;
10837
10838   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10839     {
10840       if (unformat (i, "node %s", &name))
10841         ;
10842       else if (unformat (i, "next %s", &next))
10843         ;
10844       else
10845         break;
10846     }
10847   if (name == 0)
10848     {
10849       errmsg ("node name required");
10850       return -99;
10851     }
10852   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
10853     {
10854       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10855       return -99;
10856     }
10857   if (next == 0)
10858     {
10859       errmsg ("next node required");
10860       return -99;
10861     }
10862   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
10863     {
10864       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
10865       return -99;
10866     }
10867
10868   M (ADD_NODE_NEXT, mp);
10869   clib_memcpy (mp->node_name, name, vec_len (name));
10870   clib_memcpy (mp->next_name, next, vec_len (next));
10871   vec_free (name);
10872   vec_free (next);
10873
10874   S (mp);
10875   W (ret);
10876   return ret;
10877 }
10878
10879 static int
10880 api_l2tpv3_create_tunnel (vat_main_t * vam)
10881 {
10882   unformat_input_t *i = vam->input;
10883   ip6_address_t client_address, our_address;
10884   int client_address_set = 0;
10885   int our_address_set = 0;
10886   u32 local_session_id = 0;
10887   u32 remote_session_id = 0;
10888   u64 local_cookie = 0;
10889   u64 remote_cookie = 0;
10890   u8 l2_sublayer_present = 0;
10891   vl_api_l2tpv3_create_tunnel_t *mp;
10892   int ret;
10893
10894   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10895     {
10896       if (unformat (i, "client_address %U", unformat_ip6_address,
10897                     &client_address))
10898         client_address_set = 1;
10899       else if (unformat (i, "our_address %U", unformat_ip6_address,
10900                          &our_address))
10901         our_address_set = 1;
10902       else if (unformat (i, "local_session_id %d", &local_session_id))
10903         ;
10904       else if (unformat (i, "remote_session_id %d", &remote_session_id))
10905         ;
10906       else if (unformat (i, "local_cookie %lld", &local_cookie))
10907         ;
10908       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
10909         ;
10910       else if (unformat (i, "l2-sublayer-present"))
10911         l2_sublayer_present = 1;
10912       else
10913         break;
10914     }
10915
10916   if (client_address_set == 0)
10917     {
10918       errmsg ("client_address required");
10919       return -99;
10920     }
10921
10922   if (our_address_set == 0)
10923     {
10924       errmsg ("our_address required");
10925       return -99;
10926     }
10927
10928   M (L2TPV3_CREATE_TUNNEL, mp);
10929
10930   clib_memcpy (mp->client_address, client_address.as_u8,
10931                sizeof (mp->client_address));
10932
10933   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
10934
10935   mp->local_session_id = ntohl (local_session_id);
10936   mp->remote_session_id = ntohl (remote_session_id);
10937   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
10938   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
10939   mp->l2_sublayer_present = l2_sublayer_present;
10940   mp->is_ipv6 = 1;
10941
10942   S (mp);
10943   W (ret);
10944   return ret;
10945 }
10946
10947 static int
10948 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
10949 {
10950   unformat_input_t *i = vam->input;
10951   u32 sw_if_index;
10952   u8 sw_if_index_set = 0;
10953   u64 new_local_cookie = 0;
10954   u64 new_remote_cookie = 0;
10955   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
10956   int ret;
10957
10958   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10959     {
10960       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10961         sw_if_index_set = 1;
10962       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10963         sw_if_index_set = 1;
10964       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
10965         ;
10966       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
10967         ;
10968       else
10969         break;
10970     }
10971
10972   if (sw_if_index_set == 0)
10973     {
10974       errmsg ("missing interface name or sw_if_index");
10975       return -99;
10976     }
10977
10978   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
10979
10980   mp->sw_if_index = ntohl (sw_if_index);
10981   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
10982   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
10983
10984   S (mp);
10985   W (ret);
10986   return ret;
10987 }
10988
10989 static int
10990 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
10991 {
10992   unformat_input_t *i = vam->input;
10993   vl_api_l2tpv3_interface_enable_disable_t *mp;
10994   u32 sw_if_index;
10995   u8 sw_if_index_set = 0;
10996   u8 enable_disable = 1;
10997   int ret;
10998
10999   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11000     {
11001       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11002         sw_if_index_set = 1;
11003       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11004         sw_if_index_set = 1;
11005       else if (unformat (i, "enable"))
11006         enable_disable = 1;
11007       else if (unformat (i, "disable"))
11008         enable_disable = 0;
11009       else
11010         break;
11011     }
11012
11013   if (sw_if_index_set == 0)
11014     {
11015       errmsg ("missing interface name or sw_if_index");
11016       return -99;
11017     }
11018
11019   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
11020
11021   mp->sw_if_index = ntohl (sw_if_index);
11022   mp->enable_disable = enable_disable;
11023
11024   S (mp);
11025   W (ret);
11026   return ret;
11027 }
11028
11029 static int
11030 api_l2tpv3_set_lookup_key (vat_main_t * vam)
11031 {
11032   unformat_input_t *i = vam->input;
11033   vl_api_l2tpv3_set_lookup_key_t *mp;
11034   u8 key = ~0;
11035   int ret;
11036
11037   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11038     {
11039       if (unformat (i, "lookup_v6_src"))
11040         key = L2T_LOOKUP_SRC_ADDRESS;
11041       else if (unformat (i, "lookup_v6_dst"))
11042         key = L2T_LOOKUP_DST_ADDRESS;
11043       else if (unformat (i, "lookup_session_id"))
11044         key = L2T_LOOKUP_SESSION_ID;
11045       else
11046         break;
11047     }
11048
11049   if (key == (u8) ~ 0)
11050     {
11051       errmsg ("l2tp session lookup key unset");
11052       return -99;
11053     }
11054
11055   M (L2TPV3_SET_LOOKUP_KEY, mp);
11056
11057   mp->key = key;
11058
11059   S (mp);
11060   W (ret);
11061   return ret;
11062 }
11063
11064 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
11065   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
11066 {
11067   vat_main_t *vam = &vat_main;
11068
11069   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
11070          format_ip6_address, mp->our_address,
11071          format_ip6_address, mp->client_address,
11072          clib_net_to_host_u32 (mp->sw_if_index));
11073
11074   print (vam->ofp,
11075          "   local cookies %016llx %016llx remote cookie %016llx",
11076          clib_net_to_host_u64 (mp->local_cookie[0]),
11077          clib_net_to_host_u64 (mp->local_cookie[1]),
11078          clib_net_to_host_u64 (mp->remote_cookie));
11079
11080   print (vam->ofp, "   local session-id %d remote session-id %d",
11081          clib_net_to_host_u32 (mp->local_session_id),
11082          clib_net_to_host_u32 (mp->remote_session_id));
11083
11084   print (vam->ofp, "   l2 specific sublayer %s\n",
11085          mp->l2_sublayer_present ? "preset" : "absent");
11086
11087 }
11088
11089 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
11090   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
11091 {
11092   vat_main_t *vam = &vat_main;
11093   vat_json_node_t *node = NULL;
11094   struct in6_addr addr;
11095
11096   if (VAT_JSON_ARRAY != vam->json_tree.type)
11097     {
11098       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11099       vat_json_init_array (&vam->json_tree);
11100     }
11101   node = vat_json_array_add (&vam->json_tree);
11102
11103   vat_json_init_object (node);
11104
11105   clib_memcpy (&addr, mp->our_address, sizeof (addr));
11106   vat_json_object_add_ip6 (node, "our_address", addr);
11107   clib_memcpy (&addr, mp->client_address, sizeof (addr));
11108   vat_json_object_add_ip6 (node, "client_address", addr);
11109
11110   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
11111   vat_json_init_array (lc);
11112   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
11113   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
11114   vat_json_object_add_uint (node, "remote_cookie",
11115                             clib_net_to_host_u64 (mp->remote_cookie));
11116
11117   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
11118   vat_json_object_add_uint (node, "local_session_id",
11119                             clib_net_to_host_u32 (mp->local_session_id));
11120   vat_json_object_add_uint (node, "remote_session_id",
11121                             clib_net_to_host_u32 (mp->remote_session_id));
11122   vat_json_object_add_string_copy (node, "l2_sublayer",
11123                                    mp->l2_sublayer_present ? (u8 *) "present"
11124                                    : (u8 *) "absent");
11125 }
11126
11127 static int
11128 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
11129 {
11130   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
11131   vl_api_control_ping_t *mp_ping;
11132   int ret;
11133
11134   /* Get list of l2tpv3-tunnel interfaces */
11135   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
11136   S (mp);
11137
11138   /* Use a control ping for synchronization */
11139   M (CONTROL_PING, mp_ping);
11140   S (mp_ping);
11141
11142   W (ret);
11143   return ret;
11144 }
11145
11146
11147 static void vl_api_sw_interface_tap_details_t_handler
11148   (vl_api_sw_interface_tap_details_t * mp)
11149 {
11150   vat_main_t *vam = &vat_main;
11151
11152   print (vam->ofp, "%-16s %d",
11153          mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
11154 }
11155
11156 static void vl_api_sw_interface_tap_details_t_handler_json
11157   (vl_api_sw_interface_tap_details_t * mp)
11158 {
11159   vat_main_t *vam = &vat_main;
11160   vat_json_node_t *node = NULL;
11161
11162   if (VAT_JSON_ARRAY != vam->json_tree.type)
11163     {
11164       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11165       vat_json_init_array (&vam->json_tree);
11166     }
11167   node = vat_json_array_add (&vam->json_tree);
11168
11169   vat_json_init_object (node);
11170   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11171   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
11172 }
11173
11174 static int
11175 api_sw_interface_tap_dump (vat_main_t * vam)
11176 {
11177   vl_api_sw_interface_tap_dump_t *mp;
11178   vl_api_control_ping_t *mp_ping;
11179   int ret;
11180
11181   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
11182   /* Get list of tap interfaces */
11183   M (SW_INTERFACE_TAP_DUMP, mp);
11184   S (mp);
11185
11186   /* Use a control ping for synchronization */
11187   M (CONTROL_PING, mp_ping);
11188   S (mp_ping);
11189
11190   W (ret);
11191   return ret;
11192 }
11193
11194 static uword unformat_vxlan_decap_next
11195   (unformat_input_t * input, va_list * args)
11196 {
11197   u32 *result = va_arg (*args, u32 *);
11198   u32 tmp;
11199
11200   if (unformat (input, "l2"))
11201     *result = VXLAN_INPUT_NEXT_L2_INPUT;
11202   else if (unformat (input, "%d", &tmp))
11203     *result = tmp;
11204   else
11205     return 0;
11206   return 1;
11207 }
11208
11209 static int
11210 api_vxlan_add_del_tunnel (vat_main_t * vam)
11211 {
11212   unformat_input_t *line_input = vam->input;
11213   vl_api_vxlan_add_del_tunnel_t *mp;
11214   ip46_address_t src, dst;
11215   u8 is_add = 1;
11216   u8 ipv4_set = 0, ipv6_set = 0;
11217   u8 src_set = 0;
11218   u8 dst_set = 0;
11219   u8 grp_set = 0;
11220   u32 mcast_sw_if_index = ~0;
11221   u32 encap_vrf_id = 0;
11222   u32 decap_next_index = ~0;
11223   u32 vni = 0;
11224   int ret;
11225
11226   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
11227   memset (&src, 0, sizeof src);
11228   memset (&dst, 0, sizeof dst);
11229
11230   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11231     {
11232       if (unformat (line_input, "del"))
11233         is_add = 0;
11234       else
11235         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
11236         {
11237           ipv4_set = 1;
11238           src_set = 1;
11239         }
11240       else
11241         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
11242         {
11243           ipv4_set = 1;
11244           dst_set = 1;
11245         }
11246       else
11247         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
11248         {
11249           ipv6_set = 1;
11250           src_set = 1;
11251         }
11252       else
11253         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
11254         {
11255           ipv6_set = 1;
11256           dst_set = 1;
11257         }
11258       else if (unformat (line_input, "group %U %U",
11259                          unformat_ip4_address, &dst.ip4,
11260                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11261         {
11262           grp_set = dst_set = 1;
11263           ipv4_set = 1;
11264         }
11265       else if (unformat (line_input, "group %U",
11266                          unformat_ip4_address, &dst.ip4))
11267         {
11268           grp_set = dst_set = 1;
11269           ipv4_set = 1;
11270         }
11271       else if (unformat (line_input, "group %U %U",
11272                          unformat_ip6_address, &dst.ip6,
11273                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11274         {
11275           grp_set = dst_set = 1;
11276           ipv6_set = 1;
11277         }
11278       else if (unformat (line_input, "group %U",
11279                          unformat_ip6_address, &dst.ip6))
11280         {
11281           grp_set = dst_set = 1;
11282           ipv6_set = 1;
11283         }
11284       else
11285         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
11286         ;
11287       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
11288         ;
11289       else if (unformat (line_input, "decap-next %U",
11290                          unformat_vxlan_decap_next, &decap_next_index))
11291         ;
11292       else if (unformat (line_input, "vni %d", &vni))
11293         ;
11294       else
11295         {
11296           errmsg ("parse error '%U'", format_unformat_error, line_input);
11297           return -99;
11298         }
11299     }
11300
11301   if (src_set == 0)
11302     {
11303       errmsg ("tunnel src address not specified");
11304       return -99;
11305     }
11306   if (dst_set == 0)
11307     {
11308       errmsg ("tunnel dst address not specified");
11309       return -99;
11310     }
11311
11312   if (grp_set && !ip46_address_is_multicast (&dst))
11313     {
11314       errmsg ("tunnel group address not multicast");
11315       return -99;
11316     }
11317   if (grp_set && mcast_sw_if_index == ~0)
11318     {
11319       errmsg ("tunnel nonexistent multicast device");
11320       return -99;
11321     }
11322   if (grp_set == 0 && ip46_address_is_multicast (&dst))
11323     {
11324       errmsg ("tunnel dst address must be unicast");
11325       return -99;
11326     }
11327
11328
11329   if (ipv4_set && ipv6_set)
11330     {
11331       errmsg ("both IPv4 and IPv6 addresses specified");
11332       return -99;
11333     }
11334
11335   if ((vni == 0) || (vni >> 24))
11336     {
11337       errmsg ("vni not specified or out of range");
11338       return -99;
11339     }
11340
11341   M (VXLAN_ADD_DEL_TUNNEL, mp);
11342
11343   if (ipv6_set)
11344     {
11345       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
11346       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
11347     }
11348   else
11349     {
11350       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
11351       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
11352     }
11353   mp->encap_vrf_id = ntohl (encap_vrf_id);
11354   mp->decap_next_index = ntohl (decap_next_index);
11355   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
11356   mp->vni = ntohl (vni);
11357   mp->is_add = is_add;
11358   mp->is_ipv6 = ipv6_set;
11359
11360   S (mp);
11361   W (ret);
11362   return ret;
11363 }
11364
11365 static void vl_api_vxlan_tunnel_details_t_handler
11366   (vl_api_vxlan_tunnel_details_t * mp)
11367 {
11368   vat_main_t *vam = &vat_main;
11369   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
11370   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
11371
11372   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
11373          ntohl (mp->sw_if_index),
11374          format_ip46_address, &src, IP46_TYPE_ANY,
11375          format_ip46_address, &dst, IP46_TYPE_ANY,
11376          ntohl (mp->encap_vrf_id),
11377          ntohl (mp->decap_next_index), ntohl (mp->vni),
11378          ntohl (mp->mcast_sw_if_index));
11379 }
11380
11381 static void vl_api_vxlan_tunnel_details_t_handler_json
11382   (vl_api_vxlan_tunnel_details_t * mp)
11383 {
11384   vat_main_t *vam = &vat_main;
11385   vat_json_node_t *node = NULL;
11386
11387   if (VAT_JSON_ARRAY != vam->json_tree.type)
11388     {
11389       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11390       vat_json_init_array (&vam->json_tree);
11391     }
11392   node = vat_json_array_add (&vam->json_tree);
11393
11394   vat_json_init_object (node);
11395   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11396   if (mp->is_ipv6)
11397     {
11398       struct in6_addr ip6;
11399
11400       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
11401       vat_json_object_add_ip6 (node, "src_address", ip6);
11402       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
11403       vat_json_object_add_ip6 (node, "dst_address", ip6);
11404     }
11405   else
11406     {
11407       struct in_addr ip4;
11408
11409       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
11410       vat_json_object_add_ip4 (node, "src_address", ip4);
11411       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
11412       vat_json_object_add_ip4 (node, "dst_address", ip4);
11413     }
11414   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
11415   vat_json_object_add_uint (node, "decap_next_index",
11416                             ntohl (mp->decap_next_index));
11417   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
11418   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
11419   vat_json_object_add_uint (node, "mcast_sw_if_index",
11420                             ntohl (mp->mcast_sw_if_index));
11421 }
11422
11423 static int
11424 api_vxlan_tunnel_dump (vat_main_t * vam)
11425 {
11426   unformat_input_t *i = vam->input;
11427   vl_api_vxlan_tunnel_dump_t *mp;
11428   vl_api_control_ping_t *mp_ping;
11429   u32 sw_if_index;
11430   u8 sw_if_index_set = 0;
11431   int ret;
11432
11433   /* Parse args required to build the message */
11434   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11435     {
11436       if (unformat (i, "sw_if_index %d", &sw_if_index))
11437         sw_if_index_set = 1;
11438       else
11439         break;
11440     }
11441
11442   if (sw_if_index_set == 0)
11443     {
11444       sw_if_index = ~0;
11445     }
11446
11447   if (!vam->json_output)
11448     {
11449       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
11450              "sw_if_index", "src_address", "dst_address",
11451              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
11452     }
11453
11454   /* Get list of vxlan-tunnel interfaces */
11455   M (VXLAN_TUNNEL_DUMP, mp);
11456
11457   mp->sw_if_index = htonl (sw_if_index);
11458
11459   S (mp);
11460
11461   /* Use a control ping for synchronization */
11462   M (CONTROL_PING, mp_ping);
11463   S (mp_ping);
11464
11465   W (ret);
11466   return ret;
11467 }
11468
11469 static int
11470 api_gre_add_del_tunnel (vat_main_t * vam)
11471 {
11472   unformat_input_t *line_input = vam->input;
11473   vl_api_gre_add_del_tunnel_t *mp;
11474   ip4_address_t src4, dst4;
11475   ip6_address_t src6, dst6;
11476   u8 is_add = 1;
11477   u8 ipv4_set = 0;
11478   u8 ipv6_set = 0;
11479   u8 teb = 0;
11480   u8 src_set = 0;
11481   u8 dst_set = 0;
11482   u32 outer_fib_id = 0;
11483   int ret;
11484
11485   memset (&src4, 0, sizeof src4);
11486   memset (&dst4, 0, sizeof dst4);
11487   memset (&src6, 0, sizeof src6);
11488   memset (&dst6, 0, sizeof dst6);
11489
11490   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11491     {
11492       if (unformat (line_input, "del"))
11493         is_add = 0;
11494       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
11495         {
11496           src_set = 1;
11497           ipv4_set = 1;
11498         }
11499       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
11500         {
11501           dst_set = 1;
11502           ipv4_set = 1;
11503         }
11504       else if (unformat (line_input, "src %U", unformat_ip6_address, &src6))
11505         {
11506           src_set = 1;
11507           ipv6_set = 1;
11508         }
11509       else if (unformat (line_input, "dst %U", unformat_ip6_address, &dst6))
11510         {
11511           dst_set = 1;
11512           ipv6_set = 1;
11513         }
11514       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
11515         ;
11516       else if (unformat (line_input, "teb"))
11517         teb = 1;
11518       else
11519         {
11520           errmsg ("parse error '%U'", format_unformat_error, line_input);
11521           return -99;
11522         }
11523     }
11524
11525   if (src_set == 0)
11526     {
11527       errmsg ("tunnel src address not specified");
11528       return -99;
11529     }
11530   if (dst_set == 0)
11531     {
11532       errmsg ("tunnel dst address not specified");
11533       return -99;
11534     }
11535   if (ipv4_set && ipv6_set)
11536     {
11537       errmsg ("both IPv4 and IPv6 addresses specified");
11538       return -99;
11539     }
11540
11541
11542   M (GRE_ADD_DEL_TUNNEL, mp);
11543
11544   if (ipv4_set)
11545     {
11546       clib_memcpy (&mp->src_address, &src4, 4);
11547       clib_memcpy (&mp->dst_address, &dst4, 4);
11548     }
11549   else
11550     {
11551       clib_memcpy (&mp->src_address, &src6, 16);
11552       clib_memcpy (&mp->dst_address, &dst6, 16);
11553     }
11554   mp->outer_fib_id = ntohl (outer_fib_id);
11555   mp->is_add = is_add;
11556   mp->teb = teb;
11557   mp->is_ipv6 = ipv6_set;
11558
11559   S (mp);
11560   W (ret);
11561   return ret;
11562 }
11563
11564 static void vl_api_gre_tunnel_details_t_handler
11565   (vl_api_gre_tunnel_details_t * mp)
11566 {
11567   vat_main_t *vam = &vat_main;
11568   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->src_address);
11569   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->dst_address);
11570
11571   print (vam->ofp, "%11d%24U%24U%6d%14d",
11572          ntohl (mp->sw_if_index),
11573          format_ip46_address, &src, IP46_TYPE_ANY,
11574          format_ip46_address, &dst, IP46_TYPE_ANY,
11575          mp->teb, ntohl (mp->outer_fib_id));
11576 }
11577
11578 static void vl_api_gre_tunnel_details_t_handler_json
11579   (vl_api_gre_tunnel_details_t * mp)
11580 {
11581   vat_main_t *vam = &vat_main;
11582   vat_json_node_t *node = NULL;
11583   struct in_addr ip4;
11584   struct in6_addr ip6;
11585
11586   if (VAT_JSON_ARRAY != vam->json_tree.type)
11587     {
11588       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11589       vat_json_init_array (&vam->json_tree);
11590     }
11591   node = vat_json_array_add (&vam->json_tree);
11592
11593   vat_json_init_object (node);
11594   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11595   if (!mp->is_ipv6)
11596     {
11597       clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
11598       vat_json_object_add_ip4 (node, "src_address", ip4);
11599       clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
11600       vat_json_object_add_ip4 (node, "dst_address", ip4);
11601     }
11602   else
11603     {
11604       clib_memcpy (&ip6, &mp->src_address, sizeof (ip6));
11605       vat_json_object_add_ip6 (node, "src_address", ip6);
11606       clib_memcpy (&ip6, &mp->dst_address, sizeof (ip6));
11607       vat_json_object_add_ip6 (node, "dst_address", ip6);
11608     }
11609   vat_json_object_add_uint (node, "teb", mp->teb);
11610   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
11611   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6);
11612 }
11613
11614 static int
11615 api_gre_tunnel_dump (vat_main_t * vam)
11616 {
11617   unformat_input_t *i = vam->input;
11618   vl_api_gre_tunnel_dump_t *mp;
11619   vl_api_control_ping_t *mp_ping;
11620   u32 sw_if_index;
11621   u8 sw_if_index_set = 0;
11622   int ret;
11623
11624   /* Parse args required to build the message */
11625   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11626     {
11627       if (unformat (i, "sw_if_index %d", &sw_if_index))
11628         sw_if_index_set = 1;
11629       else
11630         break;
11631     }
11632
11633   if (sw_if_index_set == 0)
11634     {
11635       sw_if_index = ~0;
11636     }
11637
11638   if (!vam->json_output)
11639     {
11640       print (vam->ofp, "%11s%24s%24s%6s%14s",
11641              "sw_if_index", "src_address", "dst_address", "teb",
11642              "outer_fib_id");
11643     }
11644
11645   /* Get list of gre-tunnel interfaces */
11646   M (GRE_TUNNEL_DUMP, mp);
11647
11648   mp->sw_if_index = htonl (sw_if_index);
11649
11650   S (mp);
11651
11652   /* Use a control ping for synchronization */
11653   M (CONTROL_PING, mp_ping);
11654   S (mp_ping);
11655
11656   W (ret);
11657   return ret;
11658 }
11659
11660 static int
11661 api_l2_fib_clear_table (vat_main_t * vam)
11662 {
11663 //  unformat_input_t * i = vam->input;
11664   vl_api_l2_fib_clear_table_t *mp;
11665   int ret;
11666
11667   M (L2_FIB_CLEAR_TABLE, mp);
11668
11669   S (mp);
11670   W (ret);
11671   return ret;
11672 }
11673
11674 static int
11675 api_l2_interface_efp_filter (vat_main_t * vam)
11676 {
11677   unformat_input_t *i = vam->input;
11678   vl_api_l2_interface_efp_filter_t *mp;
11679   u32 sw_if_index;
11680   u8 enable = 1;
11681   u8 sw_if_index_set = 0;
11682   int ret;
11683
11684   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11685     {
11686       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11687         sw_if_index_set = 1;
11688       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11689         sw_if_index_set = 1;
11690       else if (unformat (i, "enable"))
11691         enable = 1;
11692       else if (unformat (i, "disable"))
11693         enable = 0;
11694       else
11695         {
11696           clib_warning ("parse error '%U'", format_unformat_error, i);
11697           return -99;
11698         }
11699     }
11700
11701   if (sw_if_index_set == 0)
11702     {
11703       errmsg ("missing sw_if_index");
11704       return -99;
11705     }
11706
11707   M (L2_INTERFACE_EFP_FILTER, mp);
11708
11709   mp->sw_if_index = ntohl (sw_if_index);
11710   mp->enable_disable = enable;
11711
11712   S (mp);
11713   W (ret);
11714   return ret;
11715 }
11716
11717 #define foreach_vtr_op                          \
11718 _("disable",  L2_VTR_DISABLED)                  \
11719 _("push-1",  L2_VTR_PUSH_1)                     \
11720 _("push-2",  L2_VTR_PUSH_2)                     \
11721 _("pop-1",  L2_VTR_POP_1)                       \
11722 _("pop-2",  L2_VTR_POP_2)                       \
11723 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
11724 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
11725 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
11726 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
11727
11728 static int
11729 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
11730 {
11731   unformat_input_t *i = vam->input;
11732   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
11733   u32 sw_if_index;
11734   u8 sw_if_index_set = 0;
11735   u8 vtr_op_set = 0;
11736   u32 vtr_op = 0;
11737   u32 push_dot1q = 1;
11738   u32 tag1 = ~0;
11739   u32 tag2 = ~0;
11740   int ret;
11741
11742   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11743     {
11744       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11745         sw_if_index_set = 1;
11746       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11747         sw_if_index_set = 1;
11748       else if (unformat (i, "vtr_op %d", &vtr_op))
11749         vtr_op_set = 1;
11750 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
11751       foreach_vtr_op
11752 #undef _
11753         else if (unformat (i, "push_dot1q %d", &push_dot1q))
11754         ;
11755       else if (unformat (i, "tag1 %d", &tag1))
11756         ;
11757       else if (unformat (i, "tag2 %d", &tag2))
11758         ;
11759       else
11760         {
11761           clib_warning ("parse error '%U'", format_unformat_error, i);
11762           return -99;
11763         }
11764     }
11765
11766   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
11767     {
11768       errmsg ("missing vtr operation or sw_if_index");
11769       return -99;
11770     }
11771
11772   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
11773   mp->sw_if_index = ntohl (sw_if_index);
11774   mp->vtr_op = ntohl (vtr_op);
11775   mp->push_dot1q = ntohl (push_dot1q);
11776   mp->tag1 = ntohl (tag1);
11777   mp->tag2 = ntohl (tag2);
11778
11779   S (mp);
11780   W (ret);
11781   return ret;
11782 }
11783
11784 static int
11785 api_create_vhost_user_if (vat_main_t * vam)
11786 {
11787   unformat_input_t *i = vam->input;
11788   vl_api_create_vhost_user_if_t *mp;
11789   u8 *file_name;
11790   u8 is_server = 0;
11791   u8 file_name_set = 0;
11792   u32 custom_dev_instance = ~0;
11793   u8 hwaddr[6];
11794   u8 use_custom_mac = 0;
11795   u8 *tag = 0;
11796   int ret;
11797
11798   /* Shut up coverity */
11799   memset (hwaddr, 0, sizeof (hwaddr));
11800
11801   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11802     {
11803       if (unformat (i, "socket %s", &file_name))
11804         {
11805           file_name_set = 1;
11806         }
11807       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
11808         ;
11809       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
11810         use_custom_mac = 1;
11811       else if (unformat (i, "server"))
11812         is_server = 1;
11813       else if (unformat (i, "tag %s", &tag))
11814         ;
11815       else
11816         break;
11817     }
11818
11819   if (file_name_set == 0)
11820     {
11821       errmsg ("missing socket file name");
11822       return -99;
11823     }
11824
11825   if (vec_len (file_name) > 255)
11826     {
11827       errmsg ("socket file name too long");
11828       return -99;
11829     }
11830   vec_add1 (file_name, 0);
11831
11832   M (CREATE_VHOST_USER_IF, mp);
11833
11834   mp->is_server = is_server;
11835   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
11836   vec_free (file_name);
11837   if (custom_dev_instance != ~0)
11838     {
11839       mp->renumber = 1;
11840       mp->custom_dev_instance = ntohl (custom_dev_instance);
11841     }
11842   mp->use_custom_mac = use_custom_mac;
11843   clib_memcpy (mp->mac_address, hwaddr, 6);
11844   if (tag)
11845     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
11846   vec_free (tag);
11847
11848   S (mp);
11849   W (ret);
11850   return ret;
11851 }
11852
11853 static int
11854 api_modify_vhost_user_if (vat_main_t * vam)
11855 {
11856   unformat_input_t *i = vam->input;
11857   vl_api_modify_vhost_user_if_t *mp;
11858   u8 *file_name;
11859   u8 is_server = 0;
11860   u8 file_name_set = 0;
11861   u32 custom_dev_instance = ~0;
11862   u8 sw_if_index_set = 0;
11863   u32 sw_if_index = (u32) ~ 0;
11864   int ret;
11865
11866   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11867     {
11868       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11869         sw_if_index_set = 1;
11870       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11871         sw_if_index_set = 1;
11872       else if (unformat (i, "socket %s", &file_name))
11873         {
11874           file_name_set = 1;
11875         }
11876       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
11877         ;
11878       else if (unformat (i, "server"))
11879         is_server = 1;
11880       else
11881         break;
11882     }
11883
11884   if (sw_if_index_set == 0)
11885     {
11886       errmsg ("missing sw_if_index or interface name");
11887       return -99;
11888     }
11889
11890   if (file_name_set == 0)
11891     {
11892       errmsg ("missing socket file name");
11893       return -99;
11894     }
11895
11896   if (vec_len (file_name) > 255)
11897     {
11898       errmsg ("socket file name too long");
11899       return -99;
11900     }
11901   vec_add1 (file_name, 0);
11902
11903   M (MODIFY_VHOST_USER_IF, mp);
11904
11905   mp->sw_if_index = ntohl (sw_if_index);
11906   mp->is_server = is_server;
11907   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
11908   vec_free (file_name);
11909   if (custom_dev_instance != ~0)
11910     {
11911       mp->renumber = 1;
11912       mp->custom_dev_instance = ntohl (custom_dev_instance);
11913     }
11914
11915   S (mp);
11916   W (ret);
11917   return ret;
11918 }
11919
11920 static int
11921 api_delete_vhost_user_if (vat_main_t * vam)
11922 {
11923   unformat_input_t *i = vam->input;
11924   vl_api_delete_vhost_user_if_t *mp;
11925   u32 sw_if_index = ~0;
11926   u8 sw_if_index_set = 0;
11927   int ret;
11928
11929   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11930     {
11931       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11932         sw_if_index_set = 1;
11933       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11934         sw_if_index_set = 1;
11935       else
11936         break;
11937     }
11938
11939   if (sw_if_index_set == 0)
11940     {
11941       errmsg ("missing sw_if_index or interface name");
11942       return -99;
11943     }
11944
11945
11946   M (DELETE_VHOST_USER_IF, mp);
11947
11948   mp->sw_if_index = ntohl (sw_if_index);
11949
11950   S (mp);
11951   W (ret);
11952   return ret;
11953 }
11954
11955 static void vl_api_sw_interface_vhost_user_details_t_handler
11956   (vl_api_sw_interface_vhost_user_details_t * mp)
11957 {
11958   vat_main_t *vam = &vat_main;
11959
11960   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
11961          (char *) mp->interface_name,
11962          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
11963          clib_net_to_host_u64 (mp->features), mp->is_server,
11964          ntohl (mp->num_regions), (char *) mp->sock_filename);
11965   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
11966 }
11967
11968 static void vl_api_sw_interface_vhost_user_details_t_handler_json
11969   (vl_api_sw_interface_vhost_user_details_t * mp)
11970 {
11971   vat_main_t *vam = &vat_main;
11972   vat_json_node_t *node = NULL;
11973
11974   if (VAT_JSON_ARRAY != vam->json_tree.type)
11975     {
11976       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11977       vat_json_init_array (&vam->json_tree);
11978     }
11979   node = vat_json_array_add (&vam->json_tree);
11980
11981   vat_json_init_object (node);
11982   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11983   vat_json_object_add_string_copy (node, "interface_name",
11984                                    mp->interface_name);
11985   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
11986                             ntohl (mp->virtio_net_hdr_sz));
11987   vat_json_object_add_uint (node, "features",
11988                             clib_net_to_host_u64 (mp->features));
11989   vat_json_object_add_uint (node, "is_server", mp->is_server);
11990   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
11991   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
11992   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
11993 }
11994
11995 static int
11996 api_sw_interface_vhost_user_dump (vat_main_t * vam)
11997 {
11998   vl_api_sw_interface_vhost_user_dump_t *mp;
11999   vl_api_control_ping_t *mp_ping;
12000   int ret;
12001   print (vam->ofp,
12002          "Interface name            idx hdr_sz features server regions filename");
12003
12004   /* Get list of vhost-user interfaces */
12005   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
12006   S (mp);
12007
12008   /* Use a control ping for synchronization */
12009   M (CONTROL_PING, mp_ping);
12010   S (mp_ping);
12011
12012   W (ret);
12013   return ret;
12014 }
12015
12016 static int
12017 api_show_version (vat_main_t * vam)
12018 {
12019   vl_api_show_version_t *mp;
12020   int ret;
12021
12022   M (SHOW_VERSION, mp);
12023
12024   S (mp);
12025   W (ret);
12026   return ret;
12027 }
12028
12029
12030 static int
12031 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
12032 {
12033   unformat_input_t *line_input = vam->input;
12034   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
12035   ip4_address_t local4, remote4;
12036   ip6_address_t local6, remote6;
12037   u8 is_add = 1;
12038   u8 ipv4_set = 0, ipv6_set = 0;
12039   u8 local_set = 0;
12040   u8 remote_set = 0;
12041   u8 grp_set = 0;
12042   u32 mcast_sw_if_index = ~0;
12043   u32 encap_vrf_id = 0;
12044   u32 decap_vrf_id = 0;
12045   u8 protocol = ~0;
12046   u32 vni;
12047   u8 vni_set = 0;
12048   int ret;
12049
12050   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12051   memset (&local4, 0, sizeof local4);
12052   memset (&remote4, 0, sizeof remote4);
12053   memset (&local6, 0, sizeof local6);
12054   memset (&remote6, 0, sizeof remote6);
12055
12056   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12057     {
12058       if (unformat (line_input, "del"))
12059         is_add = 0;
12060       else if (unformat (line_input, "local %U",
12061                          unformat_ip4_address, &local4))
12062         {
12063           local_set = 1;
12064           ipv4_set = 1;
12065         }
12066       else if (unformat (line_input, "remote %U",
12067                          unformat_ip4_address, &remote4))
12068         {
12069           remote_set = 1;
12070           ipv4_set = 1;
12071         }
12072       else if (unformat (line_input, "local %U",
12073                          unformat_ip6_address, &local6))
12074         {
12075           local_set = 1;
12076           ipv6_set = 1;
12077         }
12078       else if (unformat (line_input, "remote %U",
12079                          unformat_ip6_address, &remote6))
12080         {
12081           remote_set = 1;
12082           ipv6_set = 1;
12083         }
12084       else if (unformat (line_input, "group %U %U",
12085                          unformat_ip4_address, &remote4,
12086                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12087         {
12088           grp_set = remote_set = 1;
12089           ipv4_set = 1;
12090         }
12091       else if (unformat (line_input, "group %U",
12092                          unformat_ip4_address, &remote4))
12093         {
12094           grp_set = remote_set = 1;
12095           ipv4_set = 1;
12096         }
12097       else if (unformat (line_input, "group %U %U",
12098                          unformat_ip6_address, &remote6,
12099                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12100         {
12101           grp_set = remote_set = 1;
12102           ipv6_set = 1;
12103         }
12104       else if (unformat (line_input, "group %U",
12105                          unformat_ip6_address, &remote6))
12106         {
12107           grp_set = remote_set = 1;
12108           ipv6_set = 1;
12109         }
12110       else
12111         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12112         ;
12113       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12114         ;
12115       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
12116         ;
12117       else if (unformat (line_input, "vni %d", &vni))
12118         vni_set = 1;
12119       else if (unformat (line_input, "next-ip4"))
12120         protocol = 1;
12121       else if (unformat (line_input, "next-ip6"))
12122         protocol = 2;
12123       else if (unformat (line_input, "next-ethernet"))
12124         protocol = 3;
12125       else if (unformat (line_input, "next-nsh"))
12126         protocol = 4;
12127       else
12128         {
12129           errmsg ("parse error '%U'", format_unformat_error, line_input);
12130           return -99;
12131         }
12132     }
12133
12134   if (local_set == 0)
12135     {
12136       errmsg ("tunnel local address not specified");
12137       return -99;
12138     }
12139   if (remote_set == 0)
12140     {
12141       errmsg ("tunnel remote address not specified");
12142       return -99;
12143     }
12144   if (grp_set && mcast_sw_if_index == ~0)
12145     {
12146       errmsg ("tunnel nonexistent multicast device");
12147       return -99;
12148     }
12149   if (ipv4_set && ipv6_set)
12150     {
12151       errmsg ("both IPv4 and IPv6 addresses specified");
12152       return -99;
12153     }
12154
12155   if (vni_set == 0)
12156     {
12157       errmsg ("vni not specified");
12158       return -99;
12159     }
12160
12161   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
12162
12163
12164   if (ipv6_set)
12165     {
12166       clib_memcpy (&mp->local, &local6, sizeof (local6));
12167       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
12168     }
12169   else
12170     {
12171       clib_memcpy (&mp->local, &local4, sizeof (local4));
12172       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
12173     }
12174
12175   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12176   mp->encap_vrf_id = ntohl (encap_vrf_id);
12177   mp->decap_vrf_id = ntohl (decap_vrf_id);
12178   mp->protocol = protocol;
12179   mp->vni = ntohl (vni);
12180   mp->is_add = is_add;
12181   mp->is_ipv6 = ipv6_set;
12182
12183   S (mp);
12184   W (ret);
12185   return ret;
12186 }
12187
12188 static void vl_api_vxlan_gpe_tunnel_details_t_handler
12189   (vl_api_vxlan_gpe_tunnel_details_t * mp)
12190 {
12191   vat_main_t *vam = &vat_main;
12192   ip46_address_t local = to_ip46 (mp->is_ipv6, mp->local);
12193   ip46_address_t remote = to_ip46 (mp->is_ipv6, mp->remote);
12194
12195   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
12196          ntohl (mp->sw_if_index),
12197          format_ip46_address, &local, IP46_TYPE_ANY,
12198          format_ip46_address, &remote, IP46_TYPE_ANY,
12199          ntohl (mp->vni), mp->protocol,
12200          ntohl (mp->mcast_sw_if_index),
12201          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
12202 }
12203
12204
12205 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
12206   (vl_api_vxlan_gpe_tunnel_details_t * mp)
12207 {
12208   vat_main_t *vam = &vat_main;
12209   vat_json_node_t *node = NULL;
12210   struct in_addr ip4;
12211   struct in6_addr ip6;
12212
12213   if (VAT_JSON_ARRAY != vam->json_tree.type)
12214     {
12215       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12216       vat_json_init_array (&vam->json_tree);
12217     }
12218   node = vat_json_array_add (&vam->json_tree);
12219
12220   vat_json_init_object (node);
12221   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12222   if (mp->is_ipv6)
12223     {
12224       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
12225       vat_json_object_add_ip6 (node, "local", ip6);
12226       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
12227       vat_json_object_add_ip6 (node, "remote", ip6);
12228     }
12229   else
12230     {
12231       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
12232       vat_json_object_add_ip4 (node, "local", ip4);
12233       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
12234       vat_json_object_add_ip4 (node, "remote", ip4);
12235     }
12236   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12237   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
12238   vat_json_object_add_uint (node, "mcast_sw_if_index",
12239                             ntohl (mp->mcast_sw_if_index));
12240   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12241   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
12242   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12243 }
12244
12245 static int
12246 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
12247 {
12248   unformat_input_t *i = vam->input;
12249   vl_api_vxlan_gpe_tunnel_dump_t *mp;
12250   vl_api_control_ping_t *mp_ping;
12251   u32 sw_if_index;
12252   u8 sw_if_index_set = 0;
12253   int ret;
12254
12255   /* Parse args required to build the message */
12256   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12257     {
12258       if (unformat (i, "sw_if_index %d", &sw_if_index))
12259         sw_if_index_set = 1;
12260       else
12261         break;
12262     }
12263
12264   if (sw_if_index_set == 0)
12265     {
12266       sw_if_index = ~0;
12267     }
12268
12269   if (!vam->json_output)
12270     {
12271       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
12272              "sw_if_index", "local", "remote", "vni",
12273              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
12274     }
12275
12276   /* Get list of vxlan-tunnel interfaces */
12277   M (VXLAN_GPE_TUNNEL_DUMP, mp);
12278
12279   mp->sw_if_index = htonl (sw_if_index);
12280
12281   S (mp);
12282
12283   /* Use a control ping for synchronization */
12284   M (CONTROL_PING, mp_ping);
12285   S (mp_ping);
12286
12287   W (ret);
12288   return ret;
12289 }
12290
12291
12292 u8 *
12293 format_l2_fib_mac_address (u8 * s, va_list * args)
12294 {
12295   u8 *a = va_arg (*args, u8 *);
12296
12297   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
12298                  a[2], a[3], a[4], a[5], a[6], a[7]);
12299 }
12300
12301 static void vl_api_l2_fib_table_details_t_handler
12302   (vl_api_l2_fib_table_details_t * mp)
12303 {
12304   vat_main_t *vam = &vat_main;
12305
12306   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
12307          "       %d       %d     %d",
12308          ntohl (mp->bd_id), format_l2_fib_mac_address, &mp->mac,
12309          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
12310          mp->bvi_mac);
12311 }
12312
12313 static void vl_api_l2_fib_table_details_t_handler_json
12314   (vl_api_l2_fib_table_details_t * mp)
12315 {
12316   vat_main_t *vam = &vat_main;
12317   vat_json_node_t *node = NULL;
12318
12319   if (VAT_JSON_ARRAY != vam->json_tree.type)
12320     {
12321       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12322       vat_json_init_array (&vam->json_tree);
12323     }
12324   node = vat_json_array_add (&vam->json_tree);
12325
12326   vat_json_init_object (node);
12327   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
12328   vat_json_object_add_uint (node, "mac", clib_net_to_host_u64 (mp->mac));
12329   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12330   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
12331   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
12332   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
12333 }
12334
12335 static int
12336 api_l2_fib_table_dump (vat_main_t * vam)
12337 {
12338   unformat_input_t *i = vam->input;
12339   vl_api_l2_fib_table_dump_t *mp;
12340   vl_api_control_ping_t *mp_ping;
12341   u32 bd_id;
12342   u8 bd_id_set = 0;
12343   int ret;
12344
12345   /* Parse args required to build the message */
12346   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12347     {
12348       if (unformat (i, "bd_id %d", &bd_id))
12349         bd_id_set = 1;
12350       else
12351         break;
12352     }
12353
12354   if (bd_id_set == 0)
12355     {
12356       errmsg ("missing bridge domain");
12357       return -99;
12358     }
12359
12360   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
12361
12362   /* Get list of l2 fib entries */
12363   M (L2_FIB_TABLE_DUMP, mp);
12364
12365   mp->bd_id = ntohl (bd_id);
12366   S (mp);
12367
12368   /* Use a control ping for synchronization */
12369   M (CONTROL_PING, mp_ping);
12370   S (mp_ping);
12371
12372   W (ret);
12373   return ret;
12374 }
12375
12376
12377 static int
12378 api_interface_name_renumber (vat_main_t * vam)
12379 {
12380   unformat_input_t *line_input = vam->input;
12381   vl_api_interface_name_renumber_t *mp;
12382   u32 sw_if_index = ~0;
12383   u32 new_show_dev_instance = ~0;
12384   int ret;
12385
12386   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12387     {
12388       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
12389                     &sw_if_index))
12390         ;
12391       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
12392         ;
12393       else if (unformat (line_input, "new_show_dev_instance %d",
12394                          &new_show_dev_instance))
12395         ;
12396       else
12397         break;
12398     }
12399
12400   if (sw_if_index == ~0)
12401     {
12402       errmsg ("missing interface name or sw_if_index");
12403       return -99;
12404     }
12405
12406   if (new_show_dev_instance == ~0)
12407     {
12408       errmsg ("missing new_show_dev_instance");
12409       return -99;
12410     }
12411
12412   M (INTERFACE_NAME_RENUMBER, mp);
12413
12414   mp->sw_if_index = ntohl (sw_if_index);
12415   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
12416
12417   S (mp);
12418   W (ret);
12419   return ret;
12420 }
12421
12422 static int
12423 api_want_ip4_arp_events (vat_main_t * vam)
12424 {
12425   unformat_input_t *line_input = vam->input;
12426   vl_api_want_ip4_arp_events_t *mp;
12427   ip4_address_t address;
12428   int address_set = 0;
12429   u32 enable_disable = 1;
12430   int ret;
12431
12432   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12433     {
12434       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
12435         address_set = 1;
12436       else if (unformat (line_input, "del"))
12437         enable_disable = 0;
12438       else
12439         break;
12440     }
12441
12442   if (address_set == 0)
12443     {
12444       errmsg ("missing addresses");
12445       return -99;
12446     }
12447
12448   M (WANT_IP4_ARP_EVENTS, mp);
12449   mp->enable_disable = enable_disable;
12450   mp->pid = htonl (getpid ());
12451   mp->address = address.as_u32;
12452
12453   S (mp);
12454   W (ret);
12455   return ret;
12456 }
12457
12458 static int
12459 api_want_ip6_nd_events (vat_main_t * vam)
12460 {
12461   unformat_input_t *line_input = vam->input;
12462   vl_api_want_ip6_nd_events_t *mp;
12463   ip6_address_t address;
12464   int address_set = 0;
12465   u32 enable_disable = 1;
12466   int ret;
12467
12468   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12469     {
12470       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
12471         address_set = 1;
12472       else if (unformat (line_input, "del"))
12473         enable_disable = 0;
12474       else
12475         break;
12476     }
12477
12478   if (address_set == 0)
12479     {
12480       errmsg ("missing addresses");
12481       return -99;
12482     }
12483
12484   M (WANT_IP6_ND_EVENTS, mp);
12485   mp->enable_disable = enable_disable;
12486   mp->pid = htonl (getpid ());
12487   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
12488
12489   S (mp);
12490   W (ret);
12491   return ret;
12492 }
12493
12494 static int
12495 api_input_acl_set_interface (vat_main_t * vam)
12496 {
12497   unformat_input_t *i = vam->input;
12498   vl_api_input_acl_set_interface_t *mp;
12499   u32 sw_if_index;
12500   int sw_if_index_set;
12501   u32 ip4_table_index = ~0;
12502   u32 ip6_table_index = ~0;
12503   u32 l2_table_index = ~0;
12504   u8 is_add = 1;
12505   int ret;
12506
12507   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12508     {
12509       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12510         sw_if_index_set = 1;
12511       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12512         sw_if_index_set = 1;
12513       else if (unformat (i, "del"))
12514         is_add = 0;
12515       else if (unformat (i, "ip4-table %d", &ip4_table_index))
12516         ;
12517       else if (unformat (i, "ip6-table %d", &ip6_table_index))
12518         ;
12519       else if (unformat (i, "l2-table %d", &l2_table_index))
12520         ;
12521       else
12522         {
12523           clib_warning ("parse error '%U'", format_unformat_error, i);
12524           return -99;
12525         }
12526     }
12527
12528   if (sw_if_index_set == 0)
12529     {
12530       errmsg ("missing interface name or sw_if_index");
12531       return -99;
12532     }
12533
12534   M (INPUT_ACL_SET_INTERFACE, mp);
12535
12536   mp->sw_if_index = ntohl (sw_if_index);
12537   mp->ip4_table_index = ntohl (ip4_table_index);
12538   mp->ip6_table_index = ntohl (ip6_table_index);
12539   mp->l2_table_index = ntohl (l2_table_index);
12540   mp->is_add = is_add;
12541
12542   S (mp);
12543   W (ret);
12544   return ret;
12545 }
12546
12547 static int
12548 api_ip_address_dump (vat_main_t * vam)
12549 {
12550   unformat_input_t *i = vam->input;
12551   vl_api_ip_address_dump_t *mp;
12552   vl_api_control_ping_t *mp_ping;
12553   u32 sw_if_index = ~0;
12554   u8 sw_if_index_set = 0;
12555   u8 ipv4_set = 0;
12556   u8 ipv6_set = 0;
12557   int ret;
12558
12559   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12560     {
12561       if (unformat (i, "sw_if_index %d", &sw_if_index))
12562         sw_if_index_set = 1;
12563       else
12564         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12565         sw_if_index_set = 1;
12566       else if (unformat (i, "ipv4"))
12567         ipv4_set = 1;
12568       else if (unformat (i, "ipv6"))
12569         ipv6_set = 1;
12570       else
12571         break;
12572     }
12573
12574   if (ipv4_set && ipv6_set)
12575     {
12576       errmsg ("ipv4 and ipv6 flags cannot be both set");
12577       return -99;
12578     }
12579
12580   if ((!ipv4_set) && (!ipv6_set))
12581     {
12582       errmsg ("no ipv4 nor ipv6 flag set");
12583       return -99;
12584     }
12585
12586   if (sw_if_index_set == 0)
12587     {
12588       errmsg ("missing interface name or sw_if_index");
12589       return -99;
12590     }
12591
12592   vam->current_sw_if_index = sw_if_index;
12593   vam->is_ipv6 = ipv6_set;
12594
12595   M (IP_ADDRESS_DUMP, mp);
12596   mp->sw_if_index = ntohl (sw_if_index);
12597   mp->is_ipv6 = ipv6_set;
12598   S (mp);
12599
12600   /* Use a control ping for synchronization */
12601   M (CONTROL_PING, mp_ping);
12602   S (mp_ping);
12603
12604   W (ret);
12605   return ret;
12606 }
12607
12608 static int
12609 api_ip_dump (vat_main_t * vam)
12610 {
12611   vl_api_ip_dump_t *mp;
12612   vl_api_control_ping_t *mp_ping;
12613   unformat_input_t *in = vam->input;
12614   int ipv4_set = 0;
12615   int ipv6_set = 0;
12616   int is_ipv6;
12617   int i;
12618   int ret;
12619
12620   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
12621     {
12622       if (unformat (in, "ipv4"))
12623         ipv4_set = 1;
12624       else if (unformat (in, "ipv6"))
12625         ipv6_set = 1;
12626       else
12627         break;
12628     }
12629
12630   if (ipv4_set && ipv6_set)
12631     {
12632       errmsg ("ipv4 and ipv6 flags cannot be both set");
12633       return -99;
12634     }
12635
12636   if ((!ipv4_set) && (!ipv6_set))
12637     {
12638       errmsg ("no ipv4 nor ipv6 flag set");
12639       return -99;
12640     }
12641
12642   is_ipv6 = ipv6_set;
12643   vam->is_ipv6 = is_ipv6;
12644
12645   /* free old data */
12646   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
12647     {
12648       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
12649     }
12650   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
12651
12652   M (IP_DUMP, mp);
12653   mp->is_ipv6 = ipv6_set;
12654   S (mp);
12655
12656   /* Use a control ping for synchronization */
12657   M (CONTROL_PING, mp_ping);
12658   S (mp_ping);
12659
12660   W (ret);
12661   return ret;
12662 }
12663
12664 static int
12665 api_ipsec_spd_add_del (vat_main_t * vam)
12666 {
12667   unformat_input_t *i = vam->input;
12668   vl_api_ipsec_spd_add_del_t *mp;
12669   u32 spd_id = ~0;
12670   u8 is_add = 1;
12671   int ret;
12672
12673   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12674     {
12675       if (unformat (i, "spd_id %d", &spd_id))
12676         ;
12677       else if (unformat (i, "del"))
12678         is_add = 0;
12679       else
12680         {
12681           clib_warning ("parse error '%U'", format_unformat_error, i);
12682           return -99;
12683         }
12684     }
12685   if (spd_id == ~0)
12686     {
12687       errmsg ("spd_id must be set");
12688       return -99;
12689     }
12690
12691   M (IPSEC_SPD_ADD_DEL, mp);
12692
12693   mp->spd_id = ntohl (spd_id);
12694   mp->is_add = is_add;
12695
12696   S (mp);
12697   W (ret);
12698   return ret;
12699 }
12700
12701 static int
12702 api_ipsec_interface_add_del_spd (vat_main_t * vam)
12703 {
12704   unformat_input_t *i = vam->input;
12705   vl_api_ipsec_interface_add_del_spd_t *mp;
12706   u32 sw_if_index;
12707   u8 sw_if_index_set = 0;
12708   u32 spd_id = (u32) ~ 0;
12709   u8 is_add = 1;
12710   int ret;
12711
12712   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12713     {
12714       if (unformat (i, "del"))
12715         is_add = 0;
12716       else if (unformat (i, "spd_id %d", &spd_id))
12717         ;
12718       else
12719         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12720         sw_if_index_set = 1;
12721       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12722         sw_if_index_set = 1;
12723       else
12724         {
12725           clib_warning ("parse error '%U'", format_unformat_error, i);
12726           return -99;
12727         }
12728
12729     }
12730
12731   if (spd_id == (u32) ~ 0)
12732     {
12733       errmsg ("spd_id must be set");
12734       return -99;
12735     }
12736
12737   if (sw_if_index_set == 0)
12738     {
12739       errmsg ("missing interface name or sw_if_index");
12740       return -99;
12741     }
12742
12743   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
12744
12745   mp->spd_id = ntohl (spd_id);
12746   mp->sw_if_index = ntohl (sw_if_index);
12747   mp->is_add = is_add;
12748
12749   S (mp);
12750   W (ret);
12751   return ret;
12752 }
12753
12754 static int
12755 api_ipsec_spd_add_del_entry (vat_main_t * vam)
12756 {
12757   unformat_input_t *i = vam->input;
12758   vl_api_ipsec_spd_add_del_entry_t *mp;
12759   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
12760   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
12761   i32 priority = 0;
12762   u32 rport_start = 0, rport_stop = (u32) ~ 0;
12763   u32 lport_start = 0, lport_stop = (u32) ~ 0;
12764   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
12765   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
12766   int ret;
12767
12768   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
12769   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
12770   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
12771   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
12772   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
12773   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
12774
12775   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12776     {
12777       if (unformat (i, "del"))
12778         is_add = 0;
12779       if (unformat (i, "outbound"))
12780         is_outbound = 1;
12781       if (unformat (i, "inbound"))
12782         is_outbound = 0;
12783       else if (unformat (i, "spd_id %d", &spd_id))
12784         ;
12785       else if (unformat (i, "sa_id %d", &sa_id))
12786         ;
12787       else if (unformat (i, "priority %d", &priority))
12788         ;
12789       else if (unformat (i, "protocol %d", &protocol))
12790         ;
12791       else if (unformat (i, "lport_start %d", &lport_start))
12792         ;
12793       else if (unformat (i, "lport_stop %d", &lport_stop))
12794         ;
12795       else if (unformat (i, "rport_start %d", &rport_start))
12796         ;
12797       else if (unformat (i, "rport_stop %d", &rport_stop))
12798         ;
12799       else
12800         if (unformat
12801             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
12802         {
12803           is_ipv6 = 0;
12804           is_ip_any = 0;
12805         }
12806       else
12807         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
12808         {
12809           is_ipv6 = 0;
12810           is_ip_any = 0;
12811         }
12812       else
12813         if (unformat
12814             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
12815         {
12816           is_ipv6 = 0;
12817           is_ip_any = 0;
12818         }
12819       else
12820         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
12821         {
12822           is_ipv6 = 0;
12823           is_ip_any = 0;
12824         }
12825       else
12826         if (unformat
12827             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
12828         {
12829           is_ipv6 = 1;
12830           is_ip_any = 0;
12831         }
12832       else
12833         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
12834         {
12835           is_ipv6 = 1;
12836           is_ip_any = 0;
12837         }
12838       else
12839         if (unformat
12840             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
12841         {
12842           is_ipv6 = 1;
12843           is_ip_any = 0;
12844         }
12845       else
12846         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
12847         {
12848           is_ipv6 = 1;
12849           is_ip_any = 0;
12850         }
12851       else
12852         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
12853         {
12854           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
12855             {
12856               clib_warning ("unsupported action: 'resolve'");
12857               return -99;
12858             }
12859         }
12860       else
12861         {
12862           clib_warning ("parse error '%U'", format_unformat_error, i);
12863           return -99;
12864         }
12865
12866     }
12867
12868   M (IPSEC_SPD_ADD_DEL_ENTRY, mp);
12869
12870   mp->spd_id = ntohl (spd_id);
12871   mp->priority = ntohl (priority);
12872   mp->is_outbound = is_outbound;
12873
12874   mp->is_ipv6 = is_ipv6;
12875   if (is_ipv6 || is_ip_any)
12876     {
12877       clib_memcpy (mp->remote_address_start, &raddr6_start,
12878                    sizeof (ip6_address_t));
12879       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
12880                    sizeof (ip6_address_t));
12881       clib_memcpy (mp->local_address_start, &laddr6_start,
12882                    sizeof (ip6_address_t));
12883       clib_memcpy (mp->local_address_stop, &laddr6_stop,
12884                    sizeof (ip6_address_t));
12885     }
12886   else
12887     {
12888       clib_memcpy (mp->remote_address_start, &raddr4_start,
12889                    sizeof (ip4_address_t));
12890       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
12891                    sizeof (ip4_address_t));
12892       clib_memcpy (mp->local_address_start, &laddr4_start,
12893                    sizeof (ip4_address_t));
12894       clib_memcpy (mp->local_address_stop, &laddr4_stop,
12895                    sizeof (ip4_address_t));
12896     }
12897   mp->protocol = (u8) protocol;
12898   mp->local_port_start = ntohs ((u16) lport_start);
12899   mp->local_port_stop = ntohs ((u16) lport_stop);
12900   mp->remote_port_start = ntohs ((u16) rport_start);
12901   mp->remote_port_stop = ntohs ((u16) rport_stop);
12902   mp->policy = (u8) policy;
12903   mp->sa_id = ntohl (sa_id);
12904   mp->is_add = is_add;
12905   mp->is_ip_any = is_ip_any;
12906   S (mp);
12907   W (ret);
12908   return ret;
12909 }
12910
12911 static int
12912 api_ipsec_sad_add_del_entry (vat_main_t * vam)
12913 {
12914   unformat_input_t *i = vam->input;
12915   vl_api_ipsec_sad_add_del_entry_t *mp;
12916   u32 sad_id = 0, spi = 0;
12917   u8 *ck = 0, *ik = 0;
12918   u8 is_add = 1;
12919
12920   u8 protocol = IPSEC_PROTOCOL_AH;
12921   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
12922   u32 crypto_alg = 0, integ_alg = 0;
12923   ip4_address_t tun_src4;
12924   ip4_address_t tun_dst4;
12925   ip6_address_t tun_src6;
12926   ip6_address_t tun_dst6;
12927   int ret;
12928
12929   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12930     {
12931       if (unformat (i, "del"))
12932         is_add = 0;
12933       else if (unformat (i, "sad_id %d", &sad_id))
12934         ;
12935       else if (unformat (i, "spi %d", &spi))
12936         ;
12937       else if (unformat (i, "esp"))
12938         protocol = IPSEC_PROTOCOL_ESP;
12939       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
12940         {
12941           is_tunnel = 1;
12942           is_tunnel_ipv6 = 0;
12943         }
12944       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
12945         {
12946           is_tunnel = 1;
12947           is_tunnel_ipv6 = 0;
12948         }
12949       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
12950         {
12951           is_tunnel = 1;
12952           is_tunnel_ipv6 = 1;
12953         }
12954       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
12955         {
12956           is_tunnel = 1;
12957           is_tunnel_ipv6 = 1;
12958         }
12959       else
12960         if (unformat
12961             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
12962         {
12963           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
12964               crypto_alg >= IPSEC_CRYPTO_N_ALG)
12965             {
12966               clib_warning ("unsupported crypto-alg: '%U'",
12967                             format_ipsec_crypto_alg, crypto_alg);
12968               return -99;
12969             }
12970         }
12971       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
12972         ;
12973       else
12974         if (unformat
12975             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
12976         {
12977           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
12978               integ_alg >= IPSEC_INTEG_N_ALG)
12979             {
12980               clib_warning ("unsupported integ-alg: '%U'",
12981                             format_ipsec_integ_alg, integ_alg);
12982               return -99;
12983             }
12984         }
12985       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
12986         ;
12987       else
12988         {
12989           clib_warning ("parse error '%U'", format_unformat_error, i);
12990           return -99;
12991         }
12992
12993     }
12994
12995   M (IPSEC_SAD_ADD_DEL_ENTRY, mp);
12996
12997   mp->sad_id = ntohl (sad_id);
12998   mp->is_add = is_add;
12999   mp->protocol = protocol;
13000   mp->spi = ntohl (spi);
13001   mp->is_tunnel = is_tunnel;
13002   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
13003   mp->crypto_algorithm = crypto_alg;
13004   mp->integrity_algorithm = integ_alg;
13005   mp->crypto_key_length = vec_len (ck);
13006   mp->integrity_key_length = vec_len (ik);
13007
13008   if (mp->crypto_key_length > sizeof (mp->crypto_key))
13009     mp->crypto_key_length = sizeof (mp->crypto_key);
13010
13011   if (mp->integrity_key_length > sizeof (mp->integrity_key))
13012     mp->integrity_key_length = sizeof (mp->integrity_key);
13013
13014   if (ck)
13015     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
13016   if (ik)
13017     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
13018
13019   if (is_tunnel)
13020     {
13021       if (is_tunnel_ipv6)
13022         {
13023           clib_memcpy (mp->tunnel_src_address, &tun_src6,
13024                        sizeof (ip6_address_t));
13025           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
13026                        sizeof (ip6_address_t));
13027         }
13028       else
13029         {
13030           clib_memcpy (mp->tunnel_src_address, &tun_src4,
13031                        sizeof (ip4_address_t));
13032           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
13033                        sizeof (ip4_address_t));
13034         }
13035     }
13036
13037   S (mp);
13038   W (ret);
13039   return ret;
13040 }
13041
13042 static int
13043 api_ipsec_sa_set_key (vat_main_t * vam)
13044 {
13045   unformat_input_t *i = vam->input;
13046   vl_api_ipsec_sa_set_key_t *mp;
13047   u32 sa_id;
13048   u8 *ck = 0, *ik = 0;
13049   int ret;
13050
13051   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13052     {
13053       if (unformat (i, "sa_id %d", &sa_id))
13054         ;
13055       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
13056         ;
13057       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
13058         ;
13059       else
13060         {
13061           clib_warning ("parse error '%U'", format_unformat_error, i);
13062           return -99;
13063         }
13064     }
13065
13066   M (IPSEC_SA_SET_KEY, mp);
13067
13068   mp->sa_id = ntohl (sa_id);
13069   mp->crypto_key_length = vec_len (ck);
13070   mp->integrity_key_length = vec_len (ik);
13071
13072   if (mp->crypto_key_length > sizeof (mp->crypto_key))
13073     mp->crypto_key_length = sizeof (mp->crypto_key);
13074
13075   if (mp->integrity_key_length > sizeof (mp->integrity_key))
13076     mp->integrity_key_length = sizeof (mp->integrity_key);
13077
13078   if (ck)
13079     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
13080   if (ik)
13081     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
13082
13083   S (mp);
13084   W (ret);
13085   return ret;
13086 }
13087
13088 static int
13089 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
13090 {
13091   unformat_input_t *i = vam->input;
13092   vl_api_ipsec_tunnel_if_add_del_t *mp;
13093   u32 local_spi = 0, remote_spi = 0;
13094   u32 crypto_alg = 0, integ_alg = 0;
13095   u8 *lck = NULL, *rck = NULL;
13096   u8 *lik = NULL, *rik = NULL;
13097   ip4_address_t local_ip = { {0} };
13098   ip4_address_t remote_ip = { {0} };
13099   u8 is_add = 1;
13100   u8 esn = 0;
13101   u8 anti_replay = 0;
13102   int ret;
13103
13104   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13105     {
13106       if (unformat (i, "del"))
13107         is_add = 0;
13108       else if (unformat (i, "esn"))
13109         esn = 1;
13110       else if (unformat (i, "anti_replay"))
13111         anti_replay = 1;
13112       else if (unformat (i, "local_spi %d", &local_spi))
13113         ;
13114       else if (unformat (i, "remote_spi %d", &remote_spi))
13115         ;
13116       else if (unformat (i, "local_ip %U", unformat_ip4_address, &local_ip))
13117         ;
13118       else if (unformat (i, "remote_ip %U", unformat_ip4_address, &remote_ip))
13119         ;
13120       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
13121         ;
13122       else
13123         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
13124         ;
13125       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
13126         ;
13127       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
13128         ;
13129       else
13130         if (unformat
13131             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
13132         {
13133           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
13134               crypto_alg >= IPSEC_CRYPTO_N_ALG)
13135             {
13136               errmsg ("unsupported crypto-alg: '%U'\n",
13137                       format_ipsec_crypto_alg, crypto_alg);
13138               return -99;
13139             }
13140         }
13141       else
13142         if (unformat
13143             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
13144         {
13145           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
13146               integ_alg >= IPSEC_INTEG_N_ALG)
13147             {
13148               errmsg ("unsupported integ-alg: '%U'\n",
13149                       format_ipsec_integ_alg, integ_alg);
13150               return -99;
13151             }
13152         }
13153       else
13154         {
13155           errmsg ("parse error '%U'\n", format_unformat_error, i);
13156           return -99;
13157         }
13158     }
13159
13160   M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
13161
13162   mp->is_add = is_add;
13163   mp->esn = esn;
13164   mp->anti_replay = anti_replay;
13165
13166   clib_memcpy (mp->local_ip, &local_ip, sizeof (ip4_address_t));
13167   clib_memcpy (mp->remote_ip, &remote_ip, sizeof (ip4_address_t));
13168
13169   mp->local_spi = htonl (local_spi);
13170   mp->remote_spi = htonl (remote_spi);
13171   mp->crypto_alg = (u8) crypto_alg;
13172
13173   mp->local_crypto_key_len = 0;
13174   if (lck)
13175     {
13176       mp->local_crypto_key_len = vec_len (lck);
13177       if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
13178         mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
13179       clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
13180     }
13181
13182   mp->remote_crypto_key_len = 0;
13183   if (rck)
13184     {
13185       mp->remote_crypto_key_len = vec_len (rck);
13186       if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
13187         mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
13188       clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
13189     }
13190
13191   mp->integ_alg = (u8) integ_alg;
13192
13193   mp->local_integ_key_len = 0;
13194   if (lik)
13195     {
13196       mp->local_integ_key_len = vec_len (lik);
13197       if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
13198         mp->local_integ_key_len = sizeof (mp->local_integ_key);
13199       clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
13200     }
13201
13202   mp->remote_integ_key_len = 0;
13203   if (rik)
13204     {
13205       mp->remote_integ_key_len = vec_len (rik);
13206       if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
13207         mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
13208       clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
13209     }
13210
13211   S (mp);
13212   W (ret);
13213   return ret;
13214 }
13215
13216 static int
13217 api_ikev2_profile_add_del (vat_main_t * vam)
13218 {
13219   unformat_input_t *i = vam->input;
13220   vl_api_ikev2_profile_add_del_t *mp;
13221   u8 is_add = 1;
13222   u8 *name = 0;
13223   int ret;
13224
13225   const char *valid_chars = "a-zA-Z0-9_";
13226
13227   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13228     {
13229       if (unformat (i, "del"))
13230         is_add = 0;
13231       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
13232         vec_add1 (name, 0);
13233       else
13234         {
13235           errmsg ("parse error '%U'", format_unformat_error, i);
13236           return -99;
13237         }
13238     }
13239
13240   if (!vec_len (name))
13241     {
13242       errmsg ("profile name must be specified");
13243       return -99;
13244     }
13245
13246   if (vec_len (name) > 64)
13247     {
13248       errmsg ("profile name too long");
13249       return -99;
13250     }
13251
13252   M (IKEV2_PROFILE_ADD_DEL, mp);
13253
13254   clib_memcpy (mp->name, name, vec_len (name));
13255   mp->is_add = is_add;
13256   vec_free (name);
13257
13258   S (mp);
13259   W (ret);
13260   return ret;
13261 }
13262
13263 static int
13264 api_ikev2_profile_set_auth (vat_main_t * vam)
13265 {
13266   unformat_input_t *i = vam->input;
13267   vl_api_ikev2_profile_set_auth_t *mp;
13268   u8 *name = 0;
13269   u8 *data = 0;
13270   u32 auth_method = 0;
13271   u8 is_hex = 0;
13272   int ret;
13273
13274   const char *valid_chars = "a-zA-Z0-9_";
13275
13276   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13277     {
13278       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
13279         vec_add1 (name, 0);
13280       else if (unformat (i, "auth_method %U",
13281                          unformat_ikev2_auth_method, &auth_method))
13282         ;
13283       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
13284         is_hex = 1;
13285       else if (unformat (i, "auth_data %v", &data))
13286         ;
13287       else
13288         {
13289           errmsg ("parse error '%U'", format_unformat_error, i);
13290           return -99;
13291         }
13292     }
13293
13294   if (!vec_len (name))
13295     {
13296       errmsg ("profile name must be specified");
13297       return -99;
13298     }
13299
13300   if (vec_len (name) > 64)
13301     {
13302       errmsg ("profile name too long");
13303       return -99;
13304     }
13305
13306   if (!vec_len (data))
13307     {
13308       errmsg ("auth_data must be specified");
13309       return -99;
13310     }
13311
13312   if (!auth_method)
13313     {
13314       errmsg ("auth_method must be specified");
13315       return -99;
13316     }
13317
13318   M (IKEV2_PROFILE_SET_AUTH, mp);
13319
13320   mp->is_hex = is_hex;
13321   mp->auth_method = (u8) auth_method;
13322   mp->data_len = vec_len (data);
13323   clib_memcpy (mp->name, name, vec_len (name));
13324   clib_memcpy (mp->data, data, vec_len (data));
13325   vec_free (name);
13326   vec_free (data);
13327
13328   S (mp);
13329   W (ret);
13330   return ret;
13331 }
13332
13333 static int
13334 api_ikev2_profile_set_id (vat_main_t * vam)
13335 {
13336   unformat_input_t *i = vam->input;
13337   vl_api_ikev2_profile_set_id_t *mp;
13338   u8 *name = 0;
13339   u8 *data = 0;
13340   u8 is_local = 0;
13341   u32 id_type = 0;
13342   ip4_address_t ip4;
13343   int ret;
13344
13345   const char *valid_chars = "a-zA-Z0-9_";
13346
13347   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13348     {
13349       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
13350         vec_add1 (name, 0);
13351       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
13352         ;
13353       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
13354         {
13355           data = vec_new (u8, 4);
13356           clib_memcpy (data, ip4.as_u8, 4);
13357         }
13358       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
13359         ;
13360       else if (unformat (i, "id_data %v", &data))
13361         ;
13362       else if (unformat (i, "local"))
13363         is_local = 1;
13364       else if (unformat (i, "remote"))
13365         is_local = 0;
13366       else
13367         {
13368           errmsg ("parse error '%U'", format_unformat_error, i);
13369           return -99;
13370         }
13371     }
13372
13373   if (!vec_len (name))
13374     {
13375       errmsg ("profile name must be specified");
13376       return -99;
13377     }
13378
13379   if (vec_len (name) > 64)
13380     {
13381       errmsg ("profile name too long");
13382       return -99;
13383     }
13384
13385   if (!vec_len (data))
13386     {
13387       errmsg ("id_data must be specified");
13388       return -99;
13389     }
13390
13391   if (!id_type)
13392     {
13393       errmsg ("id_type must be specified");
13394       return -99;
13395     }
13396
13397   M (IKEV2_PROFILE_SET_ID, mp);
13398
13399   mp->is_local = is_local;
13400   mp->id_type = (u8) id_type;
13401   mp->data_len = vec_len (data);
13402   clib_memcpy (mp->name, name, vec_len (name));
13403   clib_memcpy (mp->data, data, vec_len (data));
13404   vec_free (name);
13405   vec_free (data);
13406
13407   S (mp);
13408   W (ret);
13409   return ret;
13410 }
13411
13412 static int
13413 api_ikev2_profile_set_ts (vat_main_t * vam)
13414 {
13415   unformat_input_t *i = vam->input;
13416   vl_api_ikev2_profile_set_ts_t *mp;
13417   u8 *name = 0;
13418   u8 is_local = 0;
13419   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
13420   ip4_address_t start_addr, end_addr;
13421
13422   const char *valid_chars = "a-zA-Z0-9_";
13423   int ret;
13424
13425   start_addr.as_u32 = 0;
13426   end_addr.as_u32 = (u32) ~ 0;
13427
13428   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13429     {
13430       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
13431         vec_add1 (name, 0);
13432       else if (unformat (i, "protocol %d", &proto))
13433         ;
13434       else if (unformat (i, "start_port %d", &start_port))
13435         ;
13436       else if (unformat (i, "end_port %d", &end_port))
13437         ;
13438       else
13439         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
13440         ;
13441       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
13442         ;
13443       else if (unformat (i, "local"))
13444         is_local = 1;
13445       else if (unformat (i, "remote"))
13446         is_local = 0;
13447       else
13448         {
13449           errmsg ("parse error '%U'", format_unformat_error, i);
13450           return -99;
13451         }
13452     }
13453
13454   if (!vec_len (name))
13455     {
13456       errmsg ("profile name must be specified");
13457       return -99;
13458     }
13459
13460   if (vec_len (name) > 64)
13461     {
13462       errmsg ("profile name too long");
13463       return -99;
13464     }
13465
13466   M (IKEV2_PROFILE_SET_TS, mp);
13467
13468   mp->is_local = is_local;
13469   mp->proto = (u8) proto;
13470   mp->start_port = (u16) start_port;
13471   mp->end_port = (u16) end_port;
13472   mp->start_addr = start_addr.as_u32;
13473   mp->end_addr = end_addr.as_u32;
13474   clib_memcpy (mp->name, name, vec_len (name));
13475   vec_free (name);
13476
13477   S (mp);
13478   W (ret);
13479   return ret;
13480 }
13481
13482 static int
13483 api_ikev2_set_local_key (vat_main_t * vam)
13484 {
13485   unformat_input_t *i = vam->input;
13486   vl_api_ikev2_set_local_key_t *mp;
13487   u8 *file = 0;
13488   int ret;
13489
13490   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13491     {
13492       if (unformat (i, "file %v", &file))
13493         vec_add1 (file, 0);
13494       else
13495         {
13496           errmsg ("parse error '%U'", format_unformat_error, i);
13497           return -99;
13498         }
13499     }
13500
13501   if (!vec_len (file))
13502     {
13503       errmsg ("RSA key file must be specified");
13504       return -99;
13505     }
13506
13507   if (vec_len (file) > 256)
13508     {
13509       errmsg ("file name too long");
13510       return -99;
13511     }
13512
13513   M (IKEV2_SET_LOCAL_KEY, mp);
13514
13515   clib_memcpy (mp->key_file, file, vec_len (file));
13516   vec_free (file);
13517
13518   S (mp);
13519   W (ret);
13520   return ret;
13521 }
13522
13523 static int
13524 api_ikev2_set_responder (vat_main_t * vam)
13525 {
13526   unformat_input_t *i = vam->input;
13527   vl_api_ikev2_set_responder_t *mp;
13528   int ret;
13529   u8 *name = 0;
13530   u32 sw_if_index = ~0;
13531   ip4_address_t address;
13532
13533   const char *valid_chars = "a-zA-Z0-9_";
13534
13535   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13536     {
13537       if (unformat
13538           (i, "%U interface %d address %U", unformat_token, valid_chars,
13539            &name, &sw_if_index, unformat_ip4_address, &address))
13540         vec_add1 (name, 0);
13541       else
13542         {
13543           errmsg ("parse error '%U'", format_unformat_error, i);
13544           return -99;
13545         }
13546     }
13547
13548   if (!vec_len (name))
13549     {
13550       errmsg ("profile name must be specified");
13551       return -99;
13552     }
13553
13554   if (vec_len (name) > 64)
13555     {
13556       errmsg ("profile name too long");
13557       return -99;
13558     }
13559
13560   M (IKEV2_SET_RESPONDER, mp);
13561
13562   clib_memcpy (mp->name, name, vec_len (name));
13563   vec_free (name);
13564
13565   mp->sw_if_index = sw_if_index;
13566   clib_memcpy (mp->address, &address, sizeof (address));
13567
13568   S (mp);
13569   W (ret);
13570   return ret;
13571 }
13572
13573 static int
13574 api_ikev2_set_ike_transforms (vat_main_t * vam)
13575 {
13576   unformat_input_t *i = vam->input;
13577   vl_api_ikev2_set_ike_transforms_t *mp;
13578   int ret;
13579   u8 *name = 0;
13580   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
13581
13582   const char *valid_chars = "a-zA-Z0-9_";
13583
13584   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13585     {
13586       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
13587                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
13588         vec_add1 (name, 0);
13589       else
13590         {
13591           errmsg ("parse error '%U'", format_unformat_error, i);
13592           return -99;
13593         }
13594     }
13595
13596   if (!vec_len (name))
13597     {
13598       errmsg ("profile name must be specified");
13599       return -99;
13600     }
13601
13602   if (vec_len (name) > 64)
13603     {
13604       errmsg ("profile name too long");
13605       return -99;
13606     }
13607
13608   M (IKEV2_SET_IKE_TRANSFORMS, mp);
13609
13610   clib_memcpy (mp->name, name, vec_len (name));
13611   vec_free (name);
13612   mp->crypto_alg = crypto_alg;
13613   mp->crypto_key_size = crypto_key_size;
13614   mp->integ_alg = integ_alg;
13615   mp->dh_group = dh_group;
13616
13617   S (mp);
13618   W (ret);
13619   return ret;
13620 }
13621
13622
13623 static int
13624 api_ikev2_set_esp_transforms (vat_main_t * vam)
13625 {
13626   unformat_input_t *i = vam->input;
13627   vl_api_ikev2_set_esp_transforms_t *mp;
13628   int ret;
13629   u8 *name = 0;
13630   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
13631
13632   const char *valid_chars = "a-zA-Z0-9_";
13633
13634   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13635     {
13636       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
13637                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
13638         vec_add1 (name, 0);
13639       else
13640         {
13641           errmsg ("parse error '%U'", format_unformat_error, i);
13642           return -99;
13643         }
13644     }
13645
13646   if (!vec_len (name))
13647     {
13648       errmsg ("profile name must be specified");
13649       return -99;
13650     }
13651
13652   if (vec_len (name) > 64)
13653     {
13654       errmsg ("profile name too long");
13655       return -99;
13656     }
13657
13658   M (IKEV2_SET_ESP_TRANSFORMS, mp);
13659
13660   clib_memcpy (mp->name, name, vec_len (name));
13661   vec_free (name);
13662   mp->crypto_alg = crypto_alg;
13663   mp->crypto_key_size = crypto_key_size;
13664   mp->integ_alg = integ_alg;
13665   mp->dh_group = dh_group;
13666
13667   S (mp);
13668   W (ret);
13669   return ret;
13670 }
13671
13672 static int
13673 api_ikev2_set_sa_lifetime (vat_main_t * vam)
13674 {
13675   unformat_input_t *i = vam->input;
13676   vl_api_ikev2_set_sa_lifetime_t *mp;
13677   int ret;
13678   u8 *name = 0;
13679   u64 lifetime, lifetime_maxdata;
13680   u32 lifetime_jitter, handover;
13681
13682   const char *valid_chars = "a-zA-Z0-9_";
13683
13684   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13685     {
13686       if (unformat (i, "%U %lu %u %u %lu", unformat_token, valid_chars, &name,
13687                     &lifetime, &lifetime_jitter, &handover,
13688                     &lifetime_maxdata))
13689         vec_add1 (name, 0);
13690       else
13691         {
13692           errmsg ("parse error '%U'", format_unformat_error, i);
13693           return -99;
13694         }
13695     }
13696
13697   if (!vec_len (name))
13698     {
13699       errmsg ("profile name must be specified");
13700       return -99;
13701     }
13702
13703   if (vec_len (name) > 64)
13704     {
13705       errmsg ("profile name too long");
13706       return -99;
13707     }
13708
13709   M (IKEV2_SET_SA_LIFETIME, mp);
13710
13711   clib_memcpy (mp->name, name, vec_len (name));
13712   vec_free (name);
13713   mp->lifetime = lifetime;
13714   mp->lifetime_jitter = lifetime_jitter;
13715   mp->handover = handover;
13716   mp->lifetime_maxdata = lifetime_maxdata;
13717
13718   S (mp);
13719   W (ret);
13720   return ret;
13721 }
13722
13723 static int
13724 api_ikev2_initiate_sa_init (vat_main_t * vam)
13725 {
13726   unformat_input_t *i = vam->input;
13727   vl_api_ikev2_initiate_sa_init_t *mp;
13728   int ret;
13729   u8 *name = 0;
13730
13731   const char *valid_chars = "a-zA-Z0-9_";
13732
13733   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13734     {
13735       if (unformat (i, "%U", unformat_token, valid_chars, &name))
13736         vec_add1 (name, 0);
13737       else
13738         {
13739           errmsg ("parse error '%U'", format_unformat_error, i);
13740           return -99;
13741         }
13742     }
13743
13744   if (!vec_len (name))
13745     {
13746       errmsg ("profile name must be specified");
13747       return -99;
13748     }
13749
13750   if (vec_len (name) > 64)
13751     {
13752       errmsg ("profile name too long");
13753       return -99;
13754     }
13755
13756   M (IKEV2_INITIATE_SA_INIT, mp);
13757
13758   clib_memcpy (mp->name, name, vec_len (name));
13759   vec_free (name);
13760
13761   S (mp);
13762   W (ret);
13763   return ret;
13764 }
13765
13766 static int
13767 api_ikev2_initiate_del_ike_sa (vat_main_t * vam)
13768 {
13769   unformat_input_t *i = vam->input;
13770   vl_api_ikev2_initiate_del_ike_sa_t *mp;
13771   int ret;
13772   u64 ispi;
13773
13774
13775   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13776     {
13777       if (unformat (i, "%lx", &ispi))
13778         ;
13779       else
13780         {
13781           errmsg ("parse error '%U'", format_unformat_error, i);
13782           return -99;
13783         }
13784     }
13785
13786   M (IKEV2_INITIATE_DEL_IKE_SA, mp);
13787
13788   mp->ispi = ispi;
13789
13790   S (mp);
13791   W (ret);
13792   return ret;
13793 }
13794
13795 static int
13796 api_ikev2_initiate_del_child_sa (vat_main_t * vam)
13797 {
13798   unformat_input_t *i = vam->input;
13799   vl_api_ikev2_initiate_del_child_sa_t *mp;
13800   int ret;
13801   u32 ispi;
13802
13803
13804   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13805     {
13806       if (unformat (i, "%x", &ispi))
13807         ;
13808       else
13809         {
13810           errmsg ("parse error '%U'", format_unformat_error, i);
13811           return -99;
13812         }
13813     }
13814
13815   M (IKEV2_INITIATE_DEL_CHILD_SA, mp);
13816
13817   mp->ispi = ispi;
13818
13819   S (mp);
13820   W (ret);
13821   return ret;
13822 }
13823
13824 static int
13825 api_ikev2_initiate_rekey_child_sa (vat_main_t * vam)
13826 {
13827   unformat_input_t *i = vam->input;
13828   vl_api_ikev2_initiate_rekey_child_sa_t *mp;
13829   int ret;
13830   u32 ispi;
13831
13832
13833   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13834     {
13835       if (unformat (i, "%x", &ispi))
13836         ;
13837       else
13838         {
13839           errmsg ("parse error '%U'", format_unformat_error, i);
13840           return -99;
13841         }
13842     }
13843
13844   M (IKEV2_INITIATE_REKEY_CHILD_SA, mp);
13845
13846   mp->ispi = ispi;
13847
13848   S (mp);
13849   W (ret);
13850   return ret;
13851 }
13852
13853 /*
13854  * MAP
13855  */
13856 static int
13857 api_map_add_domain (vat_main_t * vam)
13858 {
13859   unformat_input_t *i = vam->input;
13860   vl_api_map_add_domain_t *mp;
13861
13862   ip4_address_t ip4_prefix;
13863   ip6_address_t ip6_prefix;
13864   ip6_address_t ip6_src;
13865   u32 num_m_args = 0;
13866   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
13867     0, psid_length = 0;
13868   u8 is_translation = 0;
13869   u32 mtu = 0;
13870   u32 ip6_src_len = 128;
13871   int ret;
13872
13873   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13874     {
13875       if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
13876                     &ip4_prefix, &ip4_prefix_len))
13877         num_m_args++;
13878       else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
13879                          &ip6_prefix, &ip6_prefix_len))
13880         num_m_args++;
13881       else
13882         if (unformat
13883             (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
13884              &ip6_src_len))
13885         num_m_args++;
13886       else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
13887         num_m_args++;
13888       else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
13889         num_m_args++;
13890       else if (unformat (i, "psid-offset %d", &psid_offset))
13891         num_m_args++;
13892       else if (unformat (i, "psid-len %d", &psid_length))
13893         num_m_args++;
13894       else if (unformat (i, "mtu %d", &mtu))
13895         num_m_args++;
13896       else if (unformat (i, "map-t"))
13897         is_translation = 1;
13898       else
13899         {
13900           clib_warning ("parse error '%U'", format_unformat_error, i);
13901           return -99;
13902         }
13903     }
13904
13905   if (num_m_args < 3)
13906     {
13907       errmsg ("mandatory argument(s) missing");
13908       return -99;
13909     }
13910
13911   /* Construct the API message */
13912   M (MAP_ADD_DOMAIN, mp);
13913
13914   clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
13915   mp->ip4_prefix_len = ip4_prefix_len;
13916
13917   clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
13918   mp->ip6_prefix_len = ip6_prefix_len;
13919
13920   clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
13921   mp->ip6_src_prefix_len = ip6_src_len;
13922
13923   mp->ea_bits_len = ea_bits_len;
13924   mp->psid_offset = psid_offset;
13925   mp->psid_length = psid_length;
13926   mp->is_translation = is_translation;
13927   mp->mtu = htons (mtu);
13928
13929   /* send it... */
13930   S (mp);
13931
13932   /* Wait for a reply, return good/bad news  */
13933   W (ret);
13934   return ret;
13935 }
13936
13937 static int
13938 api_map_del_domain (vat_main_t * vam)
13939 {
13940   unformat_input_t *i = vam->input;
13941   vl_api_map_del_domain_t *mp;
13942
13943   u32 num_m_args = 0;
13944   u32 index;
13945   int ret;
13946
13947   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13948     {
13949       if (unformat (i, "index %d", &index))
13950         num_m_args++;
13951       else
13952         {
13953           clib_warning ("parse error '%U'", format_unformat_error, i);
13954           return -99;
13955         }
13956     }
13957
13958   if (num_m_args != 1)
13959     {
13960       errmsg ("mandatory argument(s) missing");
13961       return -99;
13962     }
13963
13964   /* Construct the API message */
13965   M (MAP_DEL_DOMAIN, mp);
13966
13967   mp->index = ntohl (index);
13968
13969   /* send it... */
13970   S (mp);
13971
13972   /* Wait for a reply, return good/bad news  */
13973   W (ret);
13974   return ret;
13975 }
13976
13977 static int
13978 api_map_add_del_rule (vat_main_t * vam)
13979 {
13980   unformat_input_t *i = vam->input;
13981   vl_api_map_add_del_rule_t *mp;
13982   u8 is_add = 1;
13983   ip6_address_t ip6_dst;
13984   u32 num_m_args = 0, index, psid = 0;
13985   int ret;
13986
13987   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13988     {
13989       if (unformat (i, "index %d", &index))
13990         num_m_args++;
13991       else if (unformat (i, "psid %d", &psid))
13992         num_m_args++;
13993       else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
13994         num_m_args++;
13995       else if (unformat (i, "del"))
13996         {
13997           is_add = 0;
13998         }
13999       else
14000         {
14001           clib_warning ("parse error '%U'", format_unformat_error, i);
14002           return -99;
14003         }
14004     }
14005
14006   /* Construct the API message */
14007   M (MAP_ADD_DEL_RULE, mp);
14008
14009   mp->index = ntohl (index);
14010   mp->is_add = is_add;
14011   clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
14012   mp->psid = ntohs (psid);
14013
14014   /* send it... */
14015   S (mp);
14016
14017   /* Wait for a reply, return good/bad news  */
14018   W (ret);
14019   return ret;
14020 }
14021
14022 static int
14023 api_map_domain_dump (vat_main_t * vam)
14024 {
14025   vl_api_map_domain_dump_t *mp;
14026   vl_api_control_ping_t *mp_ping;
14027   int ret;
14028
14029   /* Construct the API message */
14030   M (MAP_DOMAIN_DUMP, mp);
14031
14032   /* send it... */
14033   S (mp);
14034
14035   /* Use a control ping for synchronization */
14036   M (CONTROL_PING, mp_ping);
14037   S (mp_ping);
14038
14039   W (ret);
14040   return ret;
14041 }
14042
14043 static int
14044 api_map_rule_dump (vat_main_t * vam)
14045 {
14046   unformat_input_t *i = vam->input;
14047   vl_api_map_rule_dump_t *mp;
14048   vl_api_control_ping_t *mp_ping;
14049   u32 domain_index = ~0;
14050   int ret;
14051
14052   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14053     {
14054       if (unformat (i, "index %u", &domain_index))
14055         ;
14056       else
14057         break;
14058     }
14059
14060   if (domain_index == ~0)
14061     {
14062       clib_warning ("parse error: domain index expected");
14063       return -99;
14064     }
14065
14066   /* Construct the API message */
14067   M (MAP_RULE_DUMP, mp);
14068
14069   mp->domain_index = htonl (domain_index);
14070
14071   /* send it... */
14072   S (mp);
14073
14074   /* Use a control ping for synchronization */
14075   M (CONTROL_PING, mp_ping);
14076   S (mp_ping);
14077
14078   W (ret);
14079   return ret;
14080 }
14081
14082 static void vl_api_map_add_domain_reply_t_handler
14083   (vl_api_map_add_domain_reply_t * mp)
14084 {
14085   vat_main_t *vam = &vat_main;
14086   i32 retval = ntohl (mp->retval);
14087
14088   if (vam->async_mode)
14089     {
14090       vam->async_errors += (retval < 0);
14091     }
14092   else
14093     {
14094       vam->retval = retval;
14095       vam->result_ready = 1;
14096     }
14097 }
14098
14099 static void vl_api_map_add_domain_reply_t_handler_json
14100   (vl_api_map_add_domain_reply_t * mp)
14101 {
14102   vat_main_t *vam = &vat_main;
14103   vat_json_node_t node;
14104
14105   vat_json_init_object (&node);
14106   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
14107   vat_json_object_add_uint (&node, "index", ntohl (mp->index));
14108
14109   vat_json_print (vam->ofp, &node);
14110   vat_json_free (&node);
14111
14112   vam->retval = ntohl (mp->retval);
14113   vam->result_ready = 1;
14114 }
14115
14116 static int
14117 api_get_first_msg_id (vat_main_t * vam)
14118 {
14119   vl_api_get_first_msg_id_t *mp;
14120   unformat_input_t *i = vam->input;
14121   u8 *name;
14122   u8 name_set = 0;
14123   int ret;
14124
14125   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14126     {
14127       if (unformat (i, "client %s", &name))
14128         name_set = 1;
14129       else
14130         break;
14131     }
14132
14133   if (name_set == 0)
14134     {
14135       errmsg ("missing client name");
14136       return -99;
14137     }
14138   vec_add1 (name, 0);
14139
14140   if (vec_len (name) > 63)
14141     {
14142       errmsg ("client name too long");
14143       return -99;
14144     }
14145
14146   M (GET_FIRST_MSG_ID, mp);
14147   clib_memcpy (mp->name, name, vec_len (name));
14148   S (mp);
14149   W (ret);
14150   return ret;
14151 }
14152
14153 static int
14154 api_cop_interface_enable_disable (vat_main_t * vam)
14155 {
14156   unformat_input_t *line_input = vam->input;
14157   vl_api_cop_interface_enable_disable_t *mp;
14158   u32 sw_if_index = ~0;
14159   u8 enable_disable = 1;
14160   int ret;
14161
14162   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14163     {
14164       if (unformat (line_input, "disable"))
14165         enable_disable = 0;
14166       if (unformat (line_input, "enable"))
14167         enable_disable = 1;
14168       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
14169                          vam, &sw_if_index))
14170         ;
14171       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14172         ;
14173       else
14174         break;
14175     }
14176
14177   if (sw_if_index == ~0)
14178     {
14179       errmsg ("missing interface name or sw_if_index");
14180       return -99;
14181     }
14182
14183   /* Construct the API message */
14184   M (COP_INTERFACE_ENABLE_DISABLE, mp);
14185   mp->sw_if_index = ntohl (sw_if_index);
14186   mp->enable_disable = enable_disable;
14187
14188   /* send it... */
14189   S (mp);
14190   /* Wait for the reply */
14191   W (ret);
14192   return ret;
14193 }
14194
14195 static int
14196 api_cop_whitelist_enable_disable (vat_main_t * vam)
14197 {
14198   unformat_input_t *line_input = vam->input;
14199   vl_api_cop_whitelist_enable_disable_t *mp;
14200   u32 sw_if_index = ~0;
14201   u8 ip4 = 0, ip6 = 0, default_cop = 0;
14202   u32 fib_id = 0;
14203   int ret;
14204
14205   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14206     {
14207       if (unformat (line_input, "ip4"))
14208         ip4 = 1;
14209       else if (unformat (line_input, "ip6"))
14210         ip6 = 1;
14211       else if (unformat (line_input, "default"))
14212         default_cop = 1;
14213       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
14214                          vam, &sw_if_index))
14215         ;
14216       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14217         ;
14218       else if (unformat (line_input, "fib-id %d", &fib_id))
14219         ;
14220       else
14221         break;
14222     }
14223
14224   if (sw_if_index == ~0)
14225     {
14226       errmsg ("missing interface name or sw_if_index");
14227       return -99;
14228     }
14229
14230   /* Construct the API message */
14231   M (COP_WHITELIST_ENABLE_DISABLE, mp);
14232   mp->sw_if_index = ntohl (sw_if_index);
14233   mp->fib_id = ntohl (fib_id);
14234   mp->ip4 = ip4;
14235   mp->ip6 = ip6;
14236   mp->default_cop = default_cop;
14237
14238   /* send it... */
14239   S (mp);
14240   /* Wait for the reply */
14241   W (ret);
14242   return ret;
14243 }
14244
14245 static int
14246 api_get_node_graph (vat_main_t * vam)
14247 {
14248   vl_api_get_node_graph_t *mp;
14249   int ret;
14250
14251   M (GET_NODE_GRAPH, mp);
14252
14253   /* send it... */
14254   S (mp);
14255   /* Wait for the reply */
14256   W (ret);
14257   return ret;
14258 }
14259
14260 /* *INDENT-OFF* */
14261 /** Used for parsing LISP eids */
14262 typedef CLIB_PACKED(struct{
14263   u8 addr[16];   /**< eid address */
14264   u32 len;       /**< prefix length if IP */
14265   u8 type;      /**< type of eid */
14266 }) lisp_eid_vat_t;
14267 /* *INDENT-ON* */
14268
14269 static uword
14270 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
14271 {
14272   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
14273
14274   memset (a, 0, sizeof (a[0]));
14275
14276   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
14277     {
14278       a->type = 0;              /* ipv4 type */
14279     }
14280   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
14281     {
14282       a->type = 1;              /* ipv6 type */
14283     }
14284   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
14285     {
14286       a->type = 2;              /* mac type */
14287     }
14288   else if (unformat (input, "%U", unformat_nsh_address, a->addr))
14289     {
14290       a->type = 3;              /* NSH type */
14291       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) a->addr;
14292       nsh->spi = clib_host_to_net_u32 (nsh->spi);
14293     }
14294   else
14295     {
14296       return 0;
14297     }
14298
14299   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
14300     {
14301       return 0;
14302     }
14303
14304   return 1;
14305 }
14306
14307 static int
14308 lisp_eid_size_vat (u8 type)
14309 {
14310   switch (type)
14311     {
14312     case 0:
14313       return 4;
14314     case 1:
14315       return 16;
14316     case 2:
14317       return 6;
14318     case 3:
14319       return 5;
14320     }
14321   return 0;
14322 }
14323
14324 static void
14325 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
14326 {
14327   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
14328 }
14329
14330 static int
14331 api_one_add_del_locator_set (vat_main_t * vam)
14332 {
14333   unformat_input_t *input = vam->input;
14334   vl_api_one_add_del_locator_set_t *mp;
14335   u8 is_add = 1;
14336   u8 *locator_set_name = NULL;
14337   u8 locator_set_name_set = 0;
14338   vl_api_local_locator_t locator, *locators = 0;
14339   u32 sw_if_index, priority, weight;
14340   u32 data_len = 0;
14341
14342   int ret;
14343   /* Parse args required to build the message */
14344   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14345     {
14346       if (unformat (input, "del"))
14347         {
14348           is_add = 0;
14349         }
14350       else if (unformat (input, "locator-set %s", &locator_set_name))
14351         {
14352           locator_set_name_set = 1;
14353         }
14354       else if (unformat (input, "sw_if_index %u p %u w %u",
14355                          &sw_if_index, &priority, &weight))
14356         {
14357           locator.sw_if_index = htonl (sw_if_index);
14358           locator.priority = priority;
14359           locator.weight = weight;
14360           vec_add1 (locators, locator);
14361         }
14362       else
14363         if (unformat
14364             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
14365              &sw_if_index, &priority, &weight))
14366         {
14367           locator.sw_if_index = htonl (sw_if_index);
14368           locator.priority = priority;
14369           locator.weight = weight;
14370           vec_add1 (locators, locator);
14371         }
14372       else
14373         break;
14374     }
14375
14376   if (locator_set_name_set == 0)
14377     {
14378       errmsg ("missing locator-set name");
14379       vec_free (locators);
14380       return -99;
14381     }
14382
14383   if (vec_len (locator_set_name) > 64)
14384     {
14385       errmsg ("locator-set name too long");
14386       vec_free (locator_set_name);
14387       vec_free (locators);
14388       return -99;
14389     }
14390   vec_add1 (locator_set_name, 0);
14391
14392   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
14393
14394   /* Construct the API message */
14395   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
14396
14397   mp->is_add = is_add;
14398   clib_memcpy (mp->locator_set_name, locator_set_name,
14399                vec_len (locator_set_name));
14400   vec_free (locator_set_name);
14401
14402   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
14403   if (locators)
14404     clib_memcpy (mp->locators, locators, data_len);
14405   vec_free (locators);
14406
14407   /* send it... */
14408   S (mp);
14409
14410   /* Wait for a reply... */
14411   W (ret);
14412   return ret;
14413 }
14414
14415 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
14416
14417 static int
14418 api_one_add_del_locator (vat_main_t * vam)
14419 {
14420   unformat_input_t *input = vam->input;
14421   vl_api_one_add_del_locator_t *mp;
14422   u32 tmp_if_index = ~0;
14423   u32 sw_if_index = ~0;
14424   u8 sw_if_index_set = 0;
14425   u8 sw_if_index_if_name_set = 0;
14426   u32 priority = ~0;
14427   u8 priority_set = 0;
14428   u32 weight = ~0;
14429   u8 weight_set = 0;
14430   u8 is_add = 1;
14431   u8 *locator_set_name = NULL;
14432   u8 locator_set_name_set = 0;
14433   int ret;
14434
14435   /* Parse args required to build the message */
14436   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14437     {
14438       if (unformat (input, "del"))
14439         {
14440           is_add = 0;
14441         }
14442       else if (unformat (input, "locator-set %s", &locator_set_name))
14443         {
14444           locator_set_name_set = 1;
14445         }
14446       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
14447                          &tmp_if_index))
14448         {
14449           sw_if_index_if_name_set = 1;
14450           sw_if_index = tmp_if_index;
14451         }
14452       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
14453         {
14454           sw_if_index_set = 1;
14455           sw_if_index = tmp_if_index;
14456         }
14457       else if (unformat (input, "p %d", &priority))
14458         {
14459           priority_set = 1;
14460         }
14461       else if (unformat (input, "w %d", &weight))
14462         {
14463           weight_set = 1;
14464         }
14465       else
14466         break;
14467     }
14468
14469   if (locator_set_name_set == 0)
14470     {
14471       errmsg ("missing locator-set name");
14472       return -99;
14473     }
14474
14475   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
14476     {
14477       errmsg ("missing sw_if_index");
14478       vec_free (locator_set_name);
14479       return -99;
14480     }
14481
14482   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
14483     {
14484       errmsg ("cannot use both params interface name and sw_if_index");
14485       vec_free (locator_set_name);
14486       return -99;
14487     }
14488
14489   if (priority_set == 0)
14490     {
14491       errmsg ("missing locator-set priority");
14492       vec_free (locator_set_name);
14493       return -99;
14494     }
14495
14496   if (weight_set == 0)
14497     {
14498       errmsg ("missing locator-set weight");
14499       vec_free (locator_set_name);
14500       return -99;
14501     }
14502
14503   if (vec_len (locator_set_name) > 64)
14504     {
14505       errmsg ("locator-set name too long");
14506       vec_free (locator_set_name);
14507       return -99;
14508     }
14509   vec_add1 (locator_set_name, 0);
14510
14511   /* Construct the API message */
14512   M (ONE_ADD_DEL_LOCATOR, mp);
14513
14514   mp->is_add = is_add;
14515   mp->sw_if_index = ntohl (sw_if_index);
14516   mp->priority = priority;
14517   mp->weight = weight;
14518   clib_memcpy (mp->locator_set_name, locator_set_name,
14519                vec_len (locator_set_name));
14520   vec_free (locator_set_name);
14521
14522   /* send it... */
14523   S (mp);
14524
14525   /* Wait for a reply... */
14526   W (ret);
14527   return ret;
14528 }
14529
14530 #define api_lisp_add_del_locator api_one_add_del_locator
14531
14532 uword
14533 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
14534 {
14535   u32 *key_id = va_arg (*args, u32 *);
14536   u8 *s = 0;
14537
14538   if (unformat (input, "%s", &s))
14539     {
14540       if (!strcmp ((char *) s, "sha1"))
14541         key_id[0] = HMAC_SHA_1_96;
14542       else if (!strcmp ((char *) s, "sha256"))
14543         key_id[0] = HMAC_SHA_256_128;
14544       else
14545         {
14546           clib_warning ("invalid key_id: '%s'", s);
14547           key_id[0] = HMAC_NO_KEY;
14548         }
14549     }
14550   else
14551     return 0;
14552
14553   vec_free (s);
14554   return 1;
14555 }
14556
14557 static int
14558 api_one_add_del_local_eid (vat_main_t * vam)
14559 {
14560   unformat_input_t *input = vam->input;
14561   vl_api_one_add_del_local_eid_t *mp;
14562   u8 is_add = 1;
14563   u8 eid_set = 0;
14564   lisp_eid_vat_t _eid, *eid = &_eid;
14565   u8 *locator_set_name = 0;
14566   u8 locator_set_name_set = 0;
14567   u32 vni = 0;
14568   u16 key_id = 0;
14569   u8 *key = 0;
14570   int ret;
14571
14572   /* Parse args required to build the message */
14573   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14574     {
14575       if (unformat (input, "del"))
14576         {
14577           is_add = 0;
14578         }
14579       else if (unformat (input, "vni %d", &vni))
14580         {
14581           ;
14582         }
14583       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
14584         {
14585           eid_set = 1;
14586         }
14587       else if (unformat (input, "locator-set %s", &locator_set_name))
14588         {
14589           locator_set_name_set = 1;
14590         }
14591       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
14592         ;
14593       else if (unformat (input, "secret-key %_%v%_", &key))
14594         ;
14595       else
14596         break;
14597     }
14598
14599   if (locator_set_name_set == 0)
14600     {
14601       errmsg ("missing locator-set name");
14602       return -99;
14603     }
14604
14605   if (0 == eid_set)
14606     {
14607       errmsg ("EID address not set!");
14608       vec_free (locator_set_name);
14609       return -99;
14610     }
14611
14612   if (key && (0 == key_id))
14613     {
14614       errmsg ("invalid key_id!");
14615       return -99;
14616     }
14617
14618   if (vec_len (key) > 64)
14619     {
14620       errmsg ("key too long");
14621       vec_free (key);
14622       return -99;
14623     }
14624
14625   if (vec_len (locator_set_name) > 64)
14626     {
14627       errmsg ("locator-set name too long");
14628       vec_free (locator_set_name);
14629       return -99;
14630     }
14631   vec_add1 (locator_set_name, 0);
14632
14633   /* Construct the API message */
14634   M (ONE_ADD_DEL_LOCAL_EID, mp);
14635
14636   mp->is_add = is_add;
14637   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
14638   mp->eid_type = eid->type;
14639   mp->prefix_len = eid->len;
14640   mp->vni = clib_host_to_net_u32 (vni);
14641   mp->key_id = clib_host_to_net_u16 (key_id);
14642   clib_memcpy (mp->locator_set_name, locator_set_name,
14643                vec_len (locator_set_name));
14644   clib_memcpy (mp->key, key, vec_len (key));
14645
14646   vec_free (locator_set_name);
14647   vec_free (key);
14648
14649   /* send it... */
14650   S (mp);
14651
14652   /* Wait for a reply... */
14653   W (ret);
14654   return ret;
14655 }
14656
14657 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
14658
14659 static int
14660 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
14661 {
14662   u32 dp_table = 0, vni = 0;;
14663   unformat_input_t *input = vam->input;
14664   vl_api_gpe_add_del_fwd_entry_t *mp;
14665   u8 is_add = 1;
14666   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
14667   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
14668   u8 rmt_eid_set = 0, lcl_eid_set = 0;
14669   u32 action = ~0, w;
14670   ip4_address_t rmt_rloc4, lcl_rloc4;
14671   ip6_address_t rmt_rloc6, lcl_rloc6;
14672   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
14673   int ret;
14674
14675   memset (&rloc, 0, sizeof (rloc));
14676
14677   /* Parse args required to build the message */
14678   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14679     {
14680       if (unformat (input, "del"))
14681         is_add = 0;
14682       else if (unformat (input, "add"))
14683         is_add = 1;
14684       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
14685         {
14686           rmt_eid_set = 1;
14687         }
14688       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
14689         {
14690           lcl_eid_set = 1;
14691         }
14692       else if (unformat (input, "vrf %d", &dp_table))
14693         ;
14694       else if (unformat (input, "bd %d", &dp_table))
14695         ;
14696       else if (unformat (input, "vni %d", &vni))
14697         ;
14698       else if (unformat (input, "w %d", &w))
14699         {
14700           if (!curr_rloc)
14701             {
14702               errmsg ("No RLOC configured for setting priority/weight!");
14703               return -99;
14704             }
14705           curr_rloc->weight = w;
14706         }
14707       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
14708                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
14709         {
14710           rloc.is_ip4 = 1;
14711
14712           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
14713           rloc.weight = 0;
14714           vec_add1 (lcl_locs, rloc);
14715
14716           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
14717           vec_add1 (rmt_locs, rloc);
14718           /* weight saved in rmt loc */
14719           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
14720         }
14721       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
14722                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
14723         {
14724           rloc.is_ip4 = 0;
14725           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
14726           rloc.weight = 0;
14727           vec_add1 (lcl_locs, rloc);
14728
14729           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
14730           vec_add1 (rmt_locs, rloc);
14731           /* weight saved in rmt loc */
14732           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
14733         }
14734       else if (unformat (input, "action %d", &action))
14735         {
14736           ;
14737         }
14738       else
14739         {
14740           clib_warning ("parse error '%U'", format_unformat_error, input);
14741           return -99;
14742         }
14743     }
14744
14745   if (!rmt_eid_set)
14746     {
14747       errmsg ("remote eid addresses not set");
14748       return -99;
14749     }
14750
14751   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
14752     {
14753       errmsg ("eid types don't match");
14754       return -99;
14755     }
14756
14757   if (0 == rmt_locs && (u32) ~ 0 == action)
14758     {
14759       errmsg ("action not set for negative mapping");
14760       return -99;
14761     }
14762
14763   /* Construct the API message */
14764   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
14765       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
14766
14767   mp->is_add = is_add;
14768   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
14769   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
14770   mp->eid_type = rmt_eid->type;
14771   mp->dp_table = clib_host_to_net_u32 (dp_table);
14772   mp->vni = clib_host_to_net_u32 (vni);
14773   mp->rmt_len = rmt_eid->len;
14774   mp->lcl_len = lcl_eid->len;
14775   mp->action = action;
14776
14777   if (0 != rmt_locs && 0 != lcl_locs)
14778     {
14779       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
14780       clib_memcpy (mp->locs, lcl_locs,
14781                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
14782
14783       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
14784       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
14785                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
14786     }
14787   vec_free (lcl_locs);
14788   vec_free (rmt_locs);
14789
14790   /* send it... */
14791   S (mp);
14792
14793   /* Wait for a reply... */
14794   W (ret);
14795   return ret;
14796 }
14797
14798 static int
14799 api_one_add_del_map_server (vat_main_t * vam)
14800 {
14801   unformat_input_t *input = vam->input;
14802   vl_api_one_add_del_map_server_t *mp;
14803   u8 is_add = 1;
14804   u8 ipv4_set = 0;
14805   u8 ipv6_set = 0;
14806   ip4_address_t ipv4;
14807   ip6_address_t ipv6;
14808   int ret;
14809
14810   /* Parse args required to build the message */
14811   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14812     {
14813       if (unformat (input, "del"))
14814         {
14815           is_add = 0;
14816         }
14817       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
14818         {
14819           ipv4_set = 1;
14820         }
14821       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
14822         {
14823           ipv6_set = 1;
14824         }
14825       else
14826         break;
14827     }
14828
14829   if (ipv4_set && ipv6_set)
14830     {
14831       errmsg ("both eid v4 and v6 addresses set");
14832       return -99;
14833     }
14834
14835   if (!ipv4_set && !ipv6_set)
14836     {
14837       errmsg ("eid addresses not set");
14838       return -99;
14839     }
14840
14841   /* Construct the API message */
14842   M (ONE_ADD_DEL_MAP_SERVER, mp);
14843
14844   mp->is_add = is_add;
14845   if (ipv6_set)
14846     {
14847       mp->is_ipv6 = 1;
14848       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
14849     }
14850   else
14851     {
14852       mp->is_ipv6 = 0;
14853       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
14854     }
14855
14856   /* send it... */
14857   S (mp);
14858
14859   /* Wait for a reply... */
14860   W (ret);
14861   return ret;
14862 }
14863
14864 #define api_lisp_add_del_map_server api_one_add_del_map_server
14865
14866 static int
14867 api_one_add_del_map_resolver (vat_main_t * vam)
14868 {
14869   unformat_input_t *input = vam->input;
14870   vl_api_one_add_del_map_resolver_t *mp;
14871   u8 is_add = 1;
14872   u8 ipv4_set = 0;
14873   u8 ipv6_set = 0;
14874   ip4_address_t ipv4;
14875   ip6_address_t ipv6;
14876   int ret;
14877
14878   /* Parse args required to build the message */
14879   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14880     {
14881       if (unformat (input, "del"))
14882         {
14883           is_add = 0;
14884         }
14885       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
14886         {
14887           ipv4_set = 1;
14888         }
14889       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
14890         {
14891           ipv6_set = 1;
14892         }
14893       else
14894         break;
14895     }
14896
14897   if (ipv4_set && ipv6_set)
14898     {
14899       errmsg ("both eid v4 and v6 addresses set");
14900       return -99;
14901     }
14902
14903   if (!ipv4_set && !ipv6_set)
14904     {
14905       errmsg ("eid addresses not set");
14906       return -99;
14907     }
14908
14909   /* Construct the API message */
14910   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
14911
14912   mp->is_add = is_add;
14913   if (ipv6_set)
14914     {
14915       mp->is_ipv6 = 1;
14916       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
14917     }
14918   else
14919     {
14920       mp->is_ipv6 = 0;
14921       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
14922     }
14923
14924   /* send it... */
14925   S (mp);
14926
14927   /* Wait for a reply... */
14928   W (ret);
14929   return ret;
14930 }
14931
14932 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
14933
14934 static int
14935 api_lisp_gpe_enable_disable (vat_main_t * vam)
14936 {
14937   unformat_input_t *input = vam->input;
14938   vl_api_gpe_enable_disable_t *mp;
14939   u8 is_set = 0;
14940   u8 is_en = 1;
14941   int ret;
14942
14943   /* Parse args required to build the message */
14944   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14945     {
14946       if (unformat (input, "enable"))
14947         {
14948           is_set = 1;
14949           is_en = 1;
14950         }
14951       else if (unformat (input, "disable"))
14952         {
14953           is_set = 1;
14954           is_en = 0;
14955         }
14956       else
14957         break;
14958     }
14959
14960   if (is_set == 0)
14961     {
14962       errmsg ("Value not set");
14963       return -99;
14964     }
14965
14966   /* Construct the API message */
14967   M (GPE_ENABLE_DISABLE, mp);
14968
14969   mp->is_en = is_en;
14970
14971   /* send it... */
14972   S (mp);
14973
14974   /* Wait for a reply... */
14975   W (ret);
14976   return ret;
14977 }
14978
14979 static int
14980 api_one_rloc_probe_enable_disable (vat_main_t * vam)
14981 {
14982   unformat_input_t *input = vam->input;
14983   vl_api_one_rloc_probe_enable_disable_t *mp;
14984   u8 is_set = 0;
14985   u8 is_en = 0;
14986   int ret;
14987
14988   /* Parse args required to build the message */
14989   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14990     {
14991       if (unformat (input, "enable"))
14992         {
14993           is_set = 1;
14994           is_en = 1;
14995         }
14996       else if (unformat (input, "disable"))
14997         is_set = 1;
14998       else
14999         break;
15000     }
15001
15002   if (!is_set)
15003     {
15004       errmsg ("Value not set");
15005       return -99;
15006     }
15007
15008   /* Construct the API message */
15009   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
15010
15011   mp->is_enabled = is_en;
15012
15013   /* send it... */
15014   S (mp);
15015
15016   /* Wait for a reply... */
15017   W (ret);
15018   return ret;
15019 }
15020
15021 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
15022
15023 static int
15024 api_one_map_register_enable_disable (vat_main_t * vam)
15025 {
15026   unformat_input_t *input = vam->input;
15027   vl_api_one_map_register_enable_disable_t *mp;
15028   u8 is_set = 0;
15029   u8 is_en = 0;
15030   int ret;
15031
15032   /* Parse args required to build the message */
15033   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15034     {
15035       if (unformat (input, "enable"))
15036         {
15037           is_set = 1;
15038           is_en = 1;
15039         }
15040       else if (unformat (input, "disable"))
15041         is_set = 1;
15042       else
15043         break;
15044     }
15045
15046   if (!is_set)
15047     {
15048       errmsg ("Value not set");
15049       return -99;
15050     }
15051
15052   /* Construct the API message */
15053   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
15054
15055   mp->is_enabled = is_en;
15056
15057   /* send it... */
15058   S (mp);
15059
15060   /* Wait for a reply... */
15061   W (ret);
15062   return ret;
15063 }
15064
15065 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
15066
15067 static int
15068 api_one_enable_disable (vat_main_t * vam)
15069 {
15070   unformat_input_t *input = vam->input;
15071   vl_api_one_enable_disable_t *mp;
15072   u8 is_set = 0;
15073   u8 is_en = 0;
15074   int ret;
15075
15076   /* Parse args required to build the message */
15077   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15078     {
15079       if (unformat (input, "enable"))
15080         {
15081           is_set = 1;
15082           is_en = 1;
15083         }
15084       else if (unformat (input, "disable"))
15085         {
15086           is_set = 1;
15087         }
15088       else
15089         break;
15090     }
15091
15092   if (!is_set)
15093     {
15094       errmsg ("Value not set");
15095       return -99;
15096     }
15097
15098   /* Construct the API message */
15099   M (ONE_ENABLE_DISABLE, mp);
15100
15101   mp->is_en = is_en;
15102
15103   /* send it... */
15104   S (mp);
15105
15106   /* Wait for a reply... */
15107   W (ret);
15108   return ret;
15109 }
15110
15111 #define api_lisp_enable_disable api_one_enable_disable
15112
15113 static int
15114 api_show_one_map_register_state (vat_main_t * vam)
15115 {
15116   vl_api_show_one_map_register_state_t *mp;
15117   int ret;
15118
15119   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
15120
15121   /* send */
15122   S (mp);
15123
15124   /* wait for reply */
15125   W (ret);
15126   return ret;
15127 }
15128
15129 #define api_show_lisp_map_register_state api_show_one_map_register_state
15130
15131 static int
15132 api_show_one_rloc_probe_state (vat_main_t * vam)
15133 {
15134   vl_api_show_one_rloc_probe_state_t *mp;
15135   int ret;
15136
15137   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
15138
15139   /* send */
15140   S (mp);
15141
15142   /* wait for reply */
15143   W (ret);
15144   return ret;
15145 }
15146
15147 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
15148
15149 static int
15150 api_one_add_del_l2_arp_entry (vat_main_t * vam)
15151 {
15152   vl_api_one_add_del_l2_arp_entry_t *mp;
15153   unformat_input_t *input = vam->input;
15154   u8 is_add = 1;
15155   u8 mac_set = 0;
15156   u8 bd_set = 0;
15157   u8 ip_set = 0;
15158   u8 mac[6] = { 0, };
15159   u32 ip4 = 0, bd = ~0;
15160   int ret;
15161
15162   /* Parse args required to build the message */
15163   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15164     {
15165       if (unformat (input, "del"))
15166         is_add = 0;
15167       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
15168         mac_set = 1;
15169       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
15170         ip_set = 1;
15171       else if (unformat (input, "bd %d", &bd))
15172         bd_set = 1;
15173       else
15174         {
15175           errmsg ("parse error '%U'", format_unformat_error, input);
15176           return -99;
15177         }
15178     }
15179
15180   if (!bd_set || !ip_set || (!mac_set && is_add))
15181     {
15182       errmsg ("Missing BD, IP or MAC!");
15183       return -99;
15184     }
15185
15186   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
15187   mp->is_add = is_add;
15188   clib_memcpy (mp->mac, mac, 6);
15189   mp->bd = clib_host_to_net_u32 (bd);
15190   mp->ip4 = ip4;
15191
15192   /* send */
15193   S (mp);
15194
15195   /* wait for reply */
15196   W (ret);
15197   return ret;
15198 }
15199
15200 static int
15201 api_one_l2_arp_bd_get (vat_main_t * vam)
15202 {
15203   vl_api_one_l2_arp_bd_get_t *mp;
15204   int ret;
15205
15206   M (ONE_L2_ARP_BD_GET, mp);
15207
15208   /* send */
15209   S (mp);
15210
15211   /* wait for reply */
15212   W (ret);
15213   return ret;
15214 }
15215
15216 static int
15217 api_one_l2_arp_entries_get (vat_main_t * vam)
15218 {
15219   vl_api_one_l2_arp_entries_get_t *mp;
15220   unformat_input_t *input = vam->input;
15221   u8 bd_set = 0;
15222   u32 bd = ~0;
15223   int ret;
15224
15225   /* Parse args required to build the message */
15226   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15227     {
15228       if (unformat (input, "bd %d", &bd))
15229         bd_set = 1;
15230       else
15231         {
15232           errmsg ("parse error '%U'", format_unformat_error, input);
15233           return -99;
15234         }
15235     }
15236
15237   if (!bd_set)
15238     {
15239       errmsg ("Expected bridge domain!");
15240       return -99;
15241     }
15242
15243   M (ONE_L2_ARP_ENTRIES_GET, mp);
15244   mp->bd = clib_host_to_net_u32 (bd);
15245
15246   /* send */
15247   S (mp);
15248
15249   /* wait for reply */
15250   W (ret);
15251   return ret;
15252 }
15253
15254 static int
15255 api_one_stats_enable_disable (vat_main_t * vam)
15256 {
15257   vl_api_one_stats_enable_disable_t *mp;
15258   unformat_input_t *input = vam->input;
15259   u8 is_set = 0;
15260   u8 is_en = 0;
15261   int ret;
15262
15263   /* Parse args required to build the message */
15264   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15265     {
15266       if (unformat (input, "enable"))
15267         {
15268           is_set = 1;
15269           is_en = 1;
15270         }
15271       else if (unformat (input, "disable"))
15272         {
15273           is_set = 1;
15274         }
15275       else
15276         break;
15277     }
15278
15279   if (!is_set)
15280     {
15281       errmsg ("Value not set");
15282       return -99;
15283     }
15284
15285   M (ONE_STATS_ENABLE_DISABLE, mp);
15286   mp->is_en = is_en;
15287
15288   /* send */
15289   S (mp);
15290
15291   /* wait for reply */
15292   W (ret);
15293   return ret;
15294 }
15295
15296 static int
15297 api_show_one_stats_enable_disable (vat_main_t * vam)
15298 {
15299   vl_api_show_one_stats_enable_disable_t *mp;
15300   int ret;
15301
15302   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
15303
15304   /* send */
15305   S (mp);
15306
15307   /* wait for reply */
15308   W (ret);
15309   return ret;
15310 }
15311
15312 static int
15313 api_show_one_map_request_mode (vat_main_t * vam)
15314 {
15315   vl_api_show_one_map_request_mode_t *mp;
15316   int ret;
15317
15318   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
15319
15320   /* send */
15321   S (mp);
15322
15323   /* wait for reply */
15324   W (ret);
15325   return ret;
15326 }
15327
15328 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
15329
15330 static int
15331 api_one_map_request_mode (vat_main_t * vam)
15332 {
15333   unformat_input_t *input = vam->input;
15334   vl_api_one_map_request_mode_t *mp;
15335   u8 mode = 0;
15336   int ret;
15337
15338   /* Parse args required to build the message */
15339   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15340     {
15341       if (unformat (input, "dst-only"))
15342         mode = 0;
15343       else if (unformat (input, "src-dst"))
15344         mode = 1;
15345       else
15346         {
15347           errmsg ("parse error '%U'", format_unformat_error, input);
15348           return -99;
15349         }
15350     }
15351
15352   M (ONE_MAP_REQUEST_MODE, mp);
15353
15354   mp->mode = mode;
15355
15356   /* send */
15357   S (mp);
15358
15359   /* wait for reply */
15360   W (ret);
15361   return ret;
15362 }
15363
15364 #define api_lisp_map_request_mode api_one_map_request_mode
15365
15366 /**
15367  * Enable/disable ONE proxy ITR.
15368  *
15369  * @param vam vpp API test context
15370  * @return return code
15371  */
15372 static int
15373 api_one_pitr_set_locator_set (vat_main_t * vam)
15374 {
15375   u8 ls_name_set = 0;
15376   unformat_input_t *input = vam->input;
15377   vl_api_one_pitr_set_locator_set_t *mp;
15378   u8 is_add = 1;
15379   u8 *ls_name = 0;
15380   int ret;
15381
15382   /* Parse args required to build the message */
15383   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15384     {
15385       if (unformat (input, "del"))
15386         is_add = 0;
15387       else if (unformat (input, "locator-set %s", &ls_name))
15388         ls_name_set = 1;
15389       else
15390         {
15391           errmsg ("parse error '%U'", format_unformat_error, input);
15392           return -99;
15393         }
15394     }
15395
15396   if (!ls_name_set)
15397     {
15398       errmsg ("locator-set name not set!");
15399       return -99;
15400     }
15401
15402   M (ONE_PITR_SET_LOCATOR_SET, mp);
15403
15404   mp->is_add = is_add;
15405   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
15406   vec_free (ls_name);
15407
15408   /* send */
15409   S (mp);
15410
15411   /* wait for reply */
15412   W (ret);
15413   return ret;
15414 }
15415
15416 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
15417
15418 static int
15419 api_one_nsh_set_locator_set (vat_main_t * vam)
15420 {
15421   u8 ls_name_set = 0;
15422   unformat_input_t *input = vam->input;
15423   vl_api_one_nsh_set_locator_set_t *mp;
15424   u8 is_add = 1;
15425   u8 *ls_name = 0;
15426   int ret;
15427
15428   /* Parse args required to build the message */
15429   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15430     {
15431       if (unformat (input, "del"))
15432         is_add = 0;
15433       else if (unformat (input, "ls %s", &ls_name))
15434         ls_name_set = 1;
15435       else
15436         {
15437           errmsg ("parse error '%U'", format_unformat_error, input);
15438           return -99;
15439         }
15440     }
15441
15442   if (!ls_name_set && is_add)
15443     {
15444       errmsg ("locator-set name not set!");
15445       return -99;
15446     }
15447
15448   M (ONE_NSH_SET_LOCATOR_SET, mp);
15449
15450   mp->is_add = is_add;
15451   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
15452   vec_free (ls_name);
15453
15454   /* send */
15455   S (mp);
15456
15457   /* wait for reply */
15458   W (ret);
15459   return ret;
15460 }
15461
15462 static int
15463 api_show_one_pitr (vat_main_t * vam)
15464 {
15465   vl_api_show_one_pitr_t *mp;
15466   int ret;
15467
15468   if (!vam->json_output)
15469     {
15470       print (vam->ofp, "%=20s", "lisp status:");
15471     }
15472
15473   M (SHOW_ONE_PITR, mp);
15474   /* send it... */
15475   S (mp);
15476
15477   /* Wait for a reply... */
15478   W (ret);
15479   return ret;
15480 }
15481
15482 #define api_show_lisp_pitr api_show_one_pitr
15483
15484 static int
15485 api_one_use_petr (vat_main_t * vam)
15486 {
15487   unformat_input_t *input = vam->input;
15488   vl_api_one_use_petr_t *mp;
15489   u8 is_add = 0;
15490   ip_address_t ip;
15491   int ret;
15492
15493   memset (&ip, 0, sizeof (ip));
15494
15495   /* Parse args required to build the message */
15496   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15497     {
15498       if (unformat (input, "disable"))
15499         is_add = 0;
15500       else
15501         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
15502         {
15503           is_add = 1;
15504           ip_addr_version (&ip) = IP4;
15505         }
15506       else
15507         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
15508         {
15509           is_add = 1;
15510           ip_addr_version (&ip) = IP6;
15511         }
15512       else
15513         {
15514           errmsg ("parse error '%U'", format_unformat_error, input);
15515           return -99;
15516         }
15517     }
15518
15519   M (ONE_USE_PETR, mp);
15520
15521   mp->is_add = is_add;
15522   if (is_add)
15523     {
15524       mp->is_ip4 = ip_addr_version (&ip) == IP4 ? 1 : 0;
15525       if (mp->is_ip4)
15526         clib_memcpy (mp->address, &ip, 4);
15527       else
15528         clib_memcpy (mp->address, &ip, 16);
15529     }
15530
15531   /* send */
15532   S (mp);
15533
15534   /* wait for reply */
15535   W (ret);
15536   return ret;
15537 }
15538
15539 #define api_lisp_use_petr api_one_use_petr
15540
15541 static int
15542 api_show_one_nsh_mapping (vat_main_t * vam)
15543 {
15544   vl_api_show_one_use_petr_t *mp;
15545   int ret;
15546
15547   if (!vam->json_output)
15548     {
15549       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
15550     }
15551
15552   M (SHOW_ONE_NSH_MAPPING, mp);
15553   /* send it... */
15554   S (mp);
15555
15556   /* Wait for a reply... */
15557   W (ret);
15558   return ret;
15559 }
15560
15561 static int
15562 api_show_one_use_petr (vat_main_t * vam)
15563 {
15564   vl_api_show_one_use_petr_t *mp;
15565   int ret;
15566
15567   if (!vam->json_output)
15568     {
15569       print (vam->ofp, "%=20s", "Proxy-ETR status:");
15570     }
15571
15572   M (SHOW_ONE_USE_PETR, mp);
15573   /* send it... */
15574   S (mp);
15575
15576   /* Wait for a reply... */
15577   W (ret);
15578   return ret;
15579 }
15580
15581 #define api_show_lisp_use_petr api_show_one_use_petr
15582
15583 /**
15584  * Add/delete mapping between vni and vrf
15585  */
15586 static int
15587 api_one_eid_table_add_del_map (vat_main_t * vam)
15588 {
15589   unformat_input_t *input = vam->input;
15590   vl_api_one_eid_table_add_del_map_t *mp;
15591   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
15592   u32 vni, vrf, bd_index;
15593   int ret;
15594
15595   /* Parse args required to build the message */
15596   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15597     {
15598       if (unformat (input, "del"))
15599         is_add = 0;
15600       else if (unformat (input, "vrf %d", &vrf))
15601         vrf_set = 1;
15602       else if (unformat (input, "bd_index %d", &bd_index))
15603         bd_index_set = 1;
15604       else if (unformat (input, "vni %d", &vni))
15605         vni_set = 1;
15606       else
15607         break;
15608     }
15609
15610   if (!vni_set || (!vrf_set && !bd_index_set))
15611     {
15612       errmsg ("missing arguments!");
15613       return -99;
15614     }
15615
15616   if (vrf_set && bd_index_set)
15617     {
15618       errmsg ("error: both vrf and bd entered!");
15619       return -99;
15620     }
15621
15622   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
15623
15624   mp->is_add = is_add;
15625   mp->vni = htonl (vni);
15626   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
15627   mp->is_l2 = bd_index_set;
15628
15629   /* send */
15630   S (mp);
15631
15632   /* wait for reply */
15633   W (ret);
15634   return ret;
15635 }
15636
15637 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
15638
15639 uword
15640 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
15641 {
15642   u32 *action = va_arg (*args, u32 *);
15643   u8 *s = 0;
15644
15645   if (unformat (input, "%s", &s))
15646     {
15647       if (!strcmp ((char *) s, "no-action"))
15648         action[0] = 0;
15649       else if (!strcmp ((char *) s, "natively-forward"))
15650         action[0] = 1;
15651       else if (!strcmp ((char *) s, "send-map-request"))
15652         action[0] = 2;
15653       else if (!strcmp ((char *) s, "drop"))
15654         action[0] = 3;
15655       else
15656         {
15657           clib_warning ("invalid action: '%s'", s);
15658           action[0] = 3;
15659         }
15660     }
15661   else
15662     return 0;
15663
15664   vec_free (s);
15665   return 1;
15666 }
15667
15668 /**
15669  * Add/del remote mapping to/from ONE control plane
15670  *
15671  * @param vam vpp API test context
15672  * @return return code
15673  */
15674 static int
15675 api_one_add_del_remote_mapping (vat_main_t * vam)
15676 {
15677   unformat_input_t *input = vam->input;
15678   vl_api_one_add_del_remote_mapping_t *mp;
15679   u32 vni = 0;
15680   lisp_eid_vat_t _eid, *eid = &_eid;
15681   lisp_eid_vat_t _seid, *seid = &_seid;
15682   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
15683   u32 action = ~0, p, w, data_len;
15684   ip4_address_t rloc4;
15685   ip6_address_t rloc6;
15686   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
15687   int ret;
15688
15689   memset (&rloc, 0, sizeof (rloc));
15690
15691   /* Parse args required to build the message */
15692   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15693     {
15694       if (unformat (input, "del-all"))
15695         {
15696           del_all = 1;
15697         }
15698       else if (unformat (input, "del"))
15699         {
15700           is_add = 0;
15701         }
15702       else if (unformat (input, "add"))
15703         {
15704           is_add = 1;
15705         }
15706       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
15707         {
15708           eid_set = 1;
15709         }
15710       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
15711         {
15712           seid_set = 1;
15713         }
15714       else if (unformat (input, "vni %d", &vni))
15715         {
15716           ;
15717         }
15718       else if (unformat (input, "p %d w %d", &p, &w))
15719         {
15720           if (!curr_rloc)
15721             {
15722               errmsg ("No RLOC configured for setting priority/weight!");
15723               return -99;
15724             }
15725           curr_rloc->priority = p;
15726           curr_rloc->weight = w;
15727         }
15728       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
15729         {
15730           rloc.is_ip4 = 1;
15731           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
15732           vec_add1 (rlocs, rloc);
15733           curr_rloc = &rlocs[vec_len (rlocs) - 1];
15734         }
15735       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
15736         {
15737           rloc.is_ip4 = 0;
15738           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
15739           vec_add1 (rlocs, rloc);
15740           curr_rloc = &rlocs[vec_len (rlocs) - 1];
15741         }
15742       else if (unformat (input, "action %U",
15743                          unformat_negative_mapping_action, &action))
15744         {
15745           ;
15746         }
15747       else
15748         {
15749           clib_warning ("parse error '%U'", format_unformat_error, input);
15750           return -99;
15751         }
15752     }
15753
15754   if (0 == eid_set)
15755     {
15756       errmsg ("missing params!");
15757       return -99;
15758     }
15759
15760   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
15761     {
15762       errmsg ("no action set for negative map-reply!");
15763       return -99;
15764     }
15765
15766   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
15767
15768   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
15769   mp->is_add = is_add;
15770   mp->vni = htonl (vni);
15771   mp->action = (u8) action;
15772   mp->is_src_dst = seid_set;
15773   mp->eid_len = eid->len;
15774   mp->seid_len = seid->len;
15775   mp->del_all = del_all;
15776   mp->eid_type = eid->type;
15777   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
15778   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
15779
15780   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
15781   clib_memcpy (mp->rlocs, rlocs, data_len);
15782   vec_free (rlocs);
15783
15784   /* send it... */
15785   S (mp);
15786
15787   /* Wait for a reply... */
15788   W (ret);
15789   return ret;
15790 }
15791
15792 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
15793
15794 /**
15795  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
15796  * forwarding entries in data-plane accordingly.
15797  *
15798  * @param vam vpp API test context
15799  * @return return code
15800  */
15801 static int
15802 api_one_add_del_adjacency (vat_main_t * vam)
15803 {
15804   unformat_input_t *input = vam->input;
15805   vl_api_one_add_del_adjacency_t *mp;
15806   u32 vni = 0;
15807   ip4_address_t leid4, reid4;
15808   ip6_address_t leid6, reid6;
15809   u8 reid_mac[6] = { 0 };
15810   u8 leid_mac[6] = { 0 };
15811   u8 reid_type, leid_type;
15812   u32 leid_len = 0, reid_len = 0, len;
15813   u8 is_add = 1;
15814   int ret;
15815
15816   leid_type = reid_type = (u8) ~ 0;
15817
15818   /* Parse args required to build the message */
15819   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15820     {
15821       if (unformat (input, "del"))
15822         {
15823           is_add = 0;
15824         }
15825       else if (unformat (input, "add"))
15826         {
15827           is_add = 1;
15828         }
15829       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
15830                          &reid4, &len))
15831         {
15832           reid_type = 0;        /* ipv4 */
15833           reid_len = len;
15834         }
15835       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
15836                          &reid6, &len))
15837         {
15838           reid_type = 1;        /* ipv6 */
15839           reid_len = len;
15840         }
15841       else if (unformat (input, "reid %U", unformat_ethernet_address,
15842                          reid_mac))
15843         {
15844           reid_type = 2;        /* mac */
15845         }
15846       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
15847                          &leid4, &len))
15848         {
15849           leid_type = 0;        /* ipv4 */
15850           leid_len = len;
15851         }
15852       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
15853                          &leid6, &len))
15854         {
15855           leid_type = 1;        /* ipv6 */
15856           leid_len = len;
15857         }
15858       else if (unformat (input, "leid %U", unformat_ethernet_address,
15859                          leid_mac))
15860         {
15861           leid_type = 2;        /* mac */
15862         }
15863       else if (unformat (input, "vni %d", &vni))
15864         {
15865           ;
15866         }
15867       else
15868         {
15869           errmsg ("parse error '%U'", format_unformat_error, input);
15870           return -99;
15871         }
15872     }
15873
15874   if ((u8) ~ 0 == reid_type)
15875     {
15876       errmsg ("missing params!");
15877       return -99;
15878     }
15879
15880   if (leid_type != reid_type)
15881     {
15882       errmsg ("remote and local EIDs are of different types!");
15883       return -99;
15884     }
15885
15886   M (ONE_ADD_DEL_ADJACENCY, mp);
15887   mp->is_add = is_add;
15888   mp->vni = htonl (vni);
15889   mp->leid_len = leid_len;
15890   mp->reid_len = reid_len;
15891   mp->eid_type = reid_type;
15892
15893   switch (mp->eid_type)
15894     {
15895     case 0:
15896       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
15897       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
15898       break;
15899     case 1:
15900       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
15901       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
15902       break;
15903     case 2:
15904       clib_memcpy (mp->leid, leid_mac, 6);
15905       clib_memcpy (mp->reid, reid_mac, 6);
15906       break;
15907     default:
15908       errmsg ("unknown EID type %d!", mp->eid_type);
15909       return 0;
15910     }
15911
15912   /* send it... */
15913   S (mp);
15914
15915   /* Wait for a reply... */
15916   W (ret);
15917   return ret;
15918 }
15919
15920 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
15921
15922 uword
15923 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
15924 {
15925   u32 *mode = va_arg (*args, u32 *);
15926
15927   if (unformat (input, "lisp"))
15928     *mode = 0;
15929   else if (unformat (input, "vxlan"))
15930     *mode = 1;
15931   else
15932     return 0;
15933
15934   return 1;
15935 }
15936
15937 static int
15938 api_gpe_get_encap_mode (vat_main_t * vam)
15939 {
15940   vl_api_gpe_get_encap_mode_t *mp;
15941   int ret;
15942
15943   /* Construct the API message */
15944   M (GPE_GET_ENCAP_MODE, mp);
15945
15946   /* send it... */
15947   S (mp);
15948
15949   /* Wait for a reply... */
15950   W (ret);
15951   return ret;
15952 }
15953
15954 static int
15955 api_gpe_set_encap_mode (vat_main_t * vam)
15956 {
15957   unformat_input_t *input = vam->input;
15958   vl_api_gpe_set_encap_mode_t *mp;
15959   int ret;
15960   u32 mode = 0;
15961
15962   /* Parse args required to build the message */
15963   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15964     {
15965       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
15966         ;
15967       else
15968         break;
15969     }
15970
15971   /* Construct the API message */
15972   M (GPE_SET_ENCAP_MODE, mp);
15973
15974   mp->mode = mode;
15975
15976   /* send it... */
15977   S (mp);
15978
15979   /* Wait for a reply... */
15980   W (ret);
15981   return ret;
15982 }
15983
15984 static int
15985 api_lisp_gpe_add_del_iface (vat_main_t * vam)
15986 {
15987   unformat_input_t *input = vam->input;
15988   vl_api_gpe_add_del_iface_t *mp;
15989   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
15990   u32 dp_table = 0, vni = 0;
15991   int ret;
15992
15993   /* Parse args required to build the message */
15994   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15995     {
15996       if (unformat (input, "up"))
15997         {
15998           action_set = 1;
15999           is_add = 1;
16000         }
16001       else if (unformat (input, "down"))
16002         {
16003           action_set = 1;
16004           is_add = 0;
16005         }
16006       else if (unformat (input, "table_id %d", &dp_table))
16007         {
16008           dp_table_set = 1;
16009         }
16010       else if (unformat (input, "bd_id %d", &dp_table))
16011         {
16012           dp_table_set = 1;
16013           is_l2 = 1;
16014         }
16015       else if (unformat (input, "vni %d", &vni))
16016         {
16017           vni_set = 1;
16018         }
16019       else
16020         break;
16021     }
16022
16023   if (action_set == 0)
16024     {
16025       errmsg ("Action not set");
16026       return -99;
16027     }
16028   if (dp_table_set == 0 || vni_set == 0)
16029     {
16030       errmsg ("vni and dp_table must be set");
16031       return -99;
16032     }
16033
16034   /* Construct the API message */
16035   M (GPE_ADD_DEL_IFACE, mp);
16036
16037   mp->is_add = is_add;
16038   mp->dp_table = clib_host_to_net_u32 (dp_table);
16039   mp->is_l2 = is_l2;
16040   mp->vni = clib_host_to_net_u32 (vni);
16041
16042   /* send it... */
16043   S (mp);
16044
16045   /* Wait for a reply... */
16046   W (ret);
16047   return ret;
16048 }
16049
16050 /**
16051  * Add/del map request itr rlocs from ONE control plane and updates
16052  *
16053  * @param vam vpp API test context
16054  * @return return code
16055  */
16056 static int
16057 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
16058 {
16059   unformat_input_t *input = vam->input;
16060   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
16061   u8 *locator_set_name = 0;
16062   u8 locator_set_name_set = 0;
16063   u8 is_add = 1;
16064   int ret;
16065
16066   /* Parse args required to build the message */
16067   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16068     {
16069       if (unformat (input, "del"))
16070         {
16071           is_add = 0;
16072         }
16073       else if (unformat (input, "%_%v%_", &locator_set_name))
16074         {
16075           locator_set_name_set = 1;
16076         }
16077       else
16078         {
16079           clib_warning ("parse error '%U'", format_unformat_error, input);
16080           return -99;
16081         }
16082     }
16083
16084   if (is_add && !locator_set_name_set)
16085     {
16086       errmsg ("itr-rloc is not set!");
16087       return -99;
16088     }
16089
16090   if (is_add && vec_len (locator_set_name) > 64)
16091     {
16092       errmsg ("itr-rloc locator-set name too long");
16093       vec_free (locator_set_name);
16094       return -99;
16095     }
16096
16097   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
16098   mp->is_add = is_add;
16099   if (is_add)
16100     {
16101       clib_memcpy (mp->locator_set_name, locator_set_name,
16102                    vec_len (locator_set_name));
16103     }
16104   else
16105     {
16106       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
16107     }
16108   vec_free (locator_set_name);
16109
16110   /* send it... */
16111   S (mp);
16112
16113   /* Wait for a reply... */
16114   W (ret);
16115   return ret;
16116 }
16117
16118 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
16119
16120 static int
16121 api_one_locator_dump (vat_main_t * vam)
16122 {
16123   unformat_input_t *input = vam->input;
16124   vl_api_one_locator_dump_t *mp;
16125   vl_api_control_ping_t *mp_ping;
16126   u8 is_index_set = 0, is_name_set = 0;
16127   u8 *ls_name = 0;
16128   u32 ls_index = ~0;
16129   int ret;
16130
16131   /* Parse args required to build the message */
16132   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16133     {
16134       if (unformat (input, "ls_name %_%v%_", &ls_name))
16135         {
16136           is_name_set = 1;
16137         }
16138       else if (unformat (input, "ls_index %d", &ls_index))
16139         {
16140           is_index_set = 1;
16141         }
16142       else
16143         {
16144           errmsg ("parse error '%U'", format_unformat_error, input);
16145           return -99;
16146         }
16147     }
16148
16149   if (!is_index_set && !is_name_set)
16150     {
16151       errmsg ("error: expected one of index or name!");
16152       return -99;
16153     }
16154
16155   if (is_index_set && is_name_set)
16156     {
16157       errmsg ("error: only one param expected!");
16158       return -99;
16159     }
16160
16161   if (vec_len (ls_name) > 62)
16162     {
16163       errmsg ("error: locator set name too long!");
16164       return -99;
16165     }
16166
16167   if (!vam->json_output)
16168     {
16169       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
16170     }
16171
16172   M (ONE_LOCATOR_DUMP, mp);
16173   mp->is_index_set = is_index_set;
16174
16175   if (is_index_set)
16176     mp->ls_index = clib_host_to_net_u32 (ls_index);
16177   else
16178     {
16179       vec_add1 (ls_name, 0);
16180       strncpy ((char *) mp->ls_name, (char *) ls_name,
16181                sizeof (mp->ls_name) - 1);
16182     }
16183
16184   /* send it... */
16185   S (mp);
16186
16187   /* Use a control ping for synchronization */
16188   M (CONTROL_PING, mp_ping);
16189   S (mp_ping);
16190
16191   /* Wait for a reply... */
16192   W (ret);
16193   return ret;
16194 }
16195
16196 #define api_lisp_locator_dump api_one_locator_dump
16197
16198 static int
16199 api_one_locator_set_dump (vat_main_t * vam)
16200 {
16201   vl_api_one_locator_set_dump_t *mp;
16202   vl_api_control_ping_t *mp_ping;
16203   unformat_input_t *input = vam->input;
16204   u8 filter = 0;
16205   int ret;
16206
16207   /* Parse args required to build the message */
16208   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16209     {
16210       if (unformat (input, "local"))
16211         {
16212           filter = 1;
16213         }
16214       else if (unformat (input, "remote"))
16215         {
16216           filter = 2;
16217         }
16218       else
16219         {
16220           errmsg ("parse error '%U'", format_unformat_error, input);
16221           return -99;
16222         }
16223     }
16224
16225   if (!vam->json_output)
16226     {
16227       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
16228     }
16229
16230   M (ONE_LOCATOR_SET_DUMP, mp);
16231
16232   mp->filter = filter;
16233
16234   /* send it... */
16235   S (mp);
16236
16237   /* Use a control ping for synchronization */
16238   M (CONTROL_PING, mp_ping);
16239   S (mp_ping);
16240
16241   /* Wait for a reply... */
16242   W (ret);
16243   return ret;
16244 }
16245
16246 #define api_lisp_locator_set_dump api_one_locator_set_dump
16247
16248 static int
16249 api_one_eid_table_map_dump (vat_main_t * vam)
16250 {
16251   u8 is_l2 = 0;
16252   u8 mode_set = 0;
16253   unformat_input_t *input = vam->input;
16254   vl_api_one_eid_table_map_dump_t *mp;
16255   vl_api_control_ping_t *mp_ping;
16256   int ret;
16257
16258   /* Parse args required to build the message */
16259   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16260     {
16261       if (unformat (input, "l2"))
16262         {
16263           is_l2 = 1;
16264           mode_set = 1;
16265         }
16266       else if (unformat (input, "l3"))
16267         {
16268           is_l2 = 0;
16269           mode_set = 1;
16270         }
16271       else
16272         {
16273           errmsg ("parse error '%U'", format_unformat_error, input);
16274           return -99;
16275         }
16276     }
16277
16278   if (!mode_set)
16279     {
16280       errmsg ("expected one of 'l2' or 'l3' parameter!");
16281       return -99;
16282     }
16283
16284   if (!vam->json_output)
16285     {
16286       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
16287     }
16288
16289   M (ONE_EID_TABLE_MAP_DUMP, mp);
16290   mp->is_l2 = is_l2;
16291
16292   /* send it... */
16293   S (mp);
16294
16295   /* Use a control ping for synchronization */
16296   M (CONTROL_PING, mp_ping);
16297   S (mp_ping);
16298
16299   /* Wait for a reply... */
16300   W (ret);
16301   return ret;
16302 }
16303
16304 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
16305
16306 static int
16307 api_one_eid_table_vni_dump (vat_main_t * vam)
16308 {
16309   vl_api_one_eid_table_vni_dump_t *mp;
16310   vl_api_control_ping_t *mp_ping;
16311   int ret;
16312
16313   if (!vam->json_output)
16314     {
16315       print (vam->ofp, "VNI");
16316     }
16317
16318   M (ONE_EID_TABLE_VNI_DUMP, mp);
16319
16320   /* send it... */
16321   S (mp);
16322
16323   /* Use a control ping for synchronization */
16324   M (CONTROL_PING, mp_ping);
16325   S (mp_ping);
16326
16327   /* Wait for a reply... */
16328   W (ret);
16329   return ret;
16330 }
16331
16332 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
16333
16334 static int
16335 api_one_eid_table_dump (vat_main_t * vam)
16336 {
16337   unformat_input_t *i = vam->input;
16338   vl_api_one_eid_table_dump_t *mp;
16339   vl_api_control_ping_t *mp_ping;
16340   struct in_addr ip4;
16341   struct in6_addr ip6;
16342   u8 mac[6];
16343   u8 eid_type = ~0, eid_set = 0;
16344   u32 prefix_length = ~0, t, vni = 0;
16345   u8 filter = 0;
16346   int ret;
16347   lisp_nsh_api_t nsh;
16348
16349   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16350     {
16351       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
16352         {
16353           eid_set = 1;
16354           eid_type = 0;
16355           prefix_length = t;
16356         }
16357       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
16358         {
16359           eid_set = 1;
16360           eid_type = 1;
16361           prefix_length = t;
16362         }
16363       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
16364         {
16365           eid_set = 1;
16366           eid_type = 2;
16367         }
16368       else if (unformat (i, "eid %U", unformat_nsh_address, &nsh))
16369         {
16370           eid_set = 1;
16371           eid_type = 3;
16372         }
16373       else if (unformat (i, "vni %d", &t))
16374         {
16375           vni = t;
16376         }
16377       else if (unformat (i, "local"))
16378         {
16379           filter = 1;
16380         }
16381       else if (unformat (i, "remote"))
16382         {
16383           filter = 2;
16384         }
16385       else
16386         {
16387           errmsg ("parse error '%U'", format_unformat_error, i);
16388           return -99;
16389         }
16390     }
16391
16392   if (!vam->json_output)
16393     {
16394       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
16395              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
16396     }
16397
16398   M (ONE_EID_TABLE_DUMP, mp);
16399
16400   mp->filter = filter;
16401   if (eid_set)
16402     {
16403       mp->eid_set = 1;
16404       mp->vni = htonl (vni);
16405       mp->eid_type = eid_type;
16406       switch (eid_type)
16407         {
16408         case 0:
16409           mp->prefix_length = prefix_length;
16410           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
16411           break;
16412         case 1:
16413           mp->prefix_length = prefix_length;
16414           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
16415           break;
16416         case 2:
16417           clib_memcpy (mp->eid, mac, sizeof (mac));
16418           break;
16419         case 3:
16420           clib_memcpy (mp->eid, &nsh, sizeof (nsh));
16421           break;
16422         default:
16423           errmsg ("unknown EID type %d!", eid_type);
16424           return -99;
16425         }
16426     }
16427
16428   /* send it... */
16429   S (mp);
16430
16431   /* Use a control ping for synchronization */
16432   M (CONTROL_PING, mp_ping);
16433   S (mp_ping);
16434
16435   /* Wait for a reply... */
16436   W (ret);
16437   return ret;
16438 }
16439
16440 #define api_lisp_eid_table_dump api_one_eid_table_dump
16441
16442 static int
16443 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
16444 {
16445   unformat_input_t *i = vam->input;
16446   vl_api_gpe_fwd_entries_get_t *mp;
16447   u8 vni_set = 0;
16448   u32 vni = ~0;
16449   int ret;
16450
16451   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16452     {
16453       if (unformat (i, "vni %d", &vni))
16454         {
16455           vni_set = 1;
16456         }
16457       else
16458         {
16459           errmsg ("parse error '%U'", format_unformat_error, i);
16460           return -99;
16461         }
16462     }
16463
16464   if (!vni_set)
16465     {
16466       errmsg ("vni not set!");
16467       return -99;
16468     }
16469
16470   if (!vam->json_output)
16471     {
16472       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
16473              "leid", "reid");
16474     }
16475
16476   M (GPE_FWD_ENTRIES_GET, mp);
16477   mp->vni = clib_host_to_net_u32 (vni);
16478
16479   /* send it... */
16480   S (mp);
16481
16482   /* Wait for a reply... */
16483   W (ret);
16484   return ret;
16485 }
16486
16487 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
16488 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
16489 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
16490 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
16491 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
16492 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
16493 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
16494 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
16495
16496 static int
16497 api_one_adjacencies_get (vat_main_t * vam)
16498 {
16499   unformat_input_t *i = vam->input;
16500   vl_api_one_adjacencies_get_t *mp;
16501   u8 vni_set = 0;
16502   u32 vni = ~0;
16503   int ret;
16504
16505   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16506     {
16507       if (unformat (i, "vni %d", &vni))
16508         {
16509           vni_set = 1;
16510         }
16511       else
16512         {
16513           errmsg ("parse error '%U'", format_unformat_error, i);
16514           return -99;
16515         }
16516     }
16517
16518   if (!vni_set)
16519     {
16520       errmsg ("vni not set!");
16521       return -99;
16522     }
16523
16524   if (!vam->json_output)
16525     {
16526       print (vam->ofp, "%s %40s", "leid", "reid");
16527     }
16528
16529   M (ONE_ADJACENCIES_GET, mp);
16530   mp->vni = clib_host_to_net_u32 (vni);
16531
16532   /* send it... */
16533   S (mp);
16534
16535   /* Wait for a reply... */
16536   W (ret);
16537   return ret;
16538 }
16539
16540 #define api_lisp_adjacencies_get api_one_adjacencies_get
16541
16542 static int
16543 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
16544 {
16545   unformat_input_t *i = vam->input;
16546   vl_api_gpe_native_fwd_rpaths_get_t *mp;
16547   int ret;
16548   u8 ip_family_set = 0, is_ip4 = 1;
16549
16550   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16551     {
16552       if (unformat (i, "ip4"))
16553         {
16554           ip_family_set = 1;
16555           is_ip4 = 1;
16556         }
16557       else if (unformat (i, "ip6"))
16558         {
16559           ip_family_set = 1;
16560           is_ip4 = 0;
16561         }
16562       else
16563         {
16564           errmsg ("parse error '%U'", format_unformat_error, i);
16565           return -99;
16566         }
16567     }
16568
16569   if (!ip_family_set)
16570     {
16571       errmsg ("ip family not set!");
16572       return -99;
16573     }
16574
16575   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
16576   mp->is_ip4 = is_ip4;
16577
16578   /* send it... */
16579   S (mp);
16580
16581   /* Wait for a reply... */
16582   W (ret);
16583   return ret;
16584 }
16585
16586 static int
16587 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
16588 {
16589   vl_api_gpe_fwd_entry_vnis_get_t *mp;
16590   int ret;
16591
16592   if (!vam->json_output)
16593     {
16594       print (vam->ofp, "VNIs");
16595     }
16596
16597   M (GPE_FWD_ENTRY_VNIS_GET, mp);
16598
16599   /* send it... */
16600   S (mp);
16601
16602   /* Wait for a reply... */
16603   W (ret);
16604   return ret;
16605 }
16606
16607 static int
16608 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
16609 {
16610   unformat_input_t *i = vam->input;
16611   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
16612   int ret = 0;
16613   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
16614   struct in_addr ip4;
16615   struct in6_addr ip6;
16616   u32 table_id = 0, nh_sw_if_index = ~0;
16617
16618   memset (&ip4, 0, sizeof (ip4));
16619   memset (&ip6, 0, sizeof (ip6));
16620
16621   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16622     {
16623       if (unformat (i, "del"))
16624         is_add = 0;
16625       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
16626                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
16627         {
16628           ip_set = 1;
16629           is_ip4 = 1;
16630         }
16631       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
16632                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
16633         {
16634           ip_set = 1;
16635           is_ip4 = 0;
16636         }
16637       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
16638         {
16639           ip_set = 1;
16640           is_ip4 = 1;
16641           nh_sw_if_index = ~0;
16642         }
16643       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
16644         {
16645           ip_set = 1;
16646           is_ip4 = 0;
16647           nh_sw_if_index = ~0;
16648         }
16649       else if (unformat (i, "table %d", &table_id))
16650         ;
16651       else
16652         {
16653           errmsg ("parse error '%U'", format_unformat_error, i);
16654           return -99;
16655         }
16656     }
16657
16658   if (!ip_set)
16659     {
16660       errmsg ("nh addr not set!");
16661       return -99;
16662     }
16663
16664   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
16665   mp->is_add = is_add;
16666   mp->table_id = clib_host_to_net_u32 (table_id);
16667   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
16668   mp->is_ip4 = is_ip4;
16669   if (is_ip4)
16670     clib_memcpy (mp->nh_addr, &ip4, sizeof (ip4));
16671   else
16672     clib_memcpy (mp->nh_addr, &ip6, sizeof (ip6));
16673
16674   /* send it... */
16675   S (mp);
16676
16677   /* Wait for a reply... */
16678   W (ret);
16679   return ret;
16680 }
16681
16682 static int
16683 api_one_map_server_dump (vat_main_t * vam)
16684 {
16685   vl_api_one_map_server_dump_t *mp;
16686   vl_api_control_ping_t *mp_ping;
16687   int ret;
16688
16689   if (!vam->json_output)
16690     {
16691       print (vam->ofp, "%=20s", "Map server");
16692     }
16693
16694   M (ONE_MAP_SERVER_DUMP, mp);
16695   /* send it... */
16696   S (mp);
16697
16698   /* Use a control ping for synchronization */
16699   M (CONTROL_PING, mp_ping);
16700   S (mp_ping);
16701
16702   /* Wait for a reply... */
16703   W (ret);
16704   return ret;
16705 }
16706
16707 #define api_lisp_map_server_dump api_one_map_server_dump
16708
16709 static int
16710 api_one_map_resolver_dump (vat_main_t * vam)
16711 {
16712   vl_api_one_map_resolver_dump_t *mp;
16713   vl_api_control_ping_t *mp_ping;
16714   int ret;
16715
16716   if (!vam->json_output)
16717     {
16718       print (vam->ofp, "%=20s", "Map resolver");
16719     }
16720
16721   M (ONE_MAP_RESOLVER_DUMP, mp);
16722   /* send it... */
16723   S (mp);
16724
16725   /* Use a control ping for synchronization */
16726   M (CONTROL_PING, mp_ping);
16727   S (mp_ping);
16728
16729   /* Wait for a reply... */
16730   W (ret);
16731   return ret;
16732 }
16733
16734 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
16735
16736 static int
16737 api_one_stats_flush (vat_main_t * vam)
16738 {
16739   vl_api_one_stats_flush_t *mp;
16740   int ret = 0;
16741
16742   M (ONE_STATS_FLUSH, mp);
16743   S (mp);
16744   W (ret);
16745   return ret;
16746 }
16747
16748 static int
16749 api_one_stats_dump (vat_main_t * vam)
16750 {
16751   vl_api_one_stats_dump_t *mp;
16752   vl_api_control_ping_t *mp_ping;
16753   int ret;
16754
16755   M (ONE_STATS_DUMP, mp);
16756   /* send it... */
16757   S (mp);
16758
16759   /* Use a control ping for synchronization */
16760   M (CONTROL_PING, mp_ping);
16761   S (mp_ping);
16762
16763   /* Wait for a reply... */
16764   W (ret);
16765   return ret;
16766 }
16767
16768 static int
16769 api_show_one_status (vat_main_t * vam)
16770 {
16771   vl_api_show_one_status_t *mp;
16772   int ret;
16773
16774   if (!vam->json_output)
16775     {
16776       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
16777     }
16778
16779   M (SHOW_ONE_STATUS, mp);
16780   /* send it... */
16781   S (mp);
16782   /* Wait for a reply... */
16783   W (ret);
16784   return ret;
16785 }
16786
16787 #define api_show_lisp_status api_show_one_status
16788
16789 static int
16790 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
16791 {
16792   vl_api_gpe_fwd_entry_path_dump_t *mp;
16793   vl_api_control_ping_t *mp_ping;
16794   unformat_input_t *i = vam->input;
16795   u32 fwd_entry_index = ~0;
16796   int ret;
16797
16798   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16799     {
16800       if (unformat (i, "index %d", &fwd_entry_index))
16801         ;
16802       else
16803         break;
16804     }
16805
16806   if (~0 == fwd_entry_index)
16807     {
16808       errmsg ("no index specified!");
16809       return -99;
16810     }
16811
16812   if (!vam->json_output)
16813     {
16814       print (vam->ofp, "first line");
16815     }
16816
16817   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
16818
16819   /* send it... */
16820   S (mp);
16821   /* Use a control ping for synchronization */
16822   M (CONTROL_PING, mp_ping);
16823   S (mp_ping);
16824
16825   /* Wait for a reply... */
16826   W (ret);
16827   return ret;
16828 }
16829
16830 static int
16831 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
16832 {
16833   vl_api_one_get_map_request_itr_rlocs_t *mp;
16834   int ret;
16835
16836   if (!vam->json_output)
16837     {
16838       print (vam->ofp, "%=20s", "itr-rlocs:");
16839     }
16840
16841   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
16842   /* send it... */
16843   S (mp);
16844   /* Wait for a reply... */
16845   W (ret);
16846   return ret;
16847 }
16848
16849 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
16850
16851 static int
16852 api_af_packet_create (vat_main_t * vam)
16853 {
16854   unformat_input_t *i = vam->input;
16855   vl_api_af_packet_create_t *mp;
16856   u8 *host_if_name = 0;
16857   u8 hw_addr[6];
16858   u8 random_hw_addr = 1;
16859   int ret;
16860
16861   memset (hw_addr, 0, sizeof (hw_addr));
16862
16863   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16864     {
16865       if (unformat (i, "name %s", &host_if_name))
16866         vec_add1 (host_if_name, 0);
16867       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
16868         random_hw_addr = 0;
16869       else
16870         break;
16871     }
16872
16873   if (!vec_len (host_if_name))
16874     {
16875       errmsg ("host-interface name must be specified");
16876       return -99;
16877     }
16878
16879   if (vec_len (host_if_name) > 64)
16880     {
16881       errmsg ("host-interface name too long");
16882       return -99;
16883     }
16884
16885   M (AF_PACKET_CREATE, mp);
16886
16887   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
16888   clib_memcpy (mp->hw_addr, hw_addr, 6);
16889   mp->use_random_hw_addr = random_hw_addr;
16890   vec_free (host_if_name);
16891
16892   S (mp);
16893
16894   /* *INDENT-OFF* */
16895   W2 (ret,
16896       ({
16897         if (ret == 0)
16898           fprintf (vam->ofp ? vam->ofp : stderr,
16899                    " new sw_if_index = %d\n", vam->sw_if_index);
16900       }));
16901   /* *INDENT-ON* */
16902   return ret;
16903 }
16904
16905 static int
16906 api_af_packet_delete (vat_main_t * vam)
16907 {
16908   unformat_input_t *i = vam->input;
16909   vl_api_af_packet_delete_t *mp;
16910   u8 *host_if_name = 0;
16911   int ret;
16912
16913   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16914     {
16915       if (unformat (i, "name %s", &host_if_name))
16916         vec_add1 (host_if_name, 0);
16917       else
16918         break;
16919     }
16920
16921   if (!vec_len (host_if_name))
16922     {
16923       errmsg ("host-interface name must be specified");
16924       return -99;
16925     }
16926
16927   if (vec_len (host_if_name) > 64)
16928     {
16929       errmsg ("host-interface name too long");
16930       return -99;
16931     }
16932
16933   M (AF_PACKET_DELETE, mp);
16934
16935   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
16936   vec_free (host_if_name);
16937
16938   S (mp);
16939   W (ret);
16940   return ret;
16941 }
16942
16943 static int
16944 api_policer_add_del (vat_main_t * vam)
16945 {
16946   unformat_input_t *i = vam->input;
16947   vl_api_policer_add_del_t *mp;
16948   u8 is_add = 1;
16949   u8 *name = 0;
16950   u32 cir = 0;
16951   u32 eir = 0;
16952   u64 cb = 0;
16953   u64 eb = 0;
16954   u8 rate_type = 0;
16955   u8 round_type = 0;
16956   u8 type = 0;
16957   u8 color_aware = 0;
16958   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
16959   int ret;
16960
16961   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
16962   conform_action.dscp = 0;
16963   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
16964   exceed_action.dscp = 0;
16965   violate_action.action_type = SSE2_QOS_ACTION_DROP;
16966   violate_action.dscp = 0;
16967
16968   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16969     {
16970       if (unformat (i, "del"))
16971         is_add = 0;
16972       else if (unformat (i, "name %s", &name))
16973         vec_add1 (name, 0);
16974       else if (unformat (i, "cir %u", &cir))
16975         ;
16976       else if (unformat (i, "eir %u", &eir))
16977         ;
16978       else if (unformat (i, "cb %u", &cb))
16979         ;
16980       else if (unformat (i, "eb %u", &eb))
16981         ;
16982       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
16983                          &rate_type))
16984         ;
16985       else if (unformat (i, "round_type %U", unformat_policer_round_type,
16986                          &round_type))
16987         ;
16988       else if (unformat (i, "type %U", unformat_policer_type, &type))
16989         ;
16990       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
16991                          &conform_action))
16992         ;
16993       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
16994                          &exceed_action))
16995         ;
16996       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
16997                          &violate_action))
16998         ;
16999       else if (unformat (i, "color-aware"))
17000         color_aware = 1;
17001       else
17002         break;
17003     }
17004
17005   if (!vec_len (name))
17006     {
17007       errmsg ("policer name must be specified");
17008       return -99;
17009     }
17010
17011   if (vec_len (name) > 64)
17012     {
17013       errmsg ("policer name too long");
17014       return -99;
17015     }
17016
17017   M (POLICER_ADD_DEL, mp);
17018
17019   clib_memcpy (mp->name, name, vec_len (name));
17020   vec_free (name);
17021   mp->is_add = is_add;
17022   mp->cir = cir;
17023   mp->eir = eir;
17024   mp->cb = cb;
17025   mp->eb = eb;
17026   mp->rate_type = rate_type;
17027   mp->round_type = round_type;
17028   mp->type = type;
17029   mp->conform_action_type = conform_action.action_type;
17030   mp->conform_dscp = conform_action.dscp;
17031   mp->exceed_action_type = exceed_action.action_type;
17032   mp->exceed_dscp = exceed_action.dscp;
17033   mp->violate_action_type = violate_action.action_type;
17034   mp->violate_dscp = violate_action.dscp;
17035   mp->color_aware = color_aware;
17036
17037   S (mp);
17038   W (ret);
17039   return ret;
17040 }
17041
17042 static int
17043 api_policer_dump (vat_main_t * vam)
17044 {
17045   unformat_input_t *i = vam->input;
17046   vl_api_policer_dump_t *mp;
17047   vl_api_control_ping_t *mp_ping;
17048   u8 *match_name = 0;
17049   u8 match_name_valid = 0;
17050   int ret;
17051
17052   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17053     {
17054       if (unformat (i, "name %s", &match_name))
17055         {
17056           vec_add1 (match_name, 0);
17057           match_name_valid = 1;
17058         }
17059       else
17060         break;
17061     }
17062
17063   M (POLICER_DUMP, mp);
17064   mp->match_name_valid = match_name_valid;
17065   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
17066   vec_free (match_name);
17067   /* send it... */
17068   S (mp);
17069
17070   /* Use a control ping for synchronization */
17071   M (CONTROL_PING, mp_ping);
17072   S (mp_ping);
17073
17074   /* Wait for a reply... */
17075   W (ret);
17076   return ret;
17077 }
17078
17079 static int
17080 api_policer_classify_set_interface (vat_main_t * vam)
17081 {
17082   unformat_input_t *i = vam->input;
17083   vl_api_policer_classify_set_interface_t *mp;
17084   u32 sw_if_index;
17085   int sw_if_index_set;
17086   u32 ip4_table_index = ~0;
17087   u32 ip6_table_index = ~0;
17088   u32 l2_table_index = ~0;
17089   u8 is_add = 1;
17090   int ret;
17091
17092   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17093     {
17094       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17095         sw_if_index_set = 1;
17096       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17097         sw_if_index_set = 1;
17098       else if (unformat (i, "del"))
17099         is_add = 0;
17100       else if (unformat (i, "ip4-table %d", &ip4_table_index))
17101         ;
17102       else if (unformat (i, "ip6-table %d", &ip6_table_index))
17103         ;
17104       else if (unformat (i, "l2-table %d", &l2_table_index))
17105         ;
17106       else
17107         {
17108           clib_warning ("parse error '%U'", format_unformat_error, i);
17109           return -99;
17110         }
17111     }
17112
17113   if (sw_if_index_set == 0)
17114     {
17115       errmsg ("missing interface name or sw_if_index");
17116       return -99;
17117     }
17118
17119   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
17120
17121   mp->sw_if_index = ntohl (sw_if_index);
17122   mp->ip4_table_index = ntohl (ip4_table_index);
17123   mp->ip6_table_index = ntohl (ip6_table_index);
17124   mp->l2_table_index = ntohl (l2_table_index);
17125   mp->is_add = is_add;
17126
17127   S (mp);
17128   W (ret);
17129   return ret;
17130 }
17131
17132 static int
17133 api_policer_classify_dump (vat_main_t * vam)
17134 {
17135   unformat_input_t *i = vam->input;
17136   vl_api_policer_classify_dump_t *mp;
17137   vl_api_control_ping_t *mp_ping;
17138   u8 type = POLICER_CLASSIFY_N_TABLES;
17139   int ret;
17140
17141   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
17142     ;
17143   else
17144     {
17145       errmsg ("classify table type must be specified");
17146       return -99;
17147     }
17148
17149   if (!vam->json_output)
17150     {
17151       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
17152     }
17153
17154   M (POLICER_CLASSIFY_DUMP, mp);
17155   mp->type = type;
17156   /* send it... */
17157   S (mp);
17158
17159   /* Use a control ping for synchronization */
17160   M (CONTROL_PING, mp_ping);
17161   S (mp_ping);
17162
17163   /* Wait for a reply... */
17164   W (ret);
17165   return ret;
17166 }
17167
17168 static int
17169 api_netmap_create (vat_main_t * vam)
17170 {
17171   unformat_input_t *i = vam->input;
17172   vl_api_netmap_create_t *mp;
17173   u8 *if_name = 0;
17174   u8 hw_addr[6];
17175   u8 random_hw_addr = 1;
17176   u8 is_pipe = 0;
17177   u8 is_master = 0;
17178   int ret;
17179
17180   memset (hw_addr, 0, sizeof (hw_addr));
17181
17182   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17183     {
17184       if (unformat (i, "name %s", &if_name))
17185         vec_add1 (if_name, 0);
17186       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
17187         random_hw_addr = 0;
17188       else if (unformat (i, "pipe"))
17189         is_pipe = 1;
17190       else if (unformat (i, "master"))
17191         is_master = 1;
17192       else if (unformat (i, "slave"))
17193         is_master = 0;
17194       else
17195         break;
17196     }
17197
17198   if (!vec_len (if_name))
17199     {
17200       errmsg ("interface name must be specified");
17201       return -99;
17202     }
17203
17204   if (vec_len (if_name) > 64)
17205     {
17206       errmsg ("interface name too long");
17207       return -99;
17208     }
17209
17210   M (NETMAP_CREATE, mp);
17211
17212   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
17213   clib_memcpy (mp->hw_addr, hw_addr, 6);
17214   mp->use_random_hw_addr = random_hw_addr;
17215   mp->is_pipe = is_pipe;
17216   mp->is_master = is_master;
17217   vec_free (if_name);
17218
17219   S (mp);
17220   W (ret);
17221   return ret;
17222 }
17223
17224 static int
17225 api_netmap_delete (vat_main_t * vam)
17226 {
17227   unformat_input_t *i = vam->input;
17228   vl_api_netmap_delete_t *mp;
17229   u8 *if_name = 0;
17230   int ret;
17231
17232   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17233     {
17234       if (unformat (i, "name %s", &if_name))
17235         vec_add1 (if_name, 0);
17236       else
17237         break;
17238     }
17239
17240   if (!vec_len (if_name))
17241     {
17242       errmsg ("interface name must be specified");
17243       return -99;
17244     }
17245
17246   if (vec_len (if_name) > 64)
17247     {
17248       errmsg ("interface name too long");
17249       return -99;
17250     }
17251
17252   M (NETMAP_DELETE, mp);
17253
17254   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
17255   vec_free (if_name);
17256
17257   S (mp);
17258   W (ret);
17259   return ret;
17260 }
17261
17262 static void
17263 vl_api_mpls_fib_path_print (vat_main_t * vam, vl_api_fib_path2_t * fp)
17264 {
17265   if (fp->afi == IP46_TYPE_IP6)
17266     print (vam->ofp,
17267            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
17268            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
17269            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
17270            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
17271            format_ip6_address, fp->next_hop);
17272   else if (fp->afi == IP46_TYPE_IP4)
17273     print (vam->ofp,
17274            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
17275            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
17276            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
17277            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
17278            format_ip4_address, fp->next_hop);
17279 }
17280
17281 static void
17282 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
17283                                  vl_api_fib_path2_t * fp)
17284 {
17285   struct in_addr ip4;
17286   struct in6_addr ip6;
17287
17288   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
17289   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
17290   vat_json_object_add_uint (node, "is_local", fp->is_local);
17291   vat_json_object_add_uint (node, "is_drop", fp->is_drop);
17292   vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
17293   vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
17294   vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
17295   if (fp->afi == IP46_TYPE_IP4)
17296     {
17297       clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
17298       vat_json_object_add_ip4 (node, "next_hop", ip4);
17299     }
17300   else if (fp->afi == IP46_TYPE_IP6)
17301     {
17302       clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
17303       vat_json_object_add_ip6 (node, "next_hop", ip6);
17304     }
17305 }
17306
17307 static void
17308 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
17309 {
17310   vat_main_t *vam = &vat_main;
17311   int count = ntohl (mp->mt_count);
17312   vl_api_fib_path2_t *fp;
17313   i32 i;
17314
17315   print (vam->ofp, "[%d]: sw_if_index %d via:",
17316          ntohl (mp->mt_tunnel_index), ntohl (mp->mt_sw_if_index));
17317   fp = mp->mt_paths;
17318   for (i = 0; i < count; i++)
17319     {
17320       vl_api_mpls_fib_path_print (vam, fp);
17321       fp++;
17322     }
17323
17324   print (vam->ofp, "");
17325 }
17326
17327 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
17328 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
17329
17330 static void
17331 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
17332 {
17333   vat_main_t *vam = &vat_main;
17334   vat_json_node_t *node = NULL;
17335   int count = ntohl (mp->mt_count);
17336   vl_api_fib_path2_t *fp;
17337   i32 i;
17338
17339   if (VAT_JSON_ARRAY != vam->json_tree.type)
17340     {
17341       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17342       vat_json_init_array (&vam->json_tree);
17343     }
17344   node = vat_json_array_add (&vam->json_tree);
17345
17346   vat_json_init_object (node);
17347   vat_json_object_add_uint (node, "tunnel_index",
17348                             ntohl (mp->mt_tunnel_index));
17349   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->mt_sw_if_index));
17350
17351   vat_json_object_add_uint (node, "l2_only", mp->mt_l2_only);
17352
17353   fp = mp->mt_paths;
17354   for (i = 0; i < count; i++)
17355     {
17356       vl_api_mpls_fib_path_json_print (node, fp);
17357       fp++;
17358     }
17359 }
17360
17361 static int
17362 api_mpls_tunnel_dump (vat_main_t * vam)
17363 {
17364   vl_api_mpls_tunnel_dump_t *mp;
17365   vl_api_control_ping_t *mp_ping;
17366   i32 index = -1;
17367   int ret;
17368
17369   /* Parse args required to build the message */
17370   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
17371     {
17372       if (!unformat (vam->input, "tunnel_index %d", &index))
17373         {
17374           index = -1;
17375           break;
17376         }
17377     }
17378
17379   print (vam->ofp, "  tunnel_index %d", index);
17380
17381   M (MPLS_TUNNEL_DUMP, mp);
17382   mp->tunnel_index = htonl (index);
17383   S (mp);
17384
17385   /* Use a control ping for synchronization */
17386   M (CONTROL_PING, mp_ping);
17387   S (mp_ping);
17388
17389   W (ret);
17390   return ret;
17391 }
17392
17393 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
17394 #define vl_api_mpls_fib_details_t_print vl_noop_handler
17395
17396
17397 static void
17398 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
17399 {
17400   vat_main_t *vam = &vat_main;
17401   int count = ntohl (mp->count);
17402   vl_api_fib_path2_t *fp;
17403   int i;
17404
17405   print (vam->ofp,
17406          "table-id %d, label %u, ess_bit %u",
17407          ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
17408   fp = mp->path;
17409   for (i = 0; i < count; i++)
17410     {
17411       vl_api_mpls_fib_path_print (vam, fp);
17412       fp++;
17413     }
17414 }
17415
17416 static void vl_api_mpls_fib_details_t_handler_json
17417   (vl_api_mpls_fib_details_t * mp)
17418 {
17419   vat_main_t *vam = &vat_main;
17420   int count = ntohl (mp->count);
17421   vat_json_node_t *node = NULL;
17422   vl_api_fib_path2_t *fp;
17423   int i;
17424
17425   if (VAT_JSON_ARRAY != vam->json_tree.type)
17426     {
17427       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17428       vat_json_init_array (&vam->json_tree);
17429     }
17430   node = vat_json_array_add (&vam->json_tree);
17431
17432   vat_json_init_object (node);
17433   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
17434   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
17435   vat_json_object_add_uint (node, "label", ntohl (mp->label));
17436   vat_json_object_add_uint (node, "path_count", count);
17437   fp = mp->path;
17438   for (i = 0; i < count; i++)
17439     {
17440       vl_api_mpls_fib_path_json_print (node, fp);
17441       fp++;
17442     }
17443 }
17444
17445 static int
17446 api_mpls_fib_dump (vat_main_t * vam)
17447 {
17448   vl_api_mpls_fib_dump_t *mp;
17449   vl_api_control_ping_t *mp_ping;
17450   int ret;
17451
17452   M (MPLS_FIB_DUMP, mp);
17453   S (mp);
17454
17455   /* Use a control ping for synchronization */
17456   M (CONTROL_PING, mp_ping);
17457   S (mp_ping);
17458
17459   W (ret);
17460   return ret;
17461 }
17462
17463 #define vl_api_ip_fib_details_t_endian vl_noop_handler
17464 #define vl_api_ip_fib_details_t_print vl_noop_handler
17465
17466 static void
17467 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
17468 {
17469   vat_main_t *vam = &vat_main;
17470   int count = ntohl (mp->count);
17471   vl_api_fib_path_t *fp;
17472   int i;
17473
17474   print (vam->ofp,
17475          "table-id %d, prefix %U/%d",
17476          ntohl (mp->table_id), format_ip4_address, mp->address,
17477          mp->address_length);
17478   fp = mp->path;
17479   for (i = 0; i < count; i++)
17480     {
17481       if (fp->afi == IP46_TYPE_IP6)
17482         print (vam->ofp,
17483                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
17484                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
17485                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
17486                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
17487                format_ip6_address, fp->next_hop);
17488       else if (fp->afi == IP46_TYPE_IP4)
17489         print (vam->ofp,
17490                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
17491                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
17492                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
17493                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
17494                format_ip4_address, fp->next_hop);
17495       fp++;
17496     }
17497 }
17498
17499 static void vl_api_ip_fib_details_t_handler_json
17500   (vl_api_ip_fib_details_t * mp)
17501 {
17502   vat_main_t *vam = &vat_main;
17503   int count = ntohl (mp->count);
17504   vat_json_node_t *node = NULL;
17505   struct in_addr ip4;
17506   struct in6_addr ip6;
17507   vl_api_fib_path_t *fp;
17508   int i;
17509
17510   if (VAT_JSON_ARRAY != vam->json_tree.type)
17511     {
17512       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17513       vat_json_init_array (&vam->json_tree);
17514     }
17515   node = vat_json_array_add (&vam->json_tree);
17516
17517   vat_json_init_object (node);
17518   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
17519   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
17520   vat_json_object_add_ip4 (node, "prefix", ip4);
17521   vat_json_object_add_uint (node, "mask_length", mp->address_length);
17522   vat_json_object_add_uint (node, "path_count", count);
17523   fp = mp->path;
17524   for (i = 0; i < count; i++)
17525     {
17526       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
17527       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
17528       vat_json_object_add_uint (node, "is_local", fp->is_local);
17529       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
17530       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
17531       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
17532       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
17533       if (fp->afi == IP46_TYPE_IP4)
17534         {
17535           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
17536           vat_json_object_add_ip4 (node, "next_hop", ip4);
17537         }
17538       else if (fp->afi == IP46_TYPE_IP6)
17539         {
17540           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
17541           vat_json_object_add_ip6 (node, "next_hop", ip6);
17542         }
17543     }
17544 }
17545
17546 static int
17547 api_ip_fib_dump (vat_main_t * vam)
17548 {
17549   vl_api_ip_fib_dump_t *mp;
17550   vl_api_control_ping_t *mp_ping;
17551   int ret;
17552
17553   M (IP_FIB_DUMP, mp);
17554   S (mp);
17555
17556   /* Use a control ping for synchronization */
17557   M (CONTROL_PING, mp_ping);
17558   S (mp_ping);
17559
17560   W (ret);
17561   return ret;
17562 }
17563
17564 static int
17565 api_ip_mfib_dump (vat_main_t * vam)
17566 {
17567   vl_api_ip_mfib_dump_t *mp;
17568   vl_api_control_ping_t *mp_ping;
17569   int ret;
17570
17571   M (IP_MFIB_DUMP, mp);
17572   S (mp);
17573
17574   /* Use a control ping for synchronization */
17575   M (CONTROL_PING, mp_ping);
17576   S (mp_ping);
17577
17578   W (ret);
17579   return ret;
17580 }
17581
17582 static void vl_api_ip_neighbor_details_t_handler
17583   (vl_api_ip_neighbor_details_t * mp)
17584 {
17585   vat_main_t *vam = &vat_main;
17586
17587   print (vam->ofp, "%c %U %U",
17588          (mp->is_static) ? 'S' : 'D',
17589          format_ethernet_address, &mp->mac_address,
17590          (mp->is_ipv6) ? format_ip6_address : format_ip4_address,
17591          &mp->ip_address);
17592 }
17593
17594 static void vl_api_ip_neighbor_details_t_handler_json
17595   (vl_api_ip_neighbor_details_t * mp)
17596 {
17597
17598   vat_main_t *vam = &vat_main;
17599   vat_json_node_t *node;
17600   struct in_addr ip4;
17601   struct in6_addr ip6;
17602
17603   if (VAT_JSON_ARRAY != vam->json_tree.type)
17604     {
17605       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17606       vat_json_init_array (&vam->json_tree);
17607     }
17608   node = vat_json_array_add (&vam->json_tree);
17609
17610   vat_json_init_object (node);
17611   vat_json_object_add_string_copy (node, "flag",
17612                                    (mp->is_static) ? (u8 *) "static" : (u8 *)
17613                                    "dynamic");
17614
17615   vat_json_object_add_string_copy (node, "link_layer",
17616                                    format (0, "%U", format_ethernet_address,
17617                                            &mp->mac_address));
17618
17619   if (mp->is_ipv6)
17620     {
17621       clib_memcpy (&ip6, &mp->ip_address, sizeof (ip6));
17622       vat_json_object_add_ip6 (node, "ip_address", ip6);
17623     }
17624   else
17625     {
17626       clib_memcpy (&ip4, &mp->ip_address, sizeof (ip4));
17627       vat_json_object_add_ip4 (node, "ip_address", ip4);
17628     }
17629 }
17630
17631 static int
17632 api_ip_neighbor_dump (vat_main_t * vam)
17633 {
17634   unformat_input_t *i = vam->input;
17635   vl_api_ip_neighbor_dump_t *mp;
17636   vl_api_control_ping_t *mp_ping;
17637   u8 is_ipv6 = 0;
17638   u32 sw_if_index = ~0;
17639   int ret;
17640
17641   /* Parse args required to build the message */
17642   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17643     {
17644       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17645         ;
17646       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17647         ;
17648       else if (unformat (i, "ip6"))
17649         is_ipv6 = 1;
17650       else
17651         break;
17652     }
17653
17654   if (sw_if_index == ~0)
17655     {
17656       errmsg ("missing interface name or sw_if_index");
17657       return -99;
17658     }
17659
17660   M (IP_NEIGHBOR_DUMP, mp);
17661   mp->is_ipv6 = (u8) is_ipv6;
17662   mp->sw_if_index = ntohl (sw_if_index);
17663   S (mp);
17664
17665   /* Use a control ping for synchronization */
17666   M (CONTROL_PING, mp_ping);
17667   S (mp_ping);
17668
17669   W (ret);
17670   return ret;
17671 }
17672
17673 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
17674 #define vl_api_ip6_fib_details_t_print vl_noop_handler
17675
17676 static void
17677 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
17678 {
17679   vat_main_t *vam = &vat_main;
17680   int count = ntohl (mp->count);
17681   vl_api_fib_path_t *fp;
17682   int i;
17683
17684   print (vam->ofp,
17685          "table-id %d, prefix %U/%d",
17686          ntohl (mp->table_id), format_ip6_address, mp->address,
17687          mp->address_length);
17688   fp = mp->path;
17689   for (i = 0; i < count; i++)
17690     {
17691       if (fp->afi == IP46_TYPE_IP6)
17692         print (vam->ofp,
17693                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
17694                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
17695                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
17696                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
17697                format_ip6_address, fp->next_hop);
17698       else if (fp->afi == IP46_TYPE_IP4)
17699         print (vam->ofp,
17700                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
17701                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
17702                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
17703                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
17704                format_ip4_address, fp->next_hop);
17705       fp++;
17706     }
17707 }
17708
17709 static void vl_api_ip6_fib_details_t_handler_json
17710   (vl_api_ip6_fib_details_t * mp)
17711 {
17712   vat_main_t *vam = &vat_main;
17713   int count = ntohl (mp->count);
17714   vat_json_node_t *node = NULL;
17715   struct in_addr ip4;
17716   struct in6_addr ip6;
17717   vl_api_fib_path_t *fp;
17718   int i;
17719
17720   if (VAT_JSON_ARRAY != vam->json_tree.type)
17721     {
17722       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17723       vat_json_init_array (&vam->json_tree);
17724     }
17725   node = vat_json_array_add (&vam->json_tree);
17726
17727   vat_json_init_object (node);
17728   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
17729   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
17730   vat_json_object_add_ip6 (node, "prefix", ip6);
17731   vat_json_object_add_uint (node, "mask_length", mp->address_length);
17732   vat_json_object_add_uint (node, "path_count", count);
17733   fp = mp->path;
17734   for (i = 0; i < count; i++)
17735     {
17736       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
17737       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
17738       vat_json_object_add_uint (node, "is_local", fp->is_local);
17739       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
17740       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
17741       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
17742       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
17743       if (fp->afi == IP46_TYPE_IP4)
17744         {
17745           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
17746           vat_json_object_add_ip4 (node, "next_hop", ip4);
17747         }
17748       else if (fp->afi == IP46_TYPE_IP6)
17749         {
17750           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
17751           vat_json_object_add_ip6 (node, "next_hop", ip6);
17752         }
17753     }
17754 }
17755
17756 static int
17757 api_ip6_fib_dump (vat_main_t * vam)
17758 {
17759   vl_api_ip6_fib_dump_t *mp;
17760   vl_api_control_ping_t *mp_ping;
17761   int ret;
17762
17763   M (IP6_FIB_DUMP, mp);
17764   S (mp);
17765
17766   /* Use a control ping for synchronization */
17767   M (CONTROL_PING, mp_ping);
17768   S (mp_ping);
17769
17770   W (ret);
17771   return ret;
17772 }
17773
17774 static int
17775 api_ip6_mfib_dump (vat_main_t * vam)
17776 {
17777   vl_api_ip6_mfib_dump_t *mp;
17778   vl_api_control_ping_t *mp_ping;
17779   int ret;
17780
17781   M (IP6_MFIB_DUMP, mp);
17782   S (mp);
17783
17784   /* Use a control ping for synchronization */
17785   M (CONTROL_PING, mp_ping);
17786   S (mp_ping);
17787
17788   W (ret);
17789   return ret;
17790 }
17791
17792 int
17793 api_classify_table_ids (vat_main_t * vam)
17794 {
17795   vl_api_classify_table_ids_t *mp;
17796   int ret;
17797
17798   /* Construct the API message */
17799   M (CLASSIFY_TABLE_IDS, mp);
17800   mp->context = 0;
17801
17802   S (mp);
17803   W (ret);
17804   return ret;
17805 }
17806
17807 int
17808 api_classify_table_by_interface (vat_main_t * vam)
17809 {
17810   unformat_input_t *input = vam->input;
17811   vl_api_classify_table_by_interface_t *mp;
17812
17813   u32 sw_if_index = ~0;
17814   int ret;
17815   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17816     {
17817       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17818         ;
17819       else if (unformat (input, "sw_if_index %d", &sw_if_index))
17820         ;
17821       else
17822         break;
17823     }
17824   if (sw_if_index == ~0)
17825     {
17826       errmsg ("missing interface name or sw_if_index");
17827       return -99;
17828     }
17829
17830   /* Construct the API message */
17831   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
17832   mp->context = 0;
17833   mp->sw_if_index = ntohl (sw_if_index);
17834
17835   S (mp);
17836   W (ret);
17837   return ret;
17838 }
17839
17840 int
17841 api_classify_table_info (vat_main_t * vam)
17842 {
17843   unformat_input_t *input = vam->input;
17844   vl_api_classify_table_info_t *mp;
17845
17846   u32 table_id = ~0;
17847   int ret;
17848   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17849     {
17850       if (unformat (input, "table_id %d", &table_id))
17851         ;
17852       else
17853         break;
17854     }
17855   if (table_id == ~0)
17856     {
17857       errmsg ("missing table id");
17858       return -99;
17859     }
17860
17861   /* Construct the API message */
17862   M (CLASSIFY_TABLE_INFO, mp);
17863   mp->context = 0;
17864   mp->table_id = ntohl (table_id);
17865
17866   S (mp);
17867   W (ret);
17868   return ret;
17869 }
17870
17871 int
17872 api_classify_session_dump (vat_main_t * vam)
17873 {
17874   unformat_input_t *input = vam->input;
17875   vl_api_classify_session_dump_t *mp;
17876   vl_api_control_ping_t *mp_ping;
17877
17878   u32 table_id = ~0;
17879   int ret;
17880   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17881     {
17882       if (unformat (input, "table_id %d", &table_id))
17883         ;
17884       else
17885         break;
17886     }
17887   if (table_id == ~0)
17888     {
17889       errmsg ("missing table id");
17890       return -99;
17891     }
17892
17893   /* Construct the API message */
17894   M (CLASSIFY_SESSION_DUMP, mp);
17895   mp->context = 0;
17896   mp->table_id = ntohl (table_id);
17897   S (mp);
17898
17899   /* Use a control ping for synchronization */
17900   M (CONTROL_PING, mp_ping);
17901   S (mp_ping);
17902
17903   W (ret);
17904   return ret;
17905 }
17906
17907 static void
17908 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
17909 {
17910   vat_main_t *vam = &vat_main;
17911
17912   print (vam->ofp, "collector_address %U, collector_port %d, "
17913          "src_address %U, vrf_id %d, path_mtu %u, "
17914          "template_interval %u, udp_checksum %d",
17915          format_ip4_address, mp->collector_address,
17916          ntohs (mp->collector_port),
17917          format_ip4_address, mp->src_address,
17918          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
17919          ntohl (mp->template_interval), mp->udp_checksum);
17920
17921   vam->retval = 0;
17922   vam->result_ready = 1;
17923 }
17924
17925 static void
17926   vl_api_ipfix_exporter_details_t_handler_json
17927   (vl_api_ipfix_exporter_details_t * mp)
17928 {
17929   vat_main_t *vam = &vat_main;
17930   vat_json_node_t node;
17931   struct in_addr collector_address;
17932   struct in_addr src_address;
17933
17934   vat_json_init_object (&node);
17935   clib_memcpy (&collector_address, &mp->collector_address,
17936                sizeof (collector_address));
17937   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
17938   vat_json_object_add_uint (&node, "collector_port",
17939                             ntohs (mp->collector_port));
17940   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
17941   vat_json_object_add_ip4 (&node, "src_address", src_address);
17942   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
17943   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
17944   vat_json_object_add_uint (&node, "template_interval",
17945                             ntohl (mp->template_interval));
17946   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
17947
17948   vat_json_print (vam->ofp, &node);
17949   vat_json_free (&node);
17950   vam->retval = 0;
17951   vam->result_ready = 1;
17952 }
17953
17954 int
17955 api_ipfix_exporter_dump (vat_main_t * vam)
17956 {
17957   vl_api_ipfix_exporter_dump_t *mp;
17958   int ret;
17959
17960   /* Construct the API message */
17961   M (IPFIX_EXPORTER_DUMP, mp);
17962   mp->context = 0;
17963
17964   S (mp);
17965   W (ret);
17966   return ret;
17967 }
17968
17969 static int
17970 api_ipfix_classify_stream_dump (vat_main_t * vam)
17971 {
17972   vl_api_ipfix_classify_stream_dump_t *mp;
17973   int ret;
17974
17975   /* Construct the API message */
17976   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
17977   mp->context = 0;
17978
17979   S (mp);
17980   W (ret);
17981   return ret;
17982   /* NOTREACHED */
17983   return 0;
17984 }
17985
17986 static void
17987   vl_api_ipfix_classify_stream_details_t_handler
17988   (vl_api_ipfix_classify_stream_details_t * mp)
17989 {
17990   vat_main_t *vam = &vat_main;
17991   print (vam->ofp, "domain_id %d, src_port %d",
17992          ntohl (mp->domain_id), ntohs (mp->src_port));
17993   vam->retval = 0;
17994   vam->result_ready = 1;
17995 }
17996
17997 static void
17998   vl_api_ipfix_classify_stream_details_t_handler_json
17999   (vl_api_ipfix_classify_stream_details_t * mp)
18000 {
18001   vat_main_t *vam = &vat_main;
18002   vat_json_node_t node;
18003
18004   vat_json_init_object (&node);
18005   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
18006   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
18007
18008   vat_json_print (vam->ofp, &node);
18009   vat_json_free (&node);
18010   vam->retval = 0;
18011   vam->result_ready = 1;
18012 }
18013
18014 static int
18015 api_ipfix_classify_table_dump (vat_main_t * vam)
18016 {
18017   vl_api_ipfix_classify_table_dump_t *mp;
18018   vl_api_control_ping_t *mp_ping;
18019   int ret;
18020
18021   if (!vam->json_output)
18022     {
18023       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
18024              "transport_protocol");
18025     }
18026
18027   /* Construct the API message */
18028   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
18029
18030   /* send it... */
18031   S (mp);
18032
18033   /* Use a control ping for synchronization */
18034   M (CONTROL_PING, mp_ping);
18035   S (mp_ping);
18036
18037   W (ret);
18038   return ret;
18039 }
18040
18041 static void
18042   vl_api_ipfix_classify_table_details_t_handler
18043   (vl_api_ipfix_classify_table_details_t * mp)
18044 {
18045   vat_main_t *vam = &vat_main;
18046   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
18047          mp->transport_protocol);
18048 }
18049
18050 static void
18051   vl_api_ipfix_classify_table_details_t_handler_json
18052   (vl_api_ipfix_classify_table_details_t * mp)
18053 {
18054   vat_json_node_t *node = NULL;
18055   vat_main_t *vam = &vat_main;
18056
18057   if (VAT_JSON_ARRAY != vam->json_tree.type)
18058     {
18059       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18060       vat_json_init_array (&vam->json_tree);
18061     }
18062
18063   node = vat_json_array_add (&vam->json_tree);
18064   vat_json_init_object (node);
18065
18066   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
18067   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
18068   vat_json_object_add_uint (node, "transport_protocol",
18069                             mp->transport_protocol);
18070 }
18071
18072 static int
18073 api_sw_interface_span_enable_disable (vat_main_t * vam)
18074 {
18075   unformat_input_t *i = vam->input;
18076   vl_api_sw_interface_span_enable_disable_t *mp;
18077   u32 src_sw_if_index = ~0;
18078   u32 dst_sw_if_index = ~0;
18079   u8 state = 3;
18080   int ret;
18081
18082   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18083     {
18084       if (unformat
18085           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
18086         ;
18087       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
18088         ;
18089       else
18090         if (unformat
18091             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
18092         ;
18093       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
18094         ;
18095       else if (unformat (i, "disable"))
18096         state = 0;
18097       else if (unformat (i, "rx"))
18098         state = 1;
18099       else if (unformat (i, "tx"))
18100         state = 2;
18101       else if (unformat (i, "both"))
18102         state = 3;
18103       else
18104         break;
18105     }
18106
18107   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
18108
18109   mp->sw_if_index_from = htonl (src_sw_if_index);
18110   mp->sw_if_index_to = htonl (dst_sw_if_index);
18111   mp->state = state;
18112
18113   S (mp);
18114   W (ret);
18115   return ret;
18116 }
18117
18118 static void
18119 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
18120                                             * mp)
18121 {
18122   vat_main_t *vam = &vat_main;
18123   u8 *sw_if_from_name = 0;
18124   u8 *sw_if_to_name = 0;
18125   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
18126   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
18127   char *states[] = { "none", "rx", "tx", "both" };
18128   hash_pair_t *p;
18129
18130   /* *INDENT-OFF* */
18131   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
18132   ({
18133     if ((u32) p->value[0] == sw_if_index_from)
18134       {
18135         sw_if_from_name = (u8 *)(p->key);
18136         if (sw_if_to_name)
18137           break;
18138       }
18139     if ((u32) p->value[0] == sw_if_index_to)
18140       {
18141         sw_if_to_name = (u8 *)(p->key);
18142         if (sw_if_from_name)
18143           break;
18144       }
18145   }));
18146   /* *INDENT-ON* */
18147   print (vam->ofp, "%20s => %20s (%s)",
18148          sw_if_from_name, sw_if_to_name, states[mp->state]);
18149 }
18150
18151 static void
18152   vl_api_sw_interface_span_details_t_handler_json
18153   (vl_api_sw_interface_span_details_t * mp)
18154 {
18155   vat_main_t *vam = &vat_main;
18156   vat_json_node_t *node = NULL;
18157   u8 *sw_if_from_name = 0;
18158   u8 *sw_if_to_name = 0;
18159   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
18160   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
18161   hash_pair_t *p;
18162
18163   /* *INDENT-OFF* */
18164   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
18165   ({
18166     if ((u32) p->value[0] == sw_if_index_from)
18167       {
18168         sw_if_from_name = (u8 *)(p->key);
18169         if (sw_if_to_name)
18170           break;
18171       }
18172     if ((u32) p->value[0] == sw_if_index_to)
18173       {
18174         sw_if_to_name = (u8 *)(p->key);
18175         if (sw_if_from_name)
18176           break;
18177       }
18178   }));
18179   /* *INDENT-ON* */
18180
18181   if (VAT_JSON_ARRAY != vam->json_tree.type)
18182     {
18183       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18184       vat_json_init_array (&vam->json_tree);
18185     }
18186   node = vat_json_array_add (&vam->json_tree);
18187
18188   vat_json_init_object (node);
18189   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
18190   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
18191   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
18192   if (0 != sw_if_to_name)
18193     {
18194       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
18195     }
18196   vat_json_object_add_uint (node, "state", mp->state);
18197 }
18198
18199 static int
18200 api_sw_interface_span_dump (vat_main_t * vam)
18201 {
18202   vl_api_sw_interface_span_dump_t *mp;
18203   vl_api_control_ping_t *mp_ping;
18204   int ret;
18205
18206   M (SW_INTERFACE_SPAN_DUMP, mp);
18207   S (mp);
18208
18209   /* Use a control ping for synchronization */
18210   M (CONTROL_PING, mp_ping);
18211   S (mp_ping);
18212
18213   W (ret);
18214   return ret;
18215 }
18216
18217 int
18218 api_pg_create_interface (vat_main_t * vam)
18219 {
18220   unformat_input_t *input = vam->input;
18221   vl_api_pg_create_interface_t *mp;
18222
18223   u32 if_id = ~0;
18224   int ret;
18225   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18226     {
18227       if (unformat (input, "if_id %d", &if_id))
18228         ;
18229       else
18230         break;
18231     }
18232   if (if_id == ~0)
18233     {
18234       errmsg ("missing pg interface index");
18235       return -99;
18236     }
18237
18238   /* Construct the API message */
18239   M (PG_CREATE_INTERFACE, mp);
18240   mp->context = 0;
18241   mp->interface_id = ntohl (if_id);
18242
18243   S (mp);
18244   W (ret);
18245   return ret;
18246 }
18247
18248 int
18249 api_pg_capture (vat_main_t * vam)
18250 {
18251   unformat_input_t *input = vam->input;
18252   vl_api_pg_capture_t *mp;
18253
18254   u32 if_id = ~0;
18255   u8 enable = 1;
18256   u32 count = 1;
18257   u8 pcap_file_set = 0;
18258   u8 *pcap_file = 0;
18259   int ret;
18260   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18261     {
18262       if (unformat (input, "if_id %d", &if_id))
18263         ;
18264       else if (unformat (input, "pcap %s", &pcap_file))
18265         pcap_file_set = 1;
18266       else if (unformat (input, "count %d", &count))
18267         ;
18268       else if (unformat (input, "disable"))
18269         enable = 0;
18270       else
18271         break;
18272     }
18273   if (if_id == ~0)
18274     {
18275       errmsg ("missing pg interface index");
18276       return -99;
18277     }
18278   if (pcap_file_set > 0)
18279     {
18280       if (vec_len (pcap_file) > 255)
18281         {
18282           errmsg ("pcap file name is too long");
18283           return -99;
18284         }
18285     }
18286
18287   u32 name_len = vec_len (pcap_file);
18288   /* Construct the API message */
18289   M (PG_CAPTURE, mp);
18290   mp->context = 0;
18291   mp->interface_id = ntohl (if_id);
18292   mp->is_enabled = enable;
18293   mp->count = ntohl (count);
18294   mp->pcap_name_length = ntohl (name_len);
18295   if (pcap_file_set != 0)
18296     {
18297       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
18298     }
18299   vec_free (pcap_file);
18300
18301   S (mp);
18302   W (ret);
18303   return ret;
18304 }
18305
18306 int
18307 api_pg_enable_disable (vat_main_t * vam)
18308 {
18309   unformat_input_t *input = vam->input;
18310   vl_api_pg_enable_disable_t *mp;
18311
18312   u8 enable = 1;
18313   u8 stream_name_set = 0;
18314   u8 *stream_name = 0;
18315   int ret;
18316   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18317     {
18318       if (unformat (input, "stream %s", &stream_name))
18319         stream_name_set = 1;
18320       else if (unformat (input, "disable"))
18321         enable = 0;
18322       else
18323         break;
18324     }
18325
18326   if (stream_name_set > 0)
18327     {
18328       if (vec_len (stream_name) > 255)
18329         {
18330           errmsg ("stream name too long");
18331           return -99;
18332         }
18333     }
18334
18335   u32 name_len = vec_len (stream_name);
18336   /* Construct the API message */
18337   M (PG_ENABLE_DISABLE, mp);
18338   mp->context = 0;
18339   mp->is_enabled = enable;
18340   if (stream_name_set != 0)
18341     {
18342       mp->stream_name_length = ntohl (name_len);
18343       clib_memcpy (mp->stream_name, stream_name, name_len);
18344     }
18345   vec_free (stream_name);
18346
18347   S (mp);
18348   W (ret);
18349   return ret;
18350 }
18351
18352 int
18353 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
18354 {
18355   unformat_input_t *input = vam->input;
18356   vl_api_ip_source_and_port_range_check_add_del_t *mp;
18357
18358   u16 *low_ports = 0;
18359   u16 *high_ports = 0;
18360   u16 this_low;
18361   u16 this_hi;
18362   ip4_address_t ip4_addr;
18363   ip6_address_t ip6_addr;
18364   u32 length;
18365   u32 tmp, tmp2;
18366   u8 prefix_set = 0;
18367   u32 vrf_id = ~0;
18368   u8 is_add = 1;
18369   u8 is_ipv6 = 0;
18370   int ret;
18371
18372   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18373     {
18374       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
18375         {
18376           prefix_set = 1;
18377         }
18378       else
18379         if (unformat
18380             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
18381         {
18382           prefix_set = 1;
18383           is_ipv6 = 1;
18384         }
18385       else if (unformat (input, "vrf %d", &vrf_id))
18386         ;
18387       else if (unformat (input, "del"))
18388         is_add = 0;
18389       else if (unformat (input, "port %d", &tmp))
18390         {
18391           if (tmp == 0 || tmp > 65535)
18392             {
18393               errmsg ("port %d out of range", tmp);
18394               return -99;
18395             }
18396           this_low = tmp;
18397           this_hi = this_low + 1;
18398           vec_add1 (low_ports, this_low);
18399           vec_add1 (high_ports, this_hi);
18400         }
18401       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
18402         {
18403           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
18404             {
18405               errmsg ("incorrect range parameters");
18406               return -99;
18407             }
18408           this_low = tmp;
18409           /* Note: in debug CLI +1 is added to high before
18410              passing to real fn that does "the work"
18411              (ip_source_and_port_range_check_add_del).
18412              This fn is a wrapper around the binary API fn a
18413              control plane will call, which expects this increment
18414              to have occurred. Hence letting the binary API control
18415              plane fn do the increment for consistency between VAT
18416              and other control planes.
18417            */
18418           this_hi = tmp2;
18419           vec_add1 (low_ports, this_low);
18420           vec_add1 (high_ports, this_hi);
18421         }
18422       else
18423         break;
18424     }
18425
18426   if (prefix_set == 0)
18427     {
18428       errmsg ("<address>/<mask> not specified");
18429       return -99;
18430     }
18431
18432   if (vrf_id == ~0)
18433     {
18434       errmsg ("VRF ID required, not specified");
18435       return -99;
18436     }
18437
18438   if (vrf_id == 0)
18439     {
18440       errmsg
18441         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
18442       return -99;
18443     }
18444
18445   if (vec_len (low_ports) == 0)
18446     {
18447       errmsg ("At least one port or port range required");
18448       return -99;
18449     }
18450
18451   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
18452
18453   mp->is_add = is_add;
18454
18455   if (is_ipv6)
18456     {
18457       mp->is_ipv6 = 1;
18458       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
18459     }
18460   else
18461     {
18462       mp->is_ipv6 = 0;
18463       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
18464     }
18465
18466   mp->mask_length = length;
18467   mp->number_of_ranges = vec_len (low_ports);
18468
18469   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
18470   vec_free (low_ports);
18471
18472   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
18473   vec_free (high_ports);
18474
18475   mp->vrf_id = ntohl (vrf_id);
18476
18477   S (mp);
18478   W (ret);
18479   return ret;
18480 }
18481
18482 int
18483 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
18484 {
18485   unformat_input_t *input = vam->input;
18486   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
18487   u32 sw_if_index = ~0;
18488   int vrf_set = 0;
18489   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
18490   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
18491   u8 is_add = 1;
18492   int ret;
18493
18494   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18495     {
18496       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18497         ;
18498       else if (unformat (input, "sw_if_index %d", &sw_if_index))
18499         ;
18500       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
18501         vrf_set = 1;
18502       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
18503         vrf_set = 1;
18504       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
18505         vrf_set = 1;
18506       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
18507         vrf_set = 1;
18508       else if (unformat (input, "del"))
18509         is_add = 0;
18510       else
18511         break;
18512     }
18513
18514   if (sw_if_index == ~0)
18515     {
18516       errmsg ("Interface required but not specified");
18517       return -99;
18518     }
18519
18520   if (vrf_set == 0)
18521     {
18522       errmsg ("VRF ID required but not specified");
18523       return -99;
18524     }
18525
18526   if (tcp_out_vrf_id == 0
18527       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
18528     {
18529       errmsg
18530         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
18531       return -99;
18532     }
18533
18534   /* Construct the API message */
18535   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
18536
18537   mp->sw_if_index = ntohl (sw_if_index);
18538   mp->is_add = is_add;
18539   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
18540   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
18541   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
18542   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
18543
18544   /* send it... */
18545   S (mp);
18546
18547   /* Wait for a reply... */
18548   W (ret);
18549   return ret;
18550 }
18551
18552 static int
18553 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
18554 {
18555   unformat_input_t *i = vam->input;
18556   vl_api_ipsec_gre_add_del_tunnel_t *mp;
18557   u32 local_sa_id = 0;
18558   u32 remote_sa_id = 0;
18559   ip4_address_t src_address;
18560   ip4_address_t dst_address;
18561   u8 is_add = 1;
18562   int ret;
18563
18564   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18565     {
18566       if (unformat (i, "local_sa %d", &local_sa_id))
18567         ;
18568       else if (unformat (i, "remote_sa %d", &remote_sa_id))
18569         ;
18570       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
18571         ;
18572       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
18573         ;
18574       else if (unformat (i, "del"))
18575         is_add = 0;
18576       else
18577         {
18578           clib_warning ("parse error '%U'", format_unformat_error, i);
18579           return -99;
18580         }
18581     }
18582
18583   M (IPSEC_GRE_ADD_DEL_TUNNEL, mp);
18584
18585   mp->local_sa_id = ntohl (local_sa_id);
18586   mp->remote_sa_id = ntohl (remote_sa_id);
18587   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
18588   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
18589   mp->is_add = is_add;
18590
18591   S (mp);
18592   W (ret);
18593   return ret;
18594 }
18595
18596 static int
18597 api_punt (vat_main_t * vam)
18598 {
18599   unformat_input_t *i = vam->input;
18600   vl_api_punt_t *mp;
18601   u32 ipv = ~0;
18602   u32 protocol = ~0;
18603   u32 port = ~0;
18604   int is_add = 1;
18605   int ret;
18606
18607   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18608     {
18609       if (unformat (i, "ip %d", &ipv))
18610         ;
18611       else if (unformat (i, "protocol %d", &protocol))
18612         ;
18613       else if (unformat (i, "port %d", &port))
18614         ;
18615       else if (unformat (i, "del"))
18616         is_add = 0;
18617       else
18618         {
18619           clib_warning ("parse error '%U'", format_unformat_error, i);
18620           return -99;
18621         }
18622     }
18623
18624   M (PUNT, mp);
18625
18626   mp->is_add = (u8) is_add;
18627   mp->ipv = (u8) ipv;
18628   mp->l4_protocol = (u8) protocol;
18629   mp->l4_port = htons ((u16) port);
18630
18631   S (mp);
18632   W (ret);
18633   return ret;
18634 }
18635
18636 static void vl_api_ipsec_gre_tunnel_details_t_handler
18637   (vl_api_ipsec_gre_tunnel_details_t * mp)
18638 {
18639   vat_main_t *vam = &vat_main;
18640
18641   print (vam->ofp, "%11d%15U%15U%14d%14d",
18642          ntohl (mp->sw_if_index),
18643          format_ip4_address, &mp->src_address,
18644          format_ip4_address, &mp->dst_address,
18645          ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
18646 }
18647
18648 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
18649   (vl_api_ipsec_gre_tunnel_details_t * mp)
18650 {
18651   vat_main_t *vam = &vat_main;
18652   vat_json_node_t *node = NULL;
18653   struct in_addr ip4;
18654
18655   if (VAT_JSON_ARRAY != vam->json_tree.type)
18656     {
18657       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18658       vat_json_init_array (&vam->json_tree);
18659     }
18660   node = vat_json_array_add (&vam->json_tree);
18661
18662   vat_json_init_object (node);
18663   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
18664   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
18665   vat_json_object_add_ip4 (node, "src_address", ip4);
18666   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
18667   vat_json_object_add_ip4 (node, "dst_address", ip4);
18668   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
18669   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
18670 }
18671
18672 static int
18673 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
18674 {
18675   unformat_input_t *i = vam->input;
18676   vl_api_ipsec_gre_tunnel_dump_t *mp;
18677   vl_api_control_ping_t *mp_ping;
18678   u32 sw_if_index;
18679   u8 sw_if_index_set = 0;
18680   int ret;
18681
18682   /* Parse args required to build the message */
18683   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18684     {
18685       if (unformat (i, "sw_if_index %d", &sw_if_index))
18686         sw_if_index_set = 1;
18687       else
18688         break;
18689     }
18690
18691   if (sw_if_index_set == 0)
18692     {
18693       sw_if_index = ~0;
18694     }
18695
18696   if (!vam->json_output)
18697     {
18698       print (vam->ofp, "%11s%15s%15s%14s%14s",
18699              "sw_if_index", "src_address", "dst_address",
18700              "local_sa_id", "remote_sa_id");
18701     }
18702
18703   /* Get list of gre-tunnel interfaces */
18704   M (IPSEC_GRE_TUNNEL_DUMP, mp);
18705
18706   mp->sw_if_index = htonl (sw_if_index);
18707
18708   S (mp);
18709
18710   /* Use a control ping for synchronization */
18711   M (CONTROL_PING, mp_ping);
18712   S (mp_ping);
18713
18714   W (ret);
18715   return ret;
18716 }
18717
18718 static int
18719 api_delete_subif (vat_main_t * vam)
18720 {
18721   unformat_input_t *i = vam->input;
18722   vl_api_delete_subif_t *mp;
18723   u32 sw_if_index = ~0;
18724   int ret;
18725
18726   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18727     {
18728       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18729         ;
18730       if (unformat (i, "sw_if_index %d", &sw_if_index))
18731         ;
18732       else
18733         break;
18734     }
18735
18736   if (sw_if_index == ~0)
18737     {
18738       errmsg ("missing sw_if_index");
18739       return -99;
18740     }
18741
18742   /* Construct the API message */
18743   M (DELETE_SUBIF, mp);
18744   mp->sw_if_index = ntohl (sw_if_index);
18745
18746   S (mp);
18747   W (ret);
18748   return ret;
18749 }
18750
18751 #define foreach_pbb_vtr_op      \
18752 _("disable",  L2_VTR_DISABLED)  \
18753 _("pop",  L2_VTR_POP_2)         \
18754 _("push",  L2_VTR_PUSH_2)
18755
18756 static int
18757 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
18758 {
18759   unformat_input_t *i = vam->input;
18760   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
18761   u32 sw_if_index = ~0, vtr_op = ~0;
18762   u16 outer_tag = ~0;
18763   u8 dmac[6], smac[6];
18764   u8 dmac_set = 0, smac_set = 0;
18765   u16 vlanid = 0;
18766   u32 sid = ~0;
18767   u32 tmp;
18768   int ret;
18769
18770   /* Shut up coverity */
18771   memset (dmac, 0, sizeof (dmac));
18772   memset (smac, 0, sizeof (smac));
18773
18774   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18775     {
18776       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18777         ;
18778       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18779         ;
18780       else if (unformat (i, "vtr_op %d", &vtr_op))
18781         ;
18782 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
18783       foreach_pbb_vtr_op
18784 #undef _
18785         else if (unformat (i, "translate_pbb_stag"))
18786         {
18787           if (unformat (i, "%d", &tmp))
18788             {
18789               vtr_op = L2_VTR_TRANSLATE_2_1;
18790               outer_tag = tmp;
18791             }
18792           else
18793             {
18794               errmsg
18795                 ("translate_pbb_stag operation requires outer tag definition");
18796               return -99;
18797             }
18798         }
18799       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
18800         dmac_set++;
18801       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
18802         smac_set++;
18803       else if (unformat (i, "sid %d", &sid))
18804         ;
18805       else if (unformat (i, "vlanid %d", &tmp))
18806         vlanid = tmp;
18807       else
18808         {
18809           clib_warning ("parse error '%U'", format_unformat_error, i);
18810           return -99;
18811         }
18812     }
18813
18814   if ((sw_if_index == ~0) || (vtr_op == ~0))
18815     {
18816       errmsg ("missing sw_if_index or vtr operation");
18817       return -99;
18818     }
18819   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
18820       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
18821     {
18822       errmsg
18823         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
18824       return -99;
18825     }
18826
18827   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
18828   mp->sw_if_index = ntohl (sw_if_index);
18829   mp->vtr_op = ntohl (vtr_op);
18830   mp->outer_tag = ntohs (outer_tag);
18831   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
18832   clib_memcpy (mp->b_smac, smac, sizeof (smac));
18833   mp->b_vlanid = ntohs (vlanid);
18834   mp->i_sid = ntohl (sid);
18835
18836   S (mp);
18837   W (ret);
18838   return ret;
18839 }
18840
18841 static int
18842 api_flow_classify_set_interface (vat_main_t * vam)
18843 {
18844   unformat_input_t *i = vam->input;
18845   vl_api_flow_classify_set_interface_t *mp;
18846   u32 sw_if_index;
18847   int sw_if_index_set;
18848   u32 ip4_table_index = ~0;
18849   u32 ip6_table_index = ~0;
18850   u8 is_add = 1;
18851   int ret;
18852
18853   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18854     {
18855       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18856         sw_if_index_set = 1;
18857       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18858         sw_if_index_set = 1;
18859       else if (unformat (i, "del"))
18860         is_add = 0;
18861       else if (unformat (i, "ip4-table %d", &ip4_table_index))
18862         ;
18863       else if (unformat (i, "ip6-table %d", &ip6_table_index))
18864         ;
18865       else
18866         {
18867           clib_warning ("parse error '%U'", format_unformat_error, i);
18868           return -99;
18869         }
18870     }
18871
18872   if (sw_if_index_set == 0)
18873     {
18874       errmsg ("missing interface name or sw_if_index");
18875       return -99;
18876     }
18877
18878   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
18879
18880   mp->sw_if_index = ntohl (sw_if_index);
18881   mp->ip4_table_index = ntohl (ip4_table_index);
18882   mp->ip6_table_index = ntohl (ip6_table_index);
18883   mp->is_add = is_add;
18884
18885   S (mp);
18886   W (ret);
18887   return ret;
18888 }
18889
18890 static int
18891 api_flow_classify_dump (vat_main_t * vam)
18892 {
18893   unformat_input_t *i = vam->input;
18894   vl_api_flow_classify_dump_t *mp;
18895   vl_api_control_ping_t *mp_ping;
18896   u8 type = FLOW_CLASSIFY_N_TABLES;
18897   int ret;
18898
18899   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
18900     ;
18901   else
18902     {
18903       errmsg ("classify table type must be specified");
18904       return -99;
18905     }
18906
18907   if (!vam->json_output)
18908     {
18909       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
18910     }
18911
18912   M (FLOW_CLASSIFY_DUMP, mp);
18913   mp->type = type;
18914   /* send it... */
18915   S (mp);
18916
18917   /* Use a control ping for synchronization */
18918   M (CONTROL_PING, mp_ping);
18919   S (mp_ping);
18920
18921   /* Wait for a reply... */
18922   W (ret);
18923   return ret;
18924 }
18925
18926 static int
18927 api_feature_enable_disable (vat_main_t * vam)
18928 {
18929   unformat_input_t *i = vam->input;
18930   vl_api_feature_enable_disable_t *mp;
18931   u8 *arc_name = 0;
18932   u8 *feature_name = 0;
18933   u32 sw_if_index = ~0;
18934   u8 enable = 1;
18935   int ret;
18936
18937   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18938     {
18939       if (unformat (i, "arc_name %s", &arc_name))
18940         ;
18941       else if (unformat (i, "feature_name %s", &feature_name))
18942         ;
18943       else
18944         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18945         ;
18946       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18947         ;
18948       else if (unformat (i, "disable"))
18949         enable = 0;
18950       else
18951         break;
18952     }
18953
18954   if (arc_name == 0)
18955     {
18956       errmsg ("missing arc name");
18957       return -99;
18958     }
18959   if (vec_len (arc_name) > 63)
18960     {
18961       errmsg ("arc name too long");
18962     }
18963
18964   if (feature_name == 0)
18965     {
18966       errmsg ("missing feature name");
18967       return -99;
18968     }
18969   if (vec_len (feature_name) > 63)
18970     {
18971       errmsg ("feature name too long");
18972     }
18973
18974   if (sw_if_index == ~0)
18975     {
18976       errmsg ("missing interface name or sw_if_index");
18977       return -99;
18978     }
18979
18980   /* Construct the API message */
18981   M (FEATURE_ENABLE_DISABLE, mp);
18982   mp->sw_if_index = ntohl (sw_if_index);
18983   mp->enable = enable;
18984   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
18985   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
18986   vec_free (arc_name);
18987   vec_free (feature_name);
18988
18989   S (mp);
18990   W (ret);
18991   return ret;
18992 }
18993
18994 static int
18995 api_sw_interface_tag_add_del (vat_main_t * vam)
18996 {
18997   unformat_input_t *i = vam->input;
18998   vl_api_sw_interface_tag_add_del_t *mp;
18999   u32 sw_if_index = ~0;
19000   u8 *tag = 0;
19001   u8 enable = 1;
19002   int ret;
19003
19004   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19005     {
19006       if (unformat (i, "tag %s", &tag))
19007         ;
19008       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19009         ;
19010       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19011         ;
19012       else if (unformat (i, "del"))
19013         enable = 0;
19014       else
19015         break;
19016     }
19017
19018   if (sw_if_index == ~0)
19019     {
19020       errmsg ("missing interface name or sw_if_index");
19021       return -99;
19022     }
19023
19024   if (enable && (tag == 0))
19025     {
19026       errmsg ("no tag specified");
19027       return -99;
19028     }
19029
19030   /* Construct the API message */
19031   M (SW_INTERFACE_TAG_ADD_DEL, mp);
19032   mp->sw_if_index = ntohl (sw_if_index);
19033   mp->is_add = enable;
19034   if (enable)
19035     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
19036   vec_free (tag);
19037
19038   S (mp);
19039   W (ret);
19040   return ret;
19041 }
19042
19043 static void vl_api_l2_xconnect_details_t_handler
19044   (vl_api_l2_xconnect_details_t * mp)
19045 {
19046   vat_main_t *vam = &vat_main;
19047
19048   print (vam->ofp, "%15d%15d",
19049          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
19050 }
19051
19052 static void vl_api_l2_xconnect_details_t_handler_json
19053   (vl_api_l2_xconnect_details_t * mp)
19054 {
19055   vat_main_t *vam = &vat_main;
19056   vat_json_node_t *node = NULL;
19057
19058   if (VAT_JSON_ARRAY != vam->json_tree.type)
19059     {
19060       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19061       vat_json_init_array (&vam->json_tree);
19062     }
19063   node = vat_json_array_add (&vam->json_tree);
19064
19065   vat_json_init_object (node);
19066   vat_json_object_add_uint (node, "rx_sw_if_index",
19067                             ntohl (mp->rx_sw_if_index));
19068   vat_json_object_add_uint (node, "tx_sw_if_index",
19069                             ntohl (mp->tx_sw_if_index));
19070 }
19071
19072 static int
19073 api_l2_xconnect_dump (vat_main_t * vam)
19074 {
19075   vl_api_l2_xconnect_dump_t *mp;
19076   vl_api_control_ping_t *mp_ping;
19077   int ret;
19078
19079   if (!vam->json_output)
19080     {
19081       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
19082     }
19083
19084   M (L2_XCONNECT_DUMP, mp);
19085
19086   S (mp);
19087
19088   /* Use a control ping for synchronization */
19089   M (CONTROL_PING, mp_ping);
19090   S (mp_ping);
19091
19092   W (ret);
19093   return ret;
19094 }
19095
19096 static int
19097 api_sw_interface_set_mtu (vat_main_t * vam)
19098 {
19099   unformat_input_t *i = vam->input;
19100   vl_api_sw_interface_set_mtu_t *mp;
19101   u32 sw_if_index = ~0;
19102   u32 mtu = 0;
19103   int ret;
19104
19105   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19106     {
19107       if (unformat (i, "mtu %d", &mtu))
19108         ;
19109       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19110         ;
19111       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19112         ;
19113       else
19114         break;
19115     }
19116
19117   if (sw_if_index == ~0)
19118     {
19119       errmsg ("missing interface name or sw_if_index");
19120       return -99;
19121     }
19122
19123   if (mtu == 0)
19124     {
19125       errmsg ("no mtu specified");
19126       return -99;
19127     }
19128
19129   /* Construct the API message */
19130   M (SW_INTERFACE_SET_MTU, mp);
19131   mp->sw_if_index = ntohl (sw_if_index);
19132   mp->mtu = ntohs ((u16) mtu);
19133
19134   S (mp);
19135   W (ret);
19136   return ret;
19137 }
19138
19139 static int
19140 api_p2p_ethernet_add (vat_main_t * vam)
19141 {
19142   unformat_input_t *i = vam->input;
19143   vl_api_p2p_ethernet_add_t *mp;
19144   u32 parent_if_index = ~0;
19145   u8 remote_mac[6];
19146   u8 mac_set = 0;
19147   int ret;
19148
19149   memset (remote_mac, 0, sizeof (remote_mac));
19150   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19151     {
19152       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
19153         ;
19154       else if (unformat (i, "sw_if_index %d", &parent_if_index))
19155         ;
19156       else
19157         if (unformat
19158             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
19159         mac_set++;
19160       else
19161         {
19162           clib_warning ("parse error '%U'", format_unformat_error, i);
19163           return -99;
19164         }
19165     }
19166
19167   if (parent_if_index == ~0)
19168     {
19169       errmsg ("missing interface name or sw_if_index");
19170       return -99;
19171     }
19172   if (mac_set == 0)
19173     {
19174       errmsg ("missing remote mac address");
19175       return -99;
19176     }
19177
19178   M (P2P_ETHERNET_ADD, mp);
19179   mp->parent_if_index = ntohl (parent_if_index);
19180   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
19181
19182   S (mp);
19183   W (ret);
19184   return ret;
19185 }
19186
19187 static int
19188 api_p2p_ethernet_del (vat_main_t * vam)
19189 {
19190   unformat_input_t *i = vam->input;
19191   vl_api_p2p_ethernet_del_t *mp;
19192   u32 parent_if_index = ~0;
19193   u8 remote_mac[6];
19194   u8 mac_set = 0;
19195   int ret;
19196
19197   memset (remote_mac, 0, sizeof (remote_mac));
19198   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19199     {
19200       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
19201         ;
19202       else if (unformat (i, "sw_if_index %d", &parent_if_index))
19203         ;
19204       else
19205         if (unformat
19206             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
19207         mac_set++;
19208       else
19209         {
19210           clib_warning ("parse error '%U'", format_unformat_error, i);
19211           return -99;
19212         }
19213     }
19214
19215   if (parent_if_index == ~0)
19216     {
19217       errmsg ("missing interface name or sw_if_index");
19218       return -99;
19219     }
19220   if (mac_set == 0)
19221     {
19222       errmsg ("missing remote mac address");
19223       return -99;
19224     }
19225
19226   M (P2P_ETHERNET_DEL, mp);
19227   mp->parent_if_index = ntohl (parent_if_index);
19228   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
19229
19230   S (mp);
19231   W (ret);
19232   return ret;
19233 }
19234
19235 static int
19236 q_or_quit (vat_main_t * vam)
19237 {
19238 #if VPP_API_TEST_BUILTIN == 0
19239   longjmp (vam->jump_buf, 1);
19240 #endif
19241   return 0;                     /* not so much */
19242 }
19243
19244 static int
19245 q (vat_main_t * vam)
19246 {
19247   return q_or_quit (vam);
19248 }
19249
19250 static int
19251 quit (vat_main_t * vam)
19252 {
19253   return q_or_quit (vam);
19254 }
19255
19256 static int
19257 comment (vat_main_t * vam)
19258 {
19259   return 0;
19260 }
19261
19262 static int
19263 cmd_cmp (void *a1, void *a2)
19264 {
19265   u8 **c1 = a1;
19266   u8 **c2 = a2;
19267
19268   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
19269 }
19270
19271 static int
19272 help (vat_main_t * vam)
19273 {
19274   u8 **cmds = 0;
19275   u8 *name = 0;
19276   hash_pair_t *p;
19277   unformat_input_t *i = vam->input;
19278   int j;
19279
19280   if (unformat (i, "%s", &name))
19281     {
19282       uword *hs;
19283
19284       vec_add1 (name, 0);
19285
19286       hs = hash_get_mem (vam->help_by_name, name);
19287       if (hs)
19288         print (vam->ofp, "usage: %s %s", name, hs[0]);
19289       else
19290         print (vam->ofp, "No such msg / command '%s'", name);
19291       vec_free (name);
19292       return 0;
19293     }
19294
19295   print (vam->ofp, "Help is available for the following:");
19296
19297     /* *INDENT-OFF* */
19298     hash_foreach_pair (p, vam->function_by_name,
19299     ({
19300       vec_add1 (cmds, (u8 *)(p->key));
19301     }));
19302     /* *INDENT-ON* */
19303
19304   vec_sort_with_function (cmds, cmd_cmp);
19305
19306   for (j = 0; j < vec_len (cmds); j++)
19307     print (vam->ofp, "%s", cmds[j]);
19308
19309   vec_free (cmds);
19310   return 0;
19311 }
19312
19313 static int
19314 set (vat_main_t * vam)
19315 {
19316   u8 *name = 0, *value = 0;
19317   unformat_input_t *i = vam->input;
19318
19319   if (unformat (i, "%s", &name))
19320     {
19321       /* The input buffer is a vector, not a string. */
19322       value = vec_dup (i->buffer);
19323       vec_delete (value, i->index, 0);
19324       /* Almost certainly has a trailing newline */
19325       if (value[vec_len (value) - 1] == '\n')
19326         value[vec_len (value) - 1] = 0;
19327       /* Make sure it's a proper string, one way or the other */
19328       vec_add1 (value, 0);
19329       (void) clib_macro_set_value (&vam->macro_main,
19330                                    (char *) name, (char *) value);
19331     }
19332   else
19333     errmsg ("usage: set <name> <value>");
19334
19335   vec_free (name);
19336   vec_free (value);
19337   return 0;
19338 }
19339
19340 static int
19341 unset (vat_main_t * vam)
19342 {
19343   u8 *name = 0;
19344
19345   if (unformat (vam->input, "%s", &name))
19346     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
19347       errmsg ("unset: %s wasn't set", name);
19348   vec_free (name);
19349   return 0;
19350 }
19351
19352 typedef struct
19353 {
19354   u8 *name;
19355   u8 *value;
19356 } macro_sort_t;
19357
19358
19359 static int
19360 macro_sort_cmp (void *a1, void *a2)
19361 {
19362   macro_sort_t *s1 = a1;
19363   macro_sort_t *s2 = a2;
19364
19365   return strcmp ((char *) (s1->name), (char *) (s2->name));
19366 }
19367
19368 static int
19369 dump_macro_table (vat_main_t * vam)
19370 {
19371   macro_sort_t *sort_me = 0, *sm;
19372   int i;
19373   hash_pair_t *p;
19374
19375     /* *INDENT-OFF* */
19376     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
19377     ({
19378       vec_add2 (sort_me, sm, 1);
19379       sm->name = (u8 *)(p->key);
19380       sm->value = (u8 *) (p->value[0]);
19381     }));
19382     /* *INDENT-ON* */
19383
19384   vec_sort_with_function (sort_me, macro_sort_cmp);
19385
19386   if (vec_len (sort_me))
19387     print (vam->ofp, "%-15s%s", "Name", "Value");
19388   else
19389     print (vam->ofp, "The macro table is empty...");
19390
19391   for (i = 0; i < vec_len (sort_me); i++)
19392     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
19393   return 0;
19394 }
19395
19396 static int
19397 dump_node_table (vat_main_t * vam)
19398 {
19399   int i, j;
19400   vlib_node_t *node, *next_node;
19401
19402   if (vec_len (vam->graph_nodes) == 0)
19403     {
19404       print (vam->ofp, "Node table empty, issue get_node_graph...");
19405       return 0;
19406     }
19407
19408   for (i = 0; i < vec_len (vam->graph_nodes); i++)
19409     {
19410       node = vam->graph_nodes[i];
19411       print (vam->ofp, "[%d] %s", i, node->name);
19412       for (j = 0; j < vec_len (node->next_nodes); j++)
19413         {
19414           if (node->next_nodes[j] != ~0)
19415             {
19416               next_node = vam->graph_nodes[node->next_nodes[j]];
19417               print (vam->ofp, "  [%d] %s", j, next_node->name);
19418             }
19419         }
19420     }
19421   return 0;
19422 }
19423
19424 static int
19425 value_sort_cmp (void *a1, void *a2)
19426 {
19427   name_sort_t *n1 = a1;
19428   name_sort_t *n2 = a2;
19429
19430   if (n1->value < n2->value)
19431     return -1;
19432   if (n1->value > n2->value)
19433     return 1;
19434   return 0;
19435 }
19436
19437
19438 static int
19439 dump_msg_api_table (vat_main_t * vam)
19440 {
19441   api_main_t *am = &api_main;
19442   name_sort_t *nses = 0, *ns;
19443   hash_pair_t *hp;
19444   int i;
19445
19446   /* *INDENT-OFF* */
19447   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
19448   ({
19449     vec_add2 (nses, ns, 1);
19450     ns->name = (u8 *)(hp->key);
19451     ns->value = (u32) hp->value[0];
19452   }));
19453   /* *INDENT-ON* */
19454
19455   vec_sort_with_function (nses, value_sort_cmp);
19456
19457   for (i = 0; i < vec_len (nses); i++)
19458     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
19459   vec_free (nses);
19460   return 0;
19461 }
19462
19463 static int
19464 get_msg_id (vat_main_t * vam)
19465 {
19466   u8 *name_and_crc;
19467   u32 message_index;
19468
19469   if (unformat (vam->input, "%s", &name_and_crc))
19470     {
19471       message_index = vl_api_get_msg_index (name_and_crc);
19472       if (message_index == ~0)
19473         {
19474           print (vam->ofp, " '%s' not found", name_and_crc);
19475           return 0;
19476         }
19477       print (vam->ofp, " '%s' has message index %d",
19478              name_and_crc, message_index);
19479       return 0;
19480     }
19481   errmsg ("name_and_crc required...");
19482   return 0;
19483 }
19484
19485 static int
19486 search_node_table (vat_main_t * vam)
19487 {
19488   unformat_input_t *line_input = vam->input;
19489   u8 *node_to_find;
19490   int j;
19491   vlib_node_t *node, *next_node;
19492   uword *p;
19493
19494   if (vam->graph_node_index_by_name == 0)
19495     {
19496       print (vam->ofp, "Node table empty, issue get_node_graph...");
19497       return 0;
19498     }
19499
19500   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
19501     {
19502       if (unformat (line_input, "%s", &node_to_find))
19503         {
19504           vec_add1 (node_to_find, 0);
19505           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
19506           if (p == 0)
19507             {
19508               print (vam->ofp, "%s not found...", node_to_find);
19509               goto out;
19510             }
19511           node = vam->graph_nodes[p[0]];
19512           print (vam->ofp, "[%d] %s", p[0], node->name);
19513           for (j = 0; j < vec_len (node->next_nodes); j++)
19514             {
19515               if (node->next_nodes[j] != ~0)
19516                 {
19517                   next_node = vam->graph_nodes[node->next_nodes[j]];
19518                   print (vam->ofp, "  [%d] %s", j, next_node->name);
19519                 }
19520             }
19521         }
19522
19523       else
19524         {
19525           clib_warning ("parse error '%U'", format_unformat_error,
19526                         line_input);
19527           return -99;
19528         }
19529
19530     out:
19531       vec_free (node_to_find);
19532
19533     }
19534
19535   return 0;
19536 }
19537
19538
19539 static int
19540 script (vat_main_t * vam)
19541 {
19542 #if (VPP_API_TEST_BUILTIN==0)
19543   u8 *s = 0;
19544   char *save_current_file;
19545   unformat_input_t save_input;
19546   jmp_buf save_jump_buf;
19547   u32 save_line_number;
19548
19549   FILE *new_fp, *save_ifp;
19550
19551   if (unformat (vam->input, "%s", &s))
19552     {
19553       new_fp = fopen ((char *) s, "r");
19554       if (new_fp == 0)
19555         {
19556           errmsg ("Couldn't open script file %s", s);
19557           vec_free (s);
19558           return -99;
19559         }
19560     }
19561   else
19562     {
19563       errmsg ("Missing script name");
19564       return -99;
19565     }
19566
19567   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
19568   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
19569   save_ifp = vam->ifp;
19570   save_line_number = vam->input_line_number;
19571   save_current_file = (char *) vam->current_file;
19572
19573   vam->input_line_number = 0;
19574   vam->ifp = new_fp;
19575   vam->current_file = s;
19576   do_one_file (vam);
19577
19578   clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
19579   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
19580   vam->ifp = save_ifp;
19581   vam->input_line_number = save_line_number;
19582   vam->current_file = (u8 *) save_current_file;
19583   vec_free (s);
19584
19585   return 0;
19586 #else
19587   clib_warning ("use the exec command...");
19588   return -99;
19589 #endif
19590 }
19591
19592 static int
19593 echo (vat_main_t * vam)
19594 {
19595   print (vam->ofp, "%v", vam->input->buffer);
19596   return 0;
19597 }
19598
19599 /* List of API message constructors, CLI names map to api_xxx */
19600 #define foreach_vpe_api_msg                                             \
19601 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
19602 _(sw_interface_dump,"")                                                 \
19603 _(sw_interface_set_flags,                                               \
19604   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
19605 _(sw_interface_add_del_address,                                         \
19606   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
19607 _(sw_interface_set_table,                                               \
19608   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
19609 _(sw_interface_set_mpls_enable,                                         \
19610   "<intfc> | sw_if_index [disable | dis]")                              \
19611 _(sw_interface_set_vpath,                                               \
19612   "<intfc> | sw_if_index <id> enable | disable")                        \
19613 _(sw_interface_set_vxlan_bypass,                                        \
19614   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
19615 _(sw_interface_set_l2_xconnect,                                         \
19616   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
19617   "enable | disable")                                                   \
19618 _(sw_interface_set_l2_bridge,                                           \
19619   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
19620   "[shg <split-horizon-group>] [bvi]\n"                                 \
19621   "enable | disable")                                                   \
19622 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
19623 _(bridge_domain_add_del,                                                \
19624   "bd_id <bridge-domain-id> [flood 1|0] [uu-flood 1|0] [forward 1|0] [learn 1|0] [arp-term 1|0] [mac-age 0-255] [del]\n") \
19625 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
19626 _(l2fib_add_del,                                                        \
19627   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
19628 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
19629 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
19630 _(l2_flags,                                                             \
19631   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood]\n") \
19632 _(bridge_flags,                                                         \
19633   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
19634 _(tap_connect,                                                          \
19635   "tapname <name> mac <mac-addr> | random-mac [tag <string>]")          \
19636 _(tap_modify,                                                           \
19637   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
19638 _(tap_delete,                                                           \
19639   "<vpp-if-name> | sw_if_index <id>")                                   \
19640 _(sw_interface_tap_dump, "")                                            \
19641 _(ip_add_del_route,                                                     \
19642   "<addr>/<mask> via <addr> [table-id <n>]\n"                           \
19643   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
19644   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
19645   "[multipath] [count <n>]")                                            \
19646 _(ip_mroute_add_del,                                                    \
19647   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
19648   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
19649 _(mpls_route_add_del,                                                   \
19650   "<label> <eos> via <addr> [table-id <n>]\n"                           \
19651   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
19652   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
19653   "[multipath] [count <n>]")                                            \
19654 _(mpls_ip_bind_unbind,                                                  \
19655   "<label> <addr/len>")                                                 \
19656 _(mpls_tunnel_add_del,                                                  \
19657   " via <addr> [table-id <n>]\n"                                        \
19658   "sw_if_index <id>] [l2]  [del]")                                      \
19659 _(proxy_arp_add_del,                                                    \
19660   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
19661 _(proxy_arp_intfc_enable_disable,                                       \
19662   "<intfc> | sw_if_index <id> enable | disable")                        \
19663 _(sw_interface_set_unnumbered,                                          \
19664   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
19665 _(ip_neighbor_add_del,                                                  \
19666   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
19667   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
19668 _(reset_vrf, "vrf <id> [ipv6]")                                         \
19669 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
19670 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
19671   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
19672   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
19673   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
19674 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
19675 _(reset_fib, "vrf <n> [ipv6]")                                          \
19676 _(dhcp_proxy_config,                                                    \
19677   "svr <v46-address> src <v46-address>\n"                               \
19678    "rx_vrf_id <nn> server_vrf_id <nn>  [del]")                          \
19679 _(dhcp_proxy_set_vss,                                                   \
19680   "tbl_id <n> fib_id <n> oui <n> [ipv6] [del]")                         \
19681 _(dhcp_proxy_dump, "ip6")                                               \
19682 _(dhcp_client_config,                                                   \
19683   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
19684 _(set_ip_flow_hash,                                                     \
19685   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
19686 _(sw_interface_ip6_enable_disable,                                      \
19687   "<intfc> | sw_if_index <id> enable | disable")                        \
19688 _(sw_interface_ip6_set_link_local_address,                              \
19689   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
19690 _(ip6nd_proxy_add_del,                                                  \
19691   "<intfc> | sw_if_index <id> <ip6-address>")                           \
19692 _(ip6nd_proxy_dump, "")                                                 \
19693 _(sw_interface_ip6nd_ra_prefix,                                         \
19694   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
19695   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
19696   "[nolink] [isno]")                                                    \
19697 _(sw_interface_ip6nd_ra_config,                                         \
19698   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
19699   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
19700   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
19701 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
19702 _(l2_patch_add_del,                                                     \
19703   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
19704   "enable | disable")                                                   \
19705 _(sr_localsid_add_del,                                                  \
19706   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
19707   "fib-table <num> (end.psp) sw_if_index <num>")                        \
19708 _(classify_add_del_table,                                               \
19709   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
19710   " [del] [del-chain] mask <mask-value>\n"                              \
19711   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
19712   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
19713 _(classify_add_del_session,                                             \
19714   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
19715   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
19716   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
19717   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
19718 _(classify_set_interface_ip_table,                                      \
19719   "<intfc> | sw_if_index <nn> table <nn>")                              \
19720 _(classify_set_interface_l2_tables,                                     \
19721   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
19722   "  [other-table <nn>]")                                               \
19723 _(get_node_index, "node <node-name")                                    \
19724 _(add_node_next, "node <node-name> next <next-node-name>")              \
19725 _(l2tpv3_create_tunnel,                                                 \
19726   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
19727   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
19728   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
19729 _(l2tpv3_set_tunnel_cookies,                                            \
19730   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
19731   "[new_remote_cookie <nn>]\n")                                         \
19732 _(l2tpv3_interface_enable_disable,                                      \
19733   "<intfc> | sw_if_index <nn> enable | disable")                        \
19734 _(l2tpv3_set_lookup_key,                                                \
19735   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
19736 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
19737 _(vxlan_add_del_tunnel,                                                 \
19738   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
19739   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
19740   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
19741 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
19742 _(gre_add_del_tunnel,                                                   \
19743   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [teb] [del]\n")    \
19744 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
19745 _(l2_fib_clear_table, "")                                               \
19746 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
19747 _(l2_interface_vlan_tag_rewrite,                                        \
19748   "<intfc> | sw_if_index <nn> \n"                                       \
19749   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
19750   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
19751 _(create_vhost_user_if,                                                 \
19752         "socket <filename> [server] [renumber <dev_instance>] "         \
19753         "[mac <mac_address>]")                                          \
19754 _(modify_vhost_user_if,                                                 \
19755         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
19756         "[server] [renumber <dev_instance>]")                           \
19757 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
19758 _(sw_interface_vhost_user_dump, "")                                     \
19759 _(show_version, "")                                                     \
19760 _(vxlan_gpe_add_del_tunnel,                                             \
19761   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
19762   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
19763   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
19764   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
19765 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
19766 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
19767 _(interface_name_renumber,                                              \
19768   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
19769 _(input_acl_set_interface,                                              \
19770   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
19771   "  [l2-table <nn>] [del]")                                            \
19772 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
19773 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
19774 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
19775 _(ip_dump, "ipv4 | ipv6")                                               \
19776 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
19777 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
19778   "  spid_id <n> ")                                                     \
19779 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
19780   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
19781   "  integ_alg <alg> integ_key <hex>")                                  \
19782 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
19783   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
19784   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
19785   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
19786 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
19787 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
19788   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
19789   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
19790   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n")     \
19791 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
19792 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
19793   "(auth_data 0x<data> | auth_data <data>)")                            \
19794 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
19795   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
19796 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
19797   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
19798   "(local|remote)")                                                     \
19799 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
19800 _(ikev2_set_responder, "<profile_name> interface <interface> address <addr>") \
19801 _(ikev2_set_ike_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
19802 _(ikev2_set_esp_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
19803 _(ikev2_set_sa_lifetime, "<profile_name> <seconds> <jitter> <handover> <max bytes>") \
19804 _(ikev2_initiate_sa_init, "<profile_name>")                             \
19805 _(ikev2_initiate_del_ike_sa, "<ispi>")                                  \
19806 _(ikev2_initiate_del_child_sa, "<ispi>")                                \
19807 _(ikev2_initiate_rekey_child_sa, "<ispi>")                              \
19808 _(delete_loopback,"sw_if_index <nn>")                                   \
19809 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
19810 _(map_add_domain,                                                       \
19811   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
19812   "ip6-src <ip6addr> "                                                  \
19813   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
19814 _(map_del_domain, "index <n>")                                          \
19815 _(map_add_del_rule,                                                     \
19816   "index <n> psid <n> dst <ip6addr> [del]")                             \
19817 _(map_domain_dump, "")                                                  \
19818 _(map_rule_dump, "index <map-domain>")                                  \
19819 _(want_interface_events,  "enable|disable")                             \
19820 _(want_stats,"enable|disable")                                          \
19821 _(get_first_msg_id, "client <name>")                                    \
19822 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
19823 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
19824   "fib-id <nn> [ip4][ip6][default]")                                    \
19825 _(get_node_graph, " ")                                                  \
19826 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
19827 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
19828 _(ioam_disable, "")                                                     \
19829 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
19830                             " sw_if_index <sw_if_index> p <priority> "  \
19831                             "w <weight>] [del]")                        \
19832 _(one_add_del_locator, "locator-set <locator_name> "                    \
19833                         "iface <intf> | sw_if_index <sw_if_index> "     \
19834                         "p <priority> w <weight> [del]")                \
19835 _(one_add_del_local_eid,"vni <vni> eid "                                \
19836                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
19837                          "locator-set <locator_name> [del]"             \
19838                          "[key-id sha1|sha256 secret-key <secret-key>]")\
19839 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
19840 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
19841 _(one_enable_disable, "enable|disable")                                 \
19842 _(one_map_register_enable_disable, "enable|disable")                    \
19843 _(one_rloc_probe_enable_disable, "enable|disable")                      \
19844 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
19845                                "[seid <seid>] "                         \
19846                                "rloc <locator> p <prio> "               \
19847                                "w <weight> [rloc <loc> ... ] "          \
19848                                "action <action> [del-all]")             \
19849 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
19850                           "<local-eid>")                                \
19851 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
19852 _(one_use_petr, "ip-address> | disable")                                \
19853 _(one_map_request_mode, "src-dst|dst-only")                             \
19854 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
19855 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
19856 _(one_locator_set_dump, "[local | remote]")                             \
19857 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
19858 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
19859                        "[local] | [remote]")                            \
19860 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
19861 _(one_l2_arp_bd_get, "")                                                \
19862 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
19863 _(one_stats_enable_disable, "enable|disalbe")                           \
19864 _(show_one_stats_enable_disable, "")                                    \
19865 _(one_eid_table_vni_dump, "")                                           \
19866 _(one_eid_table_map_dump, "l2|l3")                                      \
19867 _(one_map_resolver_dump, "")                                            \
19868 _(one_map_server_dump, "")                                              \
19869 _(one_adjacencies_get, "vni <vni>")                                     \
19870 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
19871 _(show_one_rloc_probe_state, "")                                        \
19872 _(show_one_map_register_state, "")                                      \
19873 _(show_one_status, "")                                                  \
19874 _(one_stats_dump, "")                                                   \
19875 _(one_stats_flush, "")                                                  \
19876 _(one_get_map_request_itr_rlocs, "")                                    \
19877 _(show_one_nsh_mapping, "")                                             \
19878 _(show_one_pitr, "")                                                    \
19879 _(show_one_use_petr, "")                                                \
19880 _(show_one_map_request_mode, "")                                        \
19881 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
19882                             " sw_if_index <sw_if_index> p <priority> "  \
19883                             "w <weight>] [del]")                        \
19884 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
19885                         "iface <intf> | sw_if_index <sw_if_index> "     \
19886                         "p <priority> w <weight> [del]")                \
19887 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
19888                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
19889                          "locator-set <locator_name> [del]"             \
19890                          "[key-id sha1|sha256 secret-key <secret-key>]") \
19891 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
19892 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
19893 _(lisp_enable_disable, "enable|disable")                                \
19894 _(lisp_map_register_enable_disable, "enable|disable")                   \
19895 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
19896 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
19897                                "[seid <seid>] "                         \
19898                                "rloc <locator> p <prio> "               \
19899                                "w <weight> [rloc <loc> ... ] "          \
19900                                "action <action> [del-all]")             \
19901 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
19902                           "<local-eid>")                                \
19903 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
19904 _(lisp_use_petr, "<ip-address> | disable")                              \
19905 _(lisp_map_request_mode, "src-dst|dst-only")                            \
19906 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
19907 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
19908 _(lisp_locator_set_dump, "[local | remote]")                            \
19909 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
19910 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
19911                        "[local] | [remote]")                            \
19912 _(lisp_eid_table_vni_dump, "")                                          \
19913 _(lisp_eid_table_map_dump, "l2|l3")                                     \
19914 _(lisp_map_resolver_dump, "")                                           \
19915 _(lisp_map_server_dump, "")                                             \
19916 _(lisp_adjacencies_get, "vni <vni>")                                    \
19917 _(gpe_fwd_entry_vnis_get, "")                                           \
19918 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
19919 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
19920                                 "[table <table-id>]")                   \
19921 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
19922 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
19923 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
19924 _(gpe_get_encap_mode, "")                                               \
19925 _(lisp_gpe_add_del_iface, "up|down")                                    \
19926 _(lisp_gpe_enable_disable, "enable|disable")                            \
19927 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
19928   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
19929 _(show_lisp_rloc_probe_state, "")                                       \
19930 _(show_lisp_map_register_state, "")                                     \
19931 _(show_lisp_status, "")                                                 \
19932 _(lisp_get_map_request_itr_rlocs, "")                                   \
19933 _(show_lisp_pitr, "")                                                   \
19934 _(show_lisp_use_petr, "")                                               \
19935 _(show_lisp_map_request_mode, "")                                       \
19936 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
19937 _(af_packet_delete, "name <host interface name>")                       \
19938 _(policer_add_del, "name <policer name> <params> [del]")                \
19939 _(policer_dump, "[name <policer name>]")                                \
19940 _(policer_classify_set_interface,                                       \
19941   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
19942   "  [l2-table <nn>] [del]")                                            \
19943 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
19944 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
19945     "[master|slave]")                                                   \
19946 _(netmap_delete, "name <interface name>")                               \
19947 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
19948 _(mpls_fib_dump, "")                                                    \
19949 _(classify_table_ids, "")                                               \
19950 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
19951 _(classify_table_info, "table_id <nn>")                                 \
19952 _(classify_session_dump, "table_id <nn>")                               \
19953 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
19954     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
19955     "[template_interval <nn>] [udp_checksum]")                          \
19956 _(ipfix_exporter_dump, "")                                              \
19957 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
19958 _(ipfix_classify_stream_dump, "")                                       \
19959 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
19960 _(ipfix_classify_table_dump, "")                                        \
19961 _(sw_interface_span_enable_disable, "[src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
19962 _(sw_interface_span_dump, "")                                           \
19963 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
19964 _(pg_create_interface, "if_id <nn>")                                    \
19965 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
19966 _(pg_enable_disable, "[stream <id>] disable")                           \
19967 _(ip_source_and_port_range_check_add_del,                               \
19968   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
19969 _(ip_source_and_port_range_check_interface_add_del,                     \
19970   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
19971   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
19972 _(ipsec_gre_add_del_tunnel,                                             \
19973   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
19974 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
19975 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
19976 _(l2_interface_pbb_tag_rewrite,                                         \
19977   "<intfc> | sw_if_index <nn> \n"                                       \
19978   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
19979   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
19980 _(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
19981 _(flow_classify_set_interface,                                          \
19982   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
19983 _(flow_classify_dump, "type [ip4|ip6]")                                 \
19984 _(ip_fib_dump, "")                                                      \
19985 _(ip_mfib_dump, "")                                                     \
19986 _(ip6_fib_dump, "")                                                     \
19987 _(ip6_mfib_dump, "")                                                    \
19988 _(feature_enable_disable, "arc_name <arc_name> "                        \
19989   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
19990 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
19991 "[disable]")                                                            \
19992 _(l2_xconnect_dump, "")                                                 \
19993 _(sw_interface_set_mtu, "<intfc> | sw_if_index <nn> mtu <nn>")        \
19994 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
19995 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
19996 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
19997 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>")
19998
19999 /* List of command functions, CLI names map directly to functions */
20000 #define foreach_cli_function                                    \
20001 _(comment, "usage: comment <ignore-rest-of-line>")              \
20002 _(dump_interface_table, "usage: dump_interface_table")          \
20003 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
20004 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
20005 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
20006 _(dump_stats_table, "usage: dump_stats_table")                  \
20007 _(dump_macro_table, "usage: dump_macro_table ")                 \
20008 _(dump_node_table, "usage: dump_node_table")                    \
20009 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
20010 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
20011 _(echo, "usage: echo <message>")                                \
20012 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
20013 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
20014 _(help, "usage: help")                                          \
20015 _(q, "usage: quit")                                             \
20016 _(quit, "usage: quit")                                          \
20017 _(search_node_table, "usage: search_node_table <name>...")      \
20018 _(set, "usage: set <variable-name> <value>")                    \
20019 _(script, "usage: script <file-name>")                          \
20020 _(unset, "usage: unset <variable-name>")
20021
20022 #define _(N,n)                                  \
20023     static void vl_api_##n##_t_handler_uni      \
20024     (vl_api_##n##_t * mp)                       \
20025     {                                           \
20026         vat_main_t * vam = &vat_main;           \
20027         if (vam->json_output) {                 \
20028             vl_api_##n##_t_handler_json(mp);    \
20029         } else {                                \
20030             vl_api_##n##_t_handler(mp);         \
20031         }                                       \
20032     }
20033 foreach_vpe_api_reply_msg;
20034 #if VPP_API_TEST_BUILTIN == 0
20035 foreach_standalone_reply_msg;
20036 #endif
20037 #undef _
20038
20039 void
20040 vat_api_hookup (vat_main_t * vam)
20041 {
20042 #define _(N,n)                                                  \
20043     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
20044                            vl_api_##n##_t_handler_uni,          \
20045                            vl_noop_handler,                     \
20046                            vl_api_##n##_t_endian,               \
20047                            vl_api_##n##_t_print,                \
20048                            sizeof(vl_api_##n##_t), 1);
20049   foreach_vpe_api_reply_msg;
20050 #if VPP_API_TEST_BUILTIN == 0
20051   foreach_standalone_reply_msg;
20052 #endif
20053 #undef _
20054
20055 #if (VPP_API_TEST_BUILTIN==0)
20056   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
20057
20058   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
20059
20060   vam->function_by_name = hash_create_string (0, sizeof (uword));
20061
20062   vam->help_by_name = hash_create_string (0, sizeof (uword));
20063 #endif
20064
20065   /* API messages we can send */
20066 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
20067   foreach_vpe_api_msg;
20068 #undef _
20069
20070   /* Help strings */
20071 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
20072   foreach_vpe_api_msg;
20073 #undef _
20074
20075   /* CLI functions */
20076 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
20077   foreach_cli_function;
20078 #undef _
20079
20080   /* Help strings */
20081 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
20082   foreach_cli_function;
20083 #undef _
20084 }
20085
20086 #if VPP_API_TEST_BUILTIN
20087 static clib_error_t *
20088 vat_api_hookup_shim (vlib_main_t * vm)
20089 {
20090   vat_api_hookup (&vat_main);
20091   return 0;
20092 }
20093
20094 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
20095 #endif
20096
20097 /*
20098  * fd.io coding-style-patch-verification: ON
20099  *
20100  * Local Variables:
20101  * eval: (c-set-style "gnu")
20102  * End:
20103  */