Fix endian issue in ARP Event Reply
[vpp.git] / src / vat / api_format.c
1 /*
2  *------------------------------------------------------------------
3  * api_format.c
4  *
5  * Copyright (c) 2014-2016 Cisco and/or its affiliates.
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at:
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *------------------------------------------------------------------
18  */
19
20 #include <vat/vat.h>
21 #include <vlibapi/api.h>
22 #include <vlibmemory/api.h>
23 #include <vlibsocket/api.h>
24 #include <vnet/ip/ip.h>
25 #include <vnet/l2/l2_input.h>
26 #include <vnet/l2tp/l2tp.h>
27 #include <vnet/vxlan/vxlan.h>
28 #include <vnet/gre/gre.h>
29 #include <vnet/vxlan-gpe/vxlan_gpe.h>
30 #include <vnet/lisp-gpe/lisp_gpe.h>
31
32 #include <vpp/api/vpe_msg_enum.h>
33 #include <vnet/l2/l2_classify.h>
34 #include <vnet/l2/l2_vtr.h>
35 #include <vnet/classify/input_acl.h>
36 #include <vnet/classify/policer_classify.h>
37 #include <vnet/classify/flow_classify.h>
38 #include <vnet/mpls/mpls.h>
39 #include <vnet/ipsec/ipsec.h>
40 #include <vnet/ipsec/ikev2.h>
41 #include <inttypes.h>
42 #include <vnet/map/map.h>
43 #include <vnet/cop/cop.h>
44 #include <vnet/ip/ip6_hop_by_hop.h>
45 #include <vnet/ip/ip_source_and_port_range_check.h>
46 #include <vnet/policer/xlate.h>
47 #include <vnet/span/span.h>
48 #include <vnet/policer/policer.h>
49 #include <vnet/policer/police.h>
50 #include <vnet/mfib/mfib_types.h>
51
52 #include "vat/json_format.h"
53
54 #include <inttypes.h>
55 #include <sys/stat.h>
56
57 #define vl_typedefs             /* define message structures */
58 #include <vpp/api/vpe_all_api_h.h>
59 #undef vl_typedefs
60
61 /* declare message handlers for each api */
62
63 #define vl_endianfun            /* define message structures */
64 #include <vpp/api/vpe_all_api_h.h>
65 #undef vl_endianfun
66
67 /* instantiate all the print functions we know about */
68 #define vl_print(handle, ...)
69 #define vl_printfun
70 #include <vpp/api/vpe_all_api_h.h>
71 #undef vl_printfun
72
73 #define __plugin_msg_base 0
74 #include <vlibapi/vat_helper_macros.h>
75
76 f64
77 vat_time_now (vat_main_t * vam)
78 {
79 #if VPP_API_TEST_BUILTIN
80   return vlib_time_now (vam->vlib_main);
81 #else
82   return clib_time_now (&vam->clib_time);
83 #endif
84 }
85
86 void
87 errmsg (char *fmt, ...)
88 {
89   vat_main_t *vam = &vat_main;
90   va_list va;
91   u8 *s;
92
93   va_start (va, fmt);
94   s = va_format (0, fmt, &va);
95   va_end (va);
96
97   vec_add1 (s, 0);
98
99 #if VPP_API_TEST_BUILTIN
100   vlib_cli_output (vam->vlib_main, (char *) s);
101 #else
102   {
103     if (vam->ifp != stdin)
104       fformat (vam->ofp, "%s(%d): \n", vam->current_file,
105                vam->input_line_number);
106     fformat (vam->ofp, (char *) s);
107     fflush (vam->ofp);
108   }
109 #endif
110
111   vec_free (s);
112 }
113
114 #if VPP_API_TEST_BUILTIN == 0
115 static uword
116 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
117 {
118   vat_main_t *vam = va_arg (*args, vat_main_t *);
119   u32 *result = va_arg (*args, u32 *);
120   u8 *if_name;
121   uword *p;
122
123   if (!unformat (input, "%s", &if_name))
124     return 0;
125
126   p = hash_get_mem (vam->sw_if_index_by_interface_name, if_name);
127   if (p == 0)
128     return 0;
129   *result = p[0];
130   return 1;
131 }
132
133 /* Parse an IP4 address %d.%d.%d.%d. */
134 uword
135 unformat_ip4_address (unformat_input_t * input, va_list * args)
136 {
137   u8 *result = va_arg (*args, u8 *);
138   unsigned a[4];
139
140   if (!unformat (input, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]))
141     return 0;
142
143   if (a[0] >= 256 || a[1] >= 256 || a[2] >= 256 || a[3] >= 256)
144     return 0;
145
146   result[0] = a[0];
147   result[1] = a[1];
148   result[2] = a[2];
149   result[3] = a[3];
150
151   return 1;
152 }
153
154 uword
155 unformat_ethernet_address (unformat_input_t * input, va_list * args)
156 {
157   u8 *result = va_arg (*args, u8 *);
158   u32 i, a[6];
159
160   if (!unformat (input, "%_%x:%x:%x:%x:%x:%x%_",
161                  &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]))
162     return 0;
163
164   /* Check range. */
165   for (i = 0; i < 6; i++)
166     if (a[i] >= (1 << 8))
167       return 0;
168
169   for (i = 0; i < 6; i++)
170     result[i] = a[i];
171
172   return 1;
173 }
174
175 /* Returns ethernet type as an int in host byte order. */
176 uword
177 unformat_ethernet_type_host_byte_order (unformat_input_t * input,
178                                         va_list * args)
179 {
180   u16 *result = va_arg (*args, u16 *);
181   int type;
182
183   /* Numeric type. */
184   if (unformat (input, "0x%x", &type) || unformat (input, "%d", &type))
185     {
186       if (type >= (1 << 16))
187         return 0;
188       *result = type;
189       return 1;
190     }
191   return 0;
192 }
193
194 /* Parse an IP6 address. */
195 uword
196 unformat_ip6_address (unformat_input_t * input, va_list * args)
197 {
198   ip6_address_t *result = va_arg (*args, ip6_address_t *);
199   u16 hex_quads[8];
200   uword hex_quad, n_hex_quads, hex_digit, n_hex_digits;
201   uword c, n_colon, double_colon_index;
202
203   n_hex_quads = hex_quad = n_hex_digits = n_colon = 0;
204   double_colon_index = ARRAY_LEN (hex_quads);
205   while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
206     {
207       hex_digit = 16;
208       if (c >= '0' && c <= '9')
209         hex_digit = c - '0';
210       else if (c >= 'a' && c <= 'f')
211         hex_digit = c + 10 - 'a';
212       else if (c >= 'A' && c <= 'F')
213         hex_digit = c + 10 - 'A';
214       else if (c == ':' && n_colon < 2)
215         n_colon++;
216       else
217         {
218           unformat_put_input (input);
219           break;
220         }
221
222       /* Too many hex quads. */
223       if (n_hex_quads >= ARRAY_LEN (hex_quads))
224         return 0;
225
226       if (hex_digit < 16)
227         {
228           hex_quad = (hex_quad << 4) | hex_digit;
229
230           /* Hex quad must fit in 16 bits. */
231           if (n_hex_digits >= 4)
232             return 0;
233
234           n_colon = 0;
235           n_hex_digits++;
236         }
237
238       /* Save position of :: */
239       if (n_colon == 2)
240         {
241           /* More than one :: ? */
242           if (double_colon_index < ARRAY_LEN (hex_quads))
243             return 0;
244           double_colon_index = n_hex_quads;
245         }
246
247       if (n_colon > 0 && n_hex_digits > 0)
248         {
249           hex_quads[n_hex_quads++] = hex_quad;
250           hex_quad = 0;
251           n_hex_digits = 0;
252         }
253     }
254
255   if (n_hex_digits > 0)
256     hex_quads[n_hex_quads++] = hex_quad;
257
258   {
259     word i;
260
261     /* Expand :: to appropriate number of zero hex quads. */
262     if (double_colon_index < ARRAY_LEN (hex_quads))
263       {
264         word n_zero = ARRAY_LEN (hex_quads) - n_hex_quads;
265
266         for (i = n_hex_quads - 1; i >= (signed) double_colon_index; i--)
267           hex_quads[n_zero + i] = hex_quads[i];
268
269         for (i = 0; i < n_zero; i++)
270           hex_quads[double_colon_index + i] = 0;
271
272         n_hex_quads = ARRAY_LEN (hex_quads);
273       }
274
275     /* Too few hex quads given. */
276     if (n_hex_quads < ARRAY_LEN (hex_quads))
277       return 0;
278
279     for (i = 0; i < ARRAY_LEN (hex_quads); i++)
280       result->as_u16[i] = clib_host_to_net_u16 (hex_quads[i]);
281
282     return 1;
283   }
284 }
285
286 uword
287 unformat_ipsec_policy_action (unformat_input_t * input, va_list * args)
288 {
289   u32 *r = va_arg (*args, u32 *);
290
291   if (0);
292 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f;
293   foreach_ipsec_policy_action
294 #undef _
295     else
296     return 0;
297   return 1;
298 }
299
300 uword
301 unformat_ipsec_crypto_alg (unformat_input_t * input, va_list * args)
302 {
303   u32 *r = va_arg (*args, u32 *);
304
305   if (0);
306 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_CRYPTO_ALG_##f;
307   foreach_ipsec_crypto_alg
308 #undef _
309     else
310     return 0;
311   return 1;
312 }
313
314 u8 *
315 format_ipsec_crypto_alg (u8 * s, va_list * args)
316 {
317   u32 i = va_arg (*args, u32);
318   u8 *t = 0;
319
320   switch (i)
321     {
322 #define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break;
323       foreach_ipsec_crypto_alg
324 #undef _
325     default:
326       return format (s, "unknown");
327     }
328   return format (s, "%s", t);
329 }
330
331 uword
332 unformat_ipsec_integ_alg (unformat_input_t * input, va_list * args)
333 {
334   u32 *r = va_arg (*args, u32 *);
335
336   if (0);
337 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_INTEG_ALG_##f;
338   foreach_ipsec_integ_alg
339 #undef _
340     else
341     return 0;
342   return 1;
343 }
344
345 u8 *
346 format_ipsec_integ_alg (u8 * s, va_list * args)
347 {
348   u32 i = va_arg (*args, u32);
349   u8 *t = 0;
350
351   switch (i)
352     {
353 #define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
354       foreach_ipsec_integ_alg
355 #undef _
356     default:
357       return format (s, "unknown");
358     }
359   return format (s, "%s", t);
360 }
361
362 uword
363 unformat_ikev2_auth_method (unformat_input_t * input, va_list * args)
364 {
365   u32 *r = va_arg (*args, u32 *);
366
367   if (0);
368 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_AUTH_METHOD_##f;
369   foreach_ikev2_auth_method
370 #undef _
371     else
372     return 0;
373   return 1;
374 }
375
376 uword
377 unformat_ikev2_id_type (unformat_input_t * input, va_list * args)
378 {
379   u32 *r = va_arg (*args, u32 *);
380
381   if (0);
382 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_ID_TYPE_##f;
383   foreach_ikev2_id_type
384 #undef _
385     else
386     return 0;
387   return 1;
388 }
389 #else /* VPP_API_TEST_BUILTIN == 1 */
390 static uword
391 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
392 {
393   vat_main_t *vam __attribute__ ((unused)) = va_arg (*args, vat_main_t *);
394   vnet_main_t *vnm = vnet_get_main ();
395   u32 *result = va_arg (*args, u32 *);
396   u32 sw_if_index;
397
398   if (!unformat (input, "%U", unformat_vnet_sw_interface, vnm, &sw_if_index))
399     return 0;
400
401   *result = sw_if_index;
402   return 1;
403 }
404 #endif /* VPP_API_TEST_BUILTIN */
405
406 static uword
407 unformat_policer_rate_type (unformat_input_t * input, va_list * args)
408 {
409   u8 *r = va_arg (*args, u8 *);
410
411   if (unformat (input, "kbps"))
412     *r = SSE2_QOS_RATE_KBPS;
413   else if (unformat (input, "pps"))
414     *r = SSE2_QOS_RATE_PPS;
415   else
416     return 0;
417   return 1;
418 }
419
420 static uword
421 unformat_policer_round_type (unformat_input_t * input, va_list * args)
422 {
423   u8 *r = va_arg (*args, u8 *);
424
425   if (unformat (input, "closest"))
426     *r = SSE2_QOS_ROUND_TO_CLOSEST;
427   else if (unformat (input, "up"))
428     *r = SSE2_QOS_ROUND_TO_UP;
429   else if (unformat (input, "down"))
430     *r = SSE2_QOS_ROUND_TO_DOWN;
431   else
432     return 0;
433   return 1;
434 }
435
436 static uword
437 unformat_policer_type (unformat_input_t * input, va_list * args)
438 {
439   u8 *r = va_arg (*args, u8 *);
440
441   if (unformat (input, "1r2c"))
442     *r = SSE2_QOS_POLICER_TYPE_1R2C;
443   else if (unformat (input, "1r3c"))
444     *r = SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697;
445   else if (unformat (input, "2r3c-2698"))
446     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698;
447   else if (unformat (input, "2r3c-4115"))
448     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115;
449   else if (unformat (input, "2r3c-mef5cf1"))
450     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
451   else
452     return 0;
453   return 1;
454 }
455
456 static uword
457 unformat_dscp (unformat_input_t * input, va_list * va)
458 {
459   u8 *r = va_arg (*va, u8 *);
460
461   if (0);
462 #define _(v,f,str) else if (unformat (input, str)) *r = VNET_DSCP_##f;
463   foreach_vnet_dscp
464 #undef _
465     else
466     return 0;
467   return 1;
468 }
469
470 static uword
471 unformat_policer_action_type (unformat_input_t * input, va_list * va)
472 {
473   sse2_qos_pol_action_params_st *a
474     = va_arg (*va, sse2_qos_pol_action_params_st *);
475
476   if (unformat (input, "drop"))
477     a->action_type = SSE2_QOS_ACTION_DROP;
478   else if (unformat (input, "transmit"))
479     a->action_type = SSE2_QOS_ACTION_TRANSMIT;
480   else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp))
481     a->action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
482   else
483     return 0;
484   return 1;
485 }
486
487 static uword
488 unformat_policer_classify_table_type (unformat_input_t * input, va_list * va)
489 {
490   u32 *r = va_arg (*va, u32 *);
491   u32 tid;
492
493   if (unformat (input, "ip4"))
494     tid = POLICER_CLASSIFY_TABLE_IP4;
495   else if (unformat (input, "ip6"))
496     tid = POLICER_CLASSIFY_TABLE_IP6;
497   else if (unformat (input, "l2"))
498     tid = POLICER_CLASSIFY_TABLE_L2;
499   else
500     return 0;
501
502   *r = tid;
503   return 1;
504 }
505
506 static uword
507 unformat_flow_classify_table_type (unformat_input_t * input, va_list * va)
508 {
509   u32 *r = va_arg (*va, u32 *);
510   u32 tid;
511
512   if (unformat (input, "ip4"))
513     tid = FLOW_CLASSIFY_TABLE_IP4;
514   else if (unformat (input, "ip6"))
515     tid = FLOW_CLASSIFY_TABLE_IP6;
516   else
517     return 0;
518
519   *r = tid;
520   return 1;
521 }
522
523 static const char *mfib_flag_names[] = MFIB_ENTRY_NAMES_SHORT;
524 static const char *mfib_flag_long_names[] = MFIB_ENTRY_NAMES_LONG;
525 static const char *mfib_itf_flag_long_names[] = MFIB_ITF_NAMES_LONG;
526 static const char *mfib_itf_flag_names[] = MFIB_ITF_NAMES_SHORT;
527
528 #if (VPP_API_TEST_BUILTIN==0)
529 uword
530 unformat_mfib_itf_flags (unformat_input_t * input, va_list * args)
531 {
532   mfib_itf_flags_t old, *iflags = va_arg (*args, mfib_itf_flags_t *);
533   mfib_itf_attribute_t attr;
534
535   old = *iflags;
536   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
537   {
538     if (unformat (input, mfib_itf_flag_long_names[attr]))
539       *iflags |= (1 << attr);
540   }
541   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
542   {
543     if (unformat (input, mfib_itf_flag_names[attr]))
544       *iflags |= (1 << attr);
545   }
546
547   return (old == *iflags ? 0 : 1);
548 }
549
550 uword
551 unformat_mfib_entry_flags (unformat_input_t * input, va_list * args)
552 {
553   mfib_entry_flags_t old, *eflags = va_arg (*args, mfib_entry_flags_t *);
554   mfib_entry_attribute_t attr;
555
556   old = *eflags;
557   FOR_EACH_MFIB_ATTRIBUTE (attr)
558   {
559     if (unformat (input, mfib_flag_long_names[attr]))
560       *eflags |= (1 << attr);
561   }
562   FOR_EACH_MFIB_ATTRIBUTE (attr)
563   {
564     if (unformat (input, mfib_flag_names[attr]))
565       *eflags |= (1 << attr);
566   }
567
568   return (old == *eflags ? 0 : 1);
569 }
570
571 u8 *
572 format_ip4_address (u8 * s, va_list * args)
573 {
574   u8 *a = va_arg (*args, u8 *);
575   return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
576 }
577
578 u8 *
579 format_ip6_address (u8 * s, va_list * args)
580 {
581   ip6_address_t *a = va_arg (*args, ip6_address_t *);
582   u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
583
584   i_max_n_zero = ARRAY_LEN (a->as_u16);
585   max_n_zeros = 0;
586   i_first_zero = i_max_n_zero;
587   n_zeros = 0;
588   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
589     {
590       u32 is_zero = a->as_u16[i] == 0;
591       if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
592         {
593           i_first_zero = i;
594           n_zeros = 0;
595         }
596       n_zeros += is_zero;
597       if ((!is_zero && n_zeros > max_n_zeros)
598           || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
599         {
600           i_max_n_zero = i_first_zero;
601           max_n_zeros = n_zeros;
602           i_first_zero = ARRAY_LEN (a->as_u16);
603           n_zeros = 0;
604         }
605     }
606
607   last_double_colon = 0;
608   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
609     {
610       if (i == i_max_n_zero && max_n_zeros > 1)
611         {
612           s = format (s, "::");
613           i += max_n_zeros - 1;
614           last_double_colon = 1;
615         }
616       else
617         {
618           s = format (s, "%s%x",
619                       (last_double_colon || i == 0) ? "" : ":",
620                       clib_net_to_host_u16 (a->as_u16[i]));
621           last_double_colon = 0;
622         }
623     }
624
625   return s;
626 }
627
628 /* Format an IP46 address. */
629 u8 *
630 format_ip46_address (u8 * s, va_list * args)
631 {
632   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
633   ip46_type_t type = va_arg (*args, ip46_type_t);
634   int is_ip4 = 1;
635
636   switch (type)
637     {
638     case IP46_TYPE_ANY:
639       is_ip4 = ip46_address_is_ip4 (ip46);
640       break;
641     case IP46_TYPE_IP4:
642       is_ip4 = 1;
643       break;
644     case IP46_TYPE_IP6:
645       is_ip4 = 0;
646       break;
647     }
648
649   return is_ip4 ?
650     format (s, "%U", format_ip4_address, &ip46->ip4) :
651     format (s, "%U", format_ip6_address, &ip46->ip6);
652 }
653
654 u8 *
655 format_ethernet_address (u8 * s, va_list * args)
656 {
657   u8 *a = va_arg (*args, u8 *);
658
659   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
660                  a[0], a[1], a[2], a[3], a[4], a[5]);
661 }
662 #endif
663
664 static void
665 increment_v4_address (ip4_address_t * a)
666 {
667   u32 v;
668
669   v = ntohl (a->as_u32) + 1;
670   a->as_u32 = ntohl (v);
671 }
672
673 static void
674 increment_v6_address (ip6_address_t * a)
675 {
676   u64 v0, v1;
677
678   v0 = clib_net_to_host_u64 (a->as_u64[0]);
679   v1 = clib_net_to_host_u64 (a->as_u64[1]);
680
681   v1 += 1;
682   if (v1 == 0)
683     v0 += 1;
684   a->as_u64[0] = clib_net_to_host_u64 (v0);
685   a->as_u64[1] = clib_net_to_host_u64 (v1);
686 }
687
688 static void
689 increment_mac_address (u64 * mac)
690 {
691   u64 tmp = *mac;
692
693   tmp = clib_net_to_host_u64 (tmp);
694   tmp += 1 << 16;               /* skip unused (least significant) octets */
695   tmp = clib_host_to_net_u64 (tmp);
696   *mac = tmp;
697 }
698
699 static void vl_api_create_loopback_reply_t_handler
700   (vl_api_create_loopback_reply_t * mp)
701 {
702   vat_main_t *vam = &vat_main;
703   i32 retval = ntohl (mp->retval);
704
705   vam->retval = retval;
706   vam->regenerate_interface_table = 1;
707   vam->sw_if_index = ntohl (mp->sw_if_index);
708   vam->result_ready = 1;
709 }
710
711 static void vl_api_create_loopback_reply_t_handler_json
712   (vl_api_create_loopback_reply_t * mp)
713 {
714   vat_main_t *vam = &vat_main;
715   vat_json_node_t node;
716
717   vat_json_init_object (&node);
718   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
719   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
720
721   vat_json_print (vam->ofp, &node);
722   vat_json_free (&node);
723   vam->retval = ntohl (mp->retval);
724   vam->result_ready = 1;
725 }
726
727 static void vl_api_create_loopback_instance_reply_t_handler
728   (vl_api_create_loopback_instance_reply_t * mp)
729 {
730   vat_main_t *vam = &vat_main;
731   i32 retval = ntohl (mp->retval);
732
733   vam->retval = retval;
734   vam->regenerate_interface_table = 1;
735   vam->sw_if_index = ntohl (mp->sw_if_index);
736   vam->result_ready = 1;
737 }
738
739 static void vl_api_create_loopback_instance_reply_t_handler_json
740   (vl_api_create_loopback_instance_reply_t * mp)
741 {
742   vat_main_t *vam = &vat_main;
743   vat_json_node_t node;
744
745   vat_json_init_object (&node);
746   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
747   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
748
749   vat_json_print (vam->ofp, &node);
750   vat_json_free (&node);
751   vam->retval = ntohl (mp->retval);
752   vam->result_ready = 1;
753 }
754
755 static void vl_api_af_packet_create_reply_t_handler
756   (vl_api_af_packet_create_reply_t * mp)
757 {
758   vat_main_t *vam = &vat_main;
759   i32 retval = ntohl (mp->retval);
760
761   vam->retval = retval;
762   vam->regenerate_interface_table = 1;
763   vam->sw_if_index = ntohl (mp->sw_if_index);
764   vam->result_ready = 1;
765 }
766
767 static void vl_api_af_packet_create_reply_t_handler_json
768   (vl_api_af_packet_create_reply_t * mp)
769 {
770   vat_main_t *vam = &vat_main;
771   vat_json_node_t node;
772
773   vat_json_init_object (&node);
774   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
775   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
776
777   vat_json_print (vam->ofp, &node);
778   vat_json_free (&node);
779
780   vam->retval = ntohl (mp->retval);
781   vam->result_ready = 1;
782 }
783
784 static void vl_api_create_vlan_subif_reply_t_handler
785   (vl_api_create_vlan_subif_reply_t * mp)
786 {
787   vat_main_t *vam = &vat_main;
788   i32 retval = ntohl (mp->retval);
789
790   vam->retval = retval;
791   vam->regenerate_interface_table = 1;
792   vam->sw_if_index = ntohl (mp->sw_if_index);
793   vam->result_ready = 1;
794 }
795
796 static void vl_api_create_vlan_subif_reply_t_handler_json
797   (vl_api_create_vlan_subif_reply_t * mp)
798 {
799   vat_main_t *vam = &vat_main;
800   vat_json_node_t node;
801
802   vat_json_init_object (&node);
803   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
804   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
805
806   vat_json_print (vam->ofp, &node);
807   vat_json_free (&node);
808
809   vam->retval = ntohl (mp->retval);
810   vam->result_ready = 1;
811 }
812
813 static void vl_api_create_subif_reply_t_handler
814   (vl_api_create_subif_reply_t * mp)
815 {
816   vat_main_t *vam = &vat_main;
817   i32 retval = ntohl (mp->retval);
818
819   vam->retval = retval;
820   vam->regenerate_interface_table = 1;
821   vam->sw_if_index = ntohl (mp->sw_if_index);
822   vam->result_ready = 1;
823 }
824
825 static void vl_api_create_subif_reply_t_handler_json
826   (vl_api_create_subif_reply_t * mp)
827 {
828   vat_main_t *vam = &vat_main;
829   vat_json_node_t node;
830
831   vat_json_init_object (&node);
832   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
833   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
834
835   vat_json_print (vam->ofp, &node);
836   vat_json_free (&node);
837
838   vam->retval = ntohl (mp->retval);
839   vam->result_ready = 1;
840 }
841
842 static void vl_api_interface_name_renumber_reply_t_handler
843   (vl_api_interface_name_renumber_reply_t * mp)
844 {
845   vat_main_t *vam = &vat_main;
846   i32 retval = ntohl (mp->retval);
847
848   vam->retval = retval;
849   vam->regenerate_interface_table = 1;
850   vam->result_ready = 1;
851 }
852
853 static void vl_api_interface_name_renumber_reply_t_handler_json
854   (vl_api_interface_name_renumber_reply_t * mp)
855 {
856   vat_main_t *vam = &vat_main;
857   vat_json_node_t node;
858
859   vat_json_init_object (&node);
860   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
861
862   vat_json_print (vam->ofp, &node);
863   vat_json_free (&node);
864
865   vam->retval = ntohl (mp->retval);
866   vam->result_ready = 1;
867 }
868
869 /*
870  * Special-case: build the interface table, maintain
871  * the next loopback sw_if_index vbl.
872  */
873 static void vl_api_sw_interface_details_t_handler
874   (vl_api_sw_interface_details_t * mp)
875 {
876   vat_main_t *vam = &vat_main;
877   u8 *s = format (0, "%s%c", mp->interface_name, 0);
878
879   hash_set_mem (vam->sw_if_index_by_interface_name, s,
880                 ntohl (mp->sw_if_index));
881
882   /* In sub interface case, fill the sub interface table entry */
883   if (mp->sw_if_index != mp->sup_sw_if_index)
884     {
885       sw_interface_subif_t *sub = NULL;
886
887       vec_add2 (vam->sw_if_subif_table, sub, 1);
888
889       vec_validate (sub->interface_name, strlen ((char *) s) + 1);
890       strncpy ((char *) sub->interface_name, (char *) s,
891                vec_len (sub->interface_name));
892       sub->sw_if_index = ntohl (mp->sw_if_index);
893       sub->sub_id = ntohl (mp->sub_id);
894
895       sub->sub_dot1ad = mp->sub_dot1ad;
896       sub->sub_number_of_tags = mp->sub_number_of_tags;
897       sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
898       sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
899       sub->sub_exact_match = mp->sub_exact_match;
900       sub->sub_default = mp->sub_default;
901       sub->sub_outer_vlan_id_any = mp->sub_outer_vlan_id_any;
902       sub->sub_inner_vlan_id_any = mp->sub_inner_vlan_id_any;
903
904       /* vlan tag rewrite */
905       sub->vtr_op = ntohl (mp->vtr_op);
906       sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
907       sub->vtr_tag1 = ntohl (mp->vtr_tag1);
908       sub->vtr_tag2 = ntohl (mp->vtr_tag2);
909     }
910 }
911
912 static void vl_api_sw_interface_details_t_handler_json
913   (vl_api_sw_interface_details_t * mp)
914 {
915   vat_main_t *vam = &vat_main;
916   vat_json_node_t *node = NULL;
917
918   if (VAT_JSON_ARRAY != vam->json_tree.type)
919     {
920       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
921       vat_json_init_array (&vam->json_tree);
922     }
923   node = vat_json_array_add (&vam->json_tree);
924
925   vat_json_init_object (node);
926   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
927   vat_json_object_add_uint (node, "sup_sw_if_index",
928                             ntohl (mp->sup_sw_if_index));
929   vat_json_object_add_uint (node, "l2_address_length",
930                             ntohl (mp->l2_address_length));
931   vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
932                              sizeof (mp->l2_address));
933   vat_json_object_add_string_copy (node, "interface_name",
934                                    mp->interface_name);
935   vat_json_object_add_uint (node, "admin_up_down", mp->admin_up_down);
936   vat_json_object_add_uint (node, "link_up_down", mp->link_up_down);
937   vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
938   vat_json_object_add_uint (node, "link_speed", mp->link_speed);
939   vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
940   vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
941   vat_json_object_add_uint (node, "sub_dot1ad", mp->sub_dot1ad);
942   vat_json_object_add_uint (node, "sub_number_of_tags",
943                             mp->sub_number_of_tags);
944   vat_json_object_add_uint (node, "sub_outer_vlan_id",
945                             ntohs (mp->sub_outer_vlan_id));
946   vat_json_object_add_uint (node, "sub_inner_vlan_id",
947                             ntohs (mp->sub_inner_vlan_id));
948   vat_json_object_add_uint (node, "sub_exact_match", mp->sub_exact_match);
949   vat_json_object_add_uint (node, "sub_default", mp->sub_default);
950   vat_json_object_add_uint (node, "sub_outer_vlan_id_any",
951                             mp->sub_outer_vlan_id_any);
952   vat_json_object_add_uint (node, "sub_inner_vlan_id_any",
953                             mp->sub_inner_vlan_id_any);
954   vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
955   vat_json_object_add_uint (node, "vtr_push_dot1q",
956                             ntohl (mp->vtr_push_dot1q));
957   vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
958   vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
959   if (mp->sub_dot1ah)
960     {
961       vat_json_object_add_string_copy (node, "pbb_vtr_dmac",
962                                        format (0, "%U",
963                                                format_ethernet_address,
964                                                &mp->b_dmac));
965       vat_json_object_add_string_copy (node, "pbb_vtr_smac",
966                                        format (0, "%U",
967                                                format_ethernet_address,
968                                                &mp->b_smac));
969       vat_json_object_add_uint (node, "pbb_vtr_b_vlanid", mp->b_vlanid);
970       vat_json_object_add_uint (node, "pbb_vtr_i_sid", mp->i_sid);
971     }
972 }
973
974 #if VPP_API_TEST_BUILTIN == 0
975 static void vl_api_sw_interface_set_flags_t_handler
976   (vl_api_sw_interface_set_flags_t * mp)
977 {
978   vat_main_t *vam = &vat_main;
979   if (vam->interface_event_display)
980     errmsg ("interface flags: sw_if_index %d %s %s",
981             ntohl (mp->sw_if_index),
982             mp->admin_up_down ? "admin-up" : "admin-down",
983             mp->link_up_down ? "link-up" : "link-down");
984 }
985 #endif
986
987 static void vl_api_sw_interface_set_flags_t_handler_json
988   (vl_api_sw_interface_set_flags_t * mp)
989 {
990   /* JSON output not supported */
991 }
992
993 static void
994 vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
995 {
996   vat_main_t *vam = &vat_main;
997   i32 retval = ntohl (mp->retval);
998
999   vam->retval = retval;
1000   vam->shmem_result = (u8 *) mp->reply_in_shmem;
1001   vam->result_ready = 1;
1002 }
1003
1004 static void
1005 vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
1006 {
1007   vat_main_t *vam = &vat_main;
1008   vat_json_node_t node;
1009   api_main_t *am = &api_main;
1010   void *oldheap;
1011   u8 *reply;
1012
1013   vat_json_init_object (&node);
1014   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1015   vat_json_object_add_uint (&node, "reply_in_shmem",
1016                             ntohl (mp->reply_in_shmem));
1017   /* Toss the shared-memory original... */
1018   pthread_mutex_lock (&am->vlib_rp->mutex);
1019   oldheap = svm_push_data_heap (am->vlib_rp);
1020
1021   reply = (u8 *) (mp->reply_in_shmem);
1022   vec_free (reply);
1023
1024   svm_pop_heap (oldheap);
1025   pthread_mutex_unlock (&am->vlib_rp->mutex);
1026
1027   vat_json_print (vam->ofp, &node);
1028   vat_json_free (&node);
1029
1030   vam->retval = ntohl (mp->retval);
1031   vam->result_ready = 1;
1032 }
1033
1034 static void
1035 vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
1036 {
1037   vat_main_t *vam = &vat_main;
1038   i32 retval = ntohl (mp->retval);
1039
1040   vam->retval = retval;
1041   vam->cmd_reply = mp->reply;
1042   vam->result_ready = 1;
1043 }
1044
1045 static void
1046 vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
1047 {
1048   vat_main_t *vam = &vat_main;
1049   vat_json_node_t node;
1050
1051   vat_json_init_object (&node);
1052   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1053   vat_json_object_add_string_copy (&node, "reply", mp->reply);
1054
1055   vat_json_print (vam->ofp, &node);
1056   vat_json_free (&node);
1057
1058   vam->retval = ntohl (mp->retval);
1059   vam->result_ready = 1;
1060 }
1061
1062 static void vl_api_classify_add_del_table_reply_t_handler
1063   (vl_api_classify_add_del_table_reply_t * mp)
1064 {
1065   vat_main_t *vam = &vat_main;
1066   i32 retval = ntohl (mp->retval);
1067   if (vam->async_mode)
1068     {
1069       vam->async_errors += (retval < 0);
1070     }
1071   else
1072     {
1073       vam->retval = retval;
1074       if (retval == 0 &&
1075           ((mp->new_table_index != 0xFFFFFFFF) ||
1076            (mp->skip_n_vectors != 0xFFFFFFFF) ||
1077            (mp->match_n_vectors != 0xFFFFFFFF)))
1078         /*
1079          * Note: this is just barely thread-safe, depends on
1080          * the main thread spinning waiting for an answer...
1081          */
1082         errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d",
1083                 ntohl (mp->new_table_index),
1084                 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
1085       vam->result_ready = 1;
1086     }
1087 }
1088
1089 static void vl_api_classify_add_del_table_reply_t_handler_json
1090   (vl_api_classify_add_del_table_reply_t * mp)
1091 {
1092   vat_main_t *vam = &vat_main;
1093   vat_json_node_t node;
1094
1095   vat_json_init_object (&node);
1096   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1097   vat_json_object_add_uint (&node, "new_table_index",
1098                             ntohl (mp->new_table_index));
1099   vat_json_object_add_uint (&node, "skip_n_vectors",
1100                             ntohl (mp->skip_n_vectors));
1101   vat_json_object_add_uint (&node, "match_n_vectors",
1102                             ntohl (mp->match_n_vectors));
1103
1104   vat_json_print (vam->ofp, &node);
1105   vat_json_free (&node);
1106
1107   vam->retval = ntohl (mp->retval);
1108   vam->result_ready = 1;
1109 }
1110
1111 static void vl_api_get_node_index_reply_t_handler
1112   (vl_api_get_node_index_reply_t * mp)
1113 {
1114   vat_main_t *vam = &vat_main;
1115   i32 retval = ntohl (mp->retval);
1116   if (vam->async_mode)
1117     {
1118       vam->async_errors += (retval < 0);
1119     }
1120   else
1121     {
1122       vam->retval = retval;
1123       if (retval == 0)
1124         errmsg ("node index %d", ntohl (mp->node_index));
1125       vam->result_ready = 1;
1126     }
1127 }
1128
1129 static void vl_api_get_node_index_reply_t_handler_json
1130   (vl_api_get_node_index_reply_t * mp)
1131 {
1132   vat_main_t *vam = &vat_main;
1133   vat_json_node_t node;
1134
1135   vat_json_init_object (&node);
1136   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1137   vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
1138
1139   vat_json_print (vam->ofp, &node);
1140   vat_json_free (&node);
1141
1142   vam->retval = ntohl (mp->retval);
1143   vam->result_ready = 1;
1144 }
1145
1146 static void vl_api_get_next_index_reply_t_handler
1147   (vl_api_get_next_index_reply_t * mp)
1148 {
1149   vat_main_t *vam = &vat_main;
1150   i32 retval = ntohl (mp->retval);
1151   if (vam->async_mode)
1152     {
1153       vam->async_errors += (retval < 0);
1154     }
1155   else
1156     {
1157       vam->retval = retval;
1158       if (retval == 0)
1159         errmsg ("next node index %d", ntohl (mp->next_index));
1160       vam->result_ready = 1;
1161     }
1162 }
1163
1164 static void vl_api_get_next_index_reply_t_handler_json
1165   (vl_api_get_next_index_reply_t * mp)
1166 {
1167   vat_main_t *vam = &vat_main;
1168   vat_json_node_t node;
1169
1170   vat_json_init_object (&node);
1171   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1172   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1173
1174   vat_json_print (vam->ofp, &node);
1175   vat_json_free (&node);
1176
1177   vam->retval = ntohl (mp->retval);
1178   vam->result_ready = 1;
1179 }
1180
1181 static void vl_api_add_node_next_reply_t_handler
1182   (vl_api_add_node_next_reply_t * mp)
1183 {
1184   vat_main_t *vam = &vat_main;
1185   i32 retval = ntohl (mp->retval);
1186   if (vam->async_mode)
1187     {
1188       vam->async_errors += (retval < 0);
1189     }
1190   else
1191     {
1192       vam->retval = retval;
1193       if (retval == 0)
1194         errmsg ("next index %d", ntohl (mp->next_index));
1195       vam->result_ready = 1;
1196     }
1197 }
1198
1199 static void vl_api_add_node_next_reply_t_handler_json
1200   (vl_api_add_node_next_reply_t * mp)
1201 {
1202   vat_main_t *vam = &vat_main;
1203   vat_json_node_t node;
1204
1205   vat_json_init_object (&node);
1206   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1207   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1208
1209   vat_json_print (vam->ofp, &node);
1210   vat_json_free (&node);
1211
1212   vam->retval = ntohl (mp->retval);
1213   vam->result_ready = 1;
1214 }
1215
1216 static void vl_api_show_version_reply_t_handler
1217   (vl_api_show_version_reply_t * mp)
1218 {
1219   vat_main_t *vam = &vat_main;
1220   i32 retval = ntohl (mp->retval);
1221
1222   if (retval >= 0)
1223     {
1224       errmsg ("        program: %s", mp->program);
1225       errmsg ("        version: %s", mp->version);
1226       errmsg ("     build date: %s", mp->build_date);
1227       errmsg ("build directory: %s", mp->build_directory);
1228     }
1229   vam->retval = retval;
1230   vam->result_ready = 1;
1231 }
1232
1233 static void vl_api_show_version_reply_t_handler_json
1234   (vl_api_show_version_reply_t * mp)
1235 {
1236   vat_main_t *vam = &vat_main;
1237   vat_json_node_t node;
1238
1239   vat_json_init_object (&node);
1240   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1241   vat_json_object_add_string_copy (&node, "program", mp->program);
1242   vat_json_object_add_string_copy (&node, "version", mp->version);
1243   vat_json_object_add_string_copy (&node, "build_date", mp->build_date);
1244   vat_json_object_add_string_copy (&node, "build_directory",
1245                                    mp->build_directory);
1246
1247   vat_json_print (vam->ofp, &node);
1248   vat_json_free (&node);
1249
1250   vam->retval = ntohl (mp->retval);
1251   vam->result_ready = 1;
1252 }
1253
1254 static void
1255 vl_api_ip4_arp_event_t_handler (vl_api_ip4_arp_event_t * mp)
1256 {
1257   u32 sw_if_index = ntohl (mp->sw_if_index);
1258   errmsg ("arp %s event: address %U new mac %U sw_if_index %d",
1259           mp->mac_ip ? "mac/ip binding" : "address resolution",
1260           format_ip4_address, &mp->address,
1261           format_ethernet_address, mp->new_mac, sw_if_index);
1262 }
1263
1264 static void
1265 vl_api_ip4_arp_event_t_handler_json (vl_api_ip4_arp_event_t * mp)
1266 {
1267   /* JSON output not supported */
1268 }
1269
1270 static void
1271 vl_api_ip6_nd_event_t_handler (vl_api_ip6_nd_event_t * mp)
1272 {
1273   u32 sw_if_index = ntohl (mp->sw_if_index);
1274   errmsg ("ip6 nd %s event: address %U new mac %U sw_if_index %d",
1275           mp->mac_ip ? "mac/ip binding" : "address resolution",
1276           format_ip6_address, mp->address,
1277           format_ethernet_address, mp->new_mac, sw_if_index);
1278 }
1279
1280 static void
1281 vl_api_ip6_nd_event_t_handler_json (vl_api_ip6_nd_event_t * mp)
1282 {
1283   /* JSON output not supported */
1284 }
1285
1286 /*
1287  * Special-case: build the bridge domain table, maintain
1288  * the next bd id vbl.
1289  */
1290 static void vl_api_bridge_domain_details_t_handler
1291   (vl_api_bridge_domain_details_t * mp)
1292 {
1293   vat_main_t *vam = &vat_main;
1294   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1295
1296   print (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-3s",
1297          " ID", "LRN", "FWD", "FLD", "BVI", "#IF");
1298
1299   print (vam->ofp, "%3d %3d %3d %3d %3d %3d",
1300          ntohl (mp->bd_id), mp->learn, mp->forward,
1301          mp->flood, ntohl (mp->bvi_sw_if_index), n_sw_ifs);
1302
1303   if (n_sw_ifs)
1304     print (vam->ofp, "\n\n%s %s  %s", "sw_if_index", "SHG", "Interface Name");
1305 }
1306
1307 static void vl_api_bridge_domain_details_t_handler_json
1308   (vl_api_bridge_domain_details_t * mp)
1309 {
1310   vat_main_t *vam = &vat_main;
1311   vat_json_node_t *node, *array = NULL;
1312
1313   if (VAT_JSON_ARRAY != vam->json_tree.type)
1314     {
1315       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1316       vat_json_init_array (&vam->json_tree);
1317     }
1318   node = vat_json_array_add (&vam->json_tree);
1319
1320   vat_json_init_object (node);
1321   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1322   vat_json_object_add_uint (node, "flood", mp->flood);
1323   vat_json_object_add_uint (node, "forward", mp->forward);
1324   vat_json_object_add_uint (node, "learn", mp->learn);
1325   vat_json_object_add_uint (node, "bvi_sw_if_index",
1326                             ntohl (mp->bvi_sw_if_index));
1327   vat_json_object_add_uint (node, "n_sw_ifs", ntohl (mp->n_sw_ifs));
1328   array = vat_json_object_add (node, "sw_if");
1329   vat_json_init_array (array);
1330 }
1331
1332 /*
1333  * Special-case: build the bridge domain sw if table.
1334  */
1335 static void vl_api_bridge_domain_sw_if_details_t_handler
1336   (vl_api_bridge_domain_sw_if_details_t * mp)
1337 {
1338   vat_main_t *vam = &vat_main;
1339   hash_pair_t *p;
1340   u8 *sw_if_name = 0;
1341   u32 sw_if_index;
1342
1343   sw_if_index = ntohl (mp->sw_if_index);
1344   /* *INDENT-OFF* */
1345   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1346   ({
1347     if ((u32) p->value[0] == sw_if_index)
1348       {
1349         sw_if_name = (u8 *)(p->key);
1350         break;
1351       }
1352   }));
1353   /* *INDENT-ON* */
1354
1355   print (vam->ofp, "%7d     %3d  %s", sw_if_index,
1356          mp->shg, sw_if_name ? (char *) sw_if_name :
1357          "sw_if_index not found!");
1358 }
1359
1360 static void vl_api_bridge_domain_sw_if_details_t_handler_json
1361   (vl_api_bridge_domain_sw_if_details_t * mp)
1362 {
1363   vat_main_t *vam = &vat_main;
1364   vat_json_node_t *node = NULL;
1365   uword last_index = 0;
1366
1367   ASSERT (VAT_JSON_ARRAY == vam->json_tree.type);
1368   ASSERT (vec_len (vam->json_tree.array) >= 1);
1369   last_index = vec_len (vam->json_tree.array) - 1;
1370   node = &vam->json_tree.array[last_index];
1371   node = vat_json_object_get_element (node, "sw_if");
1372   ASSERT (NULL != node);
1373   node = vat_json_array_add (node);
1374
1375   vat_json_init_object (node);
1376   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1377   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
1378   vat_json_object_add_uint (node, "shg", mp->shg);
1379 }
1380
1381 static void vl_api_control_ping_reply_t_handler
1382   (vl_api_control_ping_reply_t * mp)
1383 {
1384   vat_main_t *vam = &vat_main;
1385   i32 retval = ntohl (mp->retval);
1386   if (vam->async_mode)
1387     {
1388       vam->async_errors += (retval < 0);
1389     }
1390   else
1391     {
1392       vam->retval = retval;
1393       vam->result_ready = 1;
1394     }
1395 }
1396
1397 static void vl_api_control_ping_reply_t_handler_json
1398   (vl_api_control_ping_reply_t * mp)
1399 {
1400   vat_main_t *vam = &vat_main;
1401   i32 retval = ntohl (mp->retval);
1402
1403   if (VAT_JSON_NONE != vam->json_tree.type)
1404     {
1405       vat_json_print (vam->ofp, &vam->json_tree);
1406       vat_json_free (&vam->json_tree);
1407       vam->json_tree.type = VAT_JSON_NONE;
1408     }
1409   else
1410     {
1411       /* just print [] */
1412       vat_json_init_array (&vam->json_tree);
1413       vat_json_print (vam->ofp, &vam->json_tree);
1414       vam->json_tree.type = VAT_JSON_NONE;
1415     }
1416
1417   vam->retval = retval;
1418   vam->result_ready = 1;
1419 }
1420
1421 static void
1422 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1423 {
1424   vat_main_t *vam = &vat_main;
1425   i32 retval = ntohl (mp->retval);
1426   if (vam->async_mode)
1427     {
1428       vam->async_errors += (retval < 0);
1429     }
1430   else
1431     {
1432       vam->retval = retval;
1433       vam->result_ready = 1;
1434     }
1435 }
1436
1437 static void vl_api_l2_flags_reply_t_handler_json
1438   (vl_api_l2_flags_reply_t * mp)
1439 {
1440   vat_main_t *vam = &vat_main;
1441   vat_json_node_t node;
1442
1443   vat_json_init_object (&node);
1444   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1445   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1446                             ntohl (mp->resulting_feature_bitmap));
1447
1448   vat_json_print (vam->ofp, &node);
1449   vat_json_free (&node);
1450
1451   vam->retval = ntohl (mp->retval);
1452   vam->result_ready = 1;
1453 }
1454
1455 static void vl_api_bridge_flags_reply_t_handler
1456   (vl_api_bridge_flags_reply_t * mp)
1457 {
1458   vat_main_t *vam = &vat_main;
1459   i32 retval = ntohl (mp->retval);
1460   if (vam->async_mode)
1461     {
1462       vam->async_errors += (retval < 0);
1463     }
1464   else
1465     {
1466       vam->retval = retval;
1467       vam->result_ready = 1;
1468     }
1469 }
1470
1471 static void vl_api_bridge_flags_reply_t_handler_json
1472   (vl_api_bridge_flags_reply_t * mp)
1473 {
1474   vat_main_t *vam = &vat_main;
1475   vat_json_node_t node;
1476
1477   vat_json_init_object (&node);
1478   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1479   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1480                             ntohl (mp->resulting_feature_bitmap));
1481
1482   vat_json_print (vam->ofp, &node);
1483   vat_json_free (&node);
1484
1485   vam->retval = ntohl (mp->retval);
1486   vam->result_ready = 1;
1487 }
1488
1489 static void vl_api_tap_connect_reply_t_handler
1490   (vl_api_tap_connect_reply_t * mp)
1491 {
1492   vat_main_t *vam = &vat_main;
1493   i32 retval = ntohl (mp->retval);
1494   if (vam->async_mode)
1495     {
1496       vam->async_errors += (retval < 0);
1497     }
1498   else
1499     {
1500       vam->retval = retval;
1501       vam->sw_if_index = ntohl (mp->sw_if_index);
1502       vam->result_ready = 1;
1503     }
1504
1505 }
1506
1507 static void vl_api_tap_connect_reply_t_handler_json
1508   (vl_api_tap_connect_reply_t * mp)
1509 {
1510   vat_main_t *vam = &vat_main;
1511   vat_json_node_t node;
1512
1513   vat_json_init_object (&node);
1514   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1515   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1516
1517   vat_json_print (vam->ofp, &node);
1518   vat_json_free (&node);
1519
1520   vam->retval = ntohl (mp->retval);
1521   vam->result_ready = 1;
1522
1523 }
1524
1525 static void
1526 vl_api_tap_modify_reply_t_handler (vl_api_tap_modify_reply_t * mp)
1527 {
1528   vat_main_t *vam = &vat_main;
1529   i32 retval = ntohl (mp->retval);
1530   if (vam->async_mode)
1531     {
1532       vam->async_errors += (retval < 0);
1533     }
1534   else
1535     {
1536       vam->retval = retval;
1537       vam->sw_if_index = ntohl (mp->sw_if_index);
1538       vam->result_ready = 1;
1539     }
1540 }
1541
1542 static void vl_api_tap_modify_reply_t_handler_json
1543   (vl_api_tap_modify_reply_t * mp)
1544 {
1545   vat_main_t *vam = &vat_main;
1546   vat_json_node_t node;
1547
1548   vat_json_init_object (&node);
1549   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1550   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1551
1552   vat_json_print (vam->ofp, &node);
1553   vat_json_free (&node);
1554
1555   vam->retval = ntohl (mp->retval);
1556   vam->result_ready = 1;
1557 }
1558
1559 static void
1560 vl_api_tap_delete_reply_t_handler (vl_api_tap_delete_reply_t * mp)
1561 {
1562   vat_main_t *vam = &vat_main;
1563   i32 retval = ntohl (mp->retval);
1564   if (vam->async_mode)
1565     {
1566       vam->async_errors += (retval < 0);
1567     }
1568   else
1569     {
1570       vam->retval = retval;
1571       vam->result_ready = 1;
1572     }
1573 }
1574
1575 static void vl_api_tap_delete_reply_t_handler_json
1576   (vl_api_tap_delete_reply_t * mp)
1577 {
1578   vat_main_t *vam = &vat_main;
1579   vat_json_node_t node;
1580
1581   vat_json_init_object (&node);
1582   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1583
1584   vat_json_print (vam->ofp, &node);
1585   vat_json_free (&node);
1586
1587   vam->retval = ntohl (mp->retval);
1588   vam->result_ready = 1;
1589 }
1590
1591 static void vl_api_mpls_tunnel_add_del_reply_t_handler
1592   (vl_api_mpls_tunnel_add_del_reply_t * mp)
1593 {
1594   vat_main_t *vam = &vat_main;
1595   i32 retval = ntohl (mp->retval);
1596   if (vam->async_mode)
1597     {
1598       vam->async_errors += (retval < 0);
1599     }
1600   else
1601     {
1602       vam->retval = retval;
1603       vam->result_ready = 1;
1604     }
1605 }
1606
1607 static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
1608   (vl_api_mpls_tunnel_add_del_reply_t * mp)
1609 {
1610   vat_main_t *vam = &vat_main;
1611   vat_json_node_t node;
1612
1613   vat_json_init_object (&node);
1614   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1615   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
1616                             ntohl (mp->sw_if_index));
1617
1618   vat_json_print (vam->ofp, &node);
1619   vat_json_free (&node);
1620
1621   vam->retval = ntohl (mp->retval);
1622   vam->result_ready = 1;
1623 }
1624
1625 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
1626   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1627 {
1628   vat_main_t *vam = &vat_main;
1629   i32 retval = ntohl (mp->retval);
1630   if (vam->async_mode)
1631     {
1632       vam->async_errors += (retval < 0);
1633     }
1634   else
1635     {
1636       vam->retval = retval;
1637       vam->sw_if_index = ntohl (mp->sw_if_index);
1638       vam->result_ready = 1;
1639     }
1640 }
1641
1642 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
1643   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1644 {
1645   vat_main_t *vam = &vat_main;
1646   vat_json_node_t node;
1647
1648   vat_json_init_object (&node);
1649   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1650   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1651
1652   vat_json_print (vam->ofp, &node);
1653   vat_json_free (&node);
1654
1655   vam->retval = ntohl (mp->retval);
1656   vam->result_ready = 1;
1657 }
1658
1659
1660 static void vl_api_one_add_del_locator_set_reply_t_handler
1661   (vl_api_one_add_del_locator_set_reply_t * mp)
1662 {
1663   vat_main_t *vam = &vat_main;
1664   i32 retval = ntohl (mp->retval);
1665   if (vam->async_mode)
1666     {
1667       vam->async_errors += (retval < 0);
1668     }
1669   else
1670     {
1671       vam->retval = retval;
1672       vam->result_ready = 1;
1673     }
1674 }
1675
1676 static void vl_api_one_add_del_locator_set_reply_t_handler_json
1677   (vl_api_one_add_del_locator_set_reply_t * mp)
1678 {
1679   vat_main_t *vam = &vat_main;
1680   vat_json_node_t node;
1681
1682   vat_json_init_object (&node);
1683   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1684   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
1685
1686   vat_json_print (vam->ofp, &node);
1687   vat_json_free (&node);
1688
1689   vam->retval = ntohl (mp->retval);
1690   vam->result_ready = 1;
1691 }
1692
1693 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
1694   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1695 {
1696   vat_main_t *vam = &vat_main;
1697   i32 retval = ntohl (mp->retval);
1698   if (vam->async_mode)
1699     {
1700       vam->async_errors += (retval < 0);
1701     }
1702   else
1703     {
1704       vam->retval = retval;
1705       vam->sw_if_index = ntohl (mp->sw_if_index);
1706       vam->result_ready = 1;
1707     }
1708 }
1709
1710 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
1711   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1712 {
1713   vat_main_t *vam = &vat_main;
1714   vat_json_node_t node;
1715
1716   vat_json_init_object (&node);
1717   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1718   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1719
1720   vat_json_print (vam->ofp, &node);
1721   vat_json_free (&node);
1722
1723   vam->retval = ntohl (mp->retval);
1724   vam->result_ready = 1;
1725 }
1726
1727 static void vl_api_gre_add_del_tunnel_reply_t_handler
1728   (vl_api_gre_add_del_tunnel_reply_t * mp)
1729 {
1730   vat_main_t *vam = &vat_main;
1731   i32 retval = ntohl (mp->retval);
1732   if (vam->async_mode)
1733     {
1734       vam->async_errors += (retval < 0);
1735     }
1736   else
1737     {
1738       vam->retval = retval;
1739       vam->sw_if_index = ntohl (mp->sw_if_index);
1740       vam->result_ready = 1;
1741     }
1742 }
1743
1744 static void vl_api_gre_add_del_tunnel_reply_t_handler_json
1745   (vl_api_gre_add_del_tunnel_reply_t * mp)
1746 {
1747   vat_main_t *vam = &vat_main;
1748   vat_json_node_t node;
1749
1750   vat_json_init_object (&node);
1751   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1752   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1753
1754   vat_json_print (vam->ofp, &node);
1755   vat_json_free (&node);
1756
1757   vam->retval = ntohl (mp->retval);
1758   vam->result_ready = 1;
1759 }
1760
1761 static void vl_api_create_vhost_user_if_reply_t_handler
1762   (vl_api_create_vhost_user_if_reply_t * mp)
1763 {
1764   vat_main_t *vam = &vat_main;
1765   i32 retval = ntohl (mp->retval);
1766   if (vam->async_mode)
1767     {
1768       vam->async_errors += (retval < 0);
1769     }
1770   else
1771     {
1772       vam->retval = retval;
1773       vam->sw_if_index = ntohl (mp->sw_if_index);
1774       vam->result_ready = 1;
1775     }
1776 }
1777
1778 static void vl_api_create_vhost_user_if_reply_t_handler_json
1779   (vl_api_create_vhost_user_if_reply_t * mp)
1780 {
1781   vat_main_t *vam = &vat_main;
1782   vat_json_node_t node;
1783
1784   vat_json_init_object (&node);
1785   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1786   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1787
1788   vat_json_print (vam->ofp, &node);
1789   vat_json_free (&node);
1790
1791   vam->retval = ntohl (mp->retval);
1792   vam->result_ready = 1;
1793 }
1794
1795 static void vl_api_ip_address_details_t_handler
1796   (vl_api_ip_address_details_t * mp)
1797 {
1798   vat_main_t *vam = &vat_main;
1799   static ip_address_details_t empty_ip_address_details = { {0} };
1800   ip_address_details_t *address = NULL;
1801   ip_details_t *current_ip_details = NULL;
1802   ip_details_t *details = NULL;
1803
1804   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
1805
1806   if (!details || vam->current_sw_if_index >= vec_len (details)
1807       || !details[vam->current_sw_if_index].present)
1808     {
1809       errmsg ("ip address details arrived but not stored");
1810       errmsg ("ip_dump should be called first");
1811       return;
1812     }
1813
1814   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
1815
1816 #define addresses (current_ip_details->addr)
1817
1818   vec_validate_init_empty (addresses, vec_len (addresses),
1819                            empty_ip_address_details);
1820
1821   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
1822
1823   clib_memcpy (&address->ip, &mp->ip, sizeof (address->ip));
1824   address->prefix_length = mp->prefix_length;
1825 #undef addresses
1826 }
1827
1828 static void vl_api_ip_address_details_t_handler_json
1829   (vl_api_ip_address_details_t * mp)
1830 {
1831   vat_main_t *vam = &vat_main;
1832   vat_json_node_t *node = NULL;
1833   struct in6_addr ip6;
1834   struct in_addr ip4;
1835
1836   if (VAT_JSON_ARRAY != vam->json_tree.type)
1837     {
1838       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1839       vat_json_init_array (&vam->json_tree);
1840     }
1841   node = vat_json_array_add (&vam->json_tree);
1842
1843   vat_json_init_object (node);
1844   if (vam->is_ipv6)
1845     {
1846       clib_memcpy (&ip6, mp->ip, sizeof (ip6));
1847       vat_json_object_add_ip6 (node, "ip", ip6);
1848     }
1849   else
1850     {
1851       clib_memcpy (&ip4, mp->ip, sizeof (ip4));
1852       vat_json_object_add_ip4 (node, "ip", ip4);
1853     }
1854   vat_json_object_add_uint (node, "prefix_length", mp->prefix_length);
1855 }
1856
1857 static void
1858 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
1859 {
1860   vat_main_t *vam = &vat_main;
1861   static ip_details_t empty_ip_details = { 0 };
1862   ip_details_t *ip = NULL;
1863   u32 sw_if_index = ~0;
1864
1865   sw_if_index = ntohl (mp->sw_if_index);
1866
1867   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1868                            sw_if_index, empty_ip_details);
1869
1870   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1871                          sw_if_index);
1872
1873   ip->present = 1;
1874 }
1875
1876 static void
1877 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
1878 {
1879   vat_main_t *vam = &vat_main;
1880
1881   if (VAT_JSON_ARRAY != vam->json_tree.type)
1882     {
1883       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1884       vat_json_init_array (&vam->json_tree);
1885     }
1886   vat_json_array_add_uint (&vam->json_tree,
1887                            clib_net_to_host_u32 (mp->sw_if_index));
1888 }
1889
1890 static void vl_api_map_domain_details_t_handler_json
1891   (vl_api_map_domain_details_t * mp)
1892 {
1893   vat_json_node_t *node = NULL;
1894   vat_main_t *vam = &vat_main;
1895   struct in6_addr ip6;
1896   struct in_addr ip4;
1897
1898   if (VAT_JSON_ARRAY != vam->json_tree.type)
1899     {
1900       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1901       vat_json_init_array (&vam->json_tree);
1902     }
1903
1904   node = vat_json_array_add (&vam->json_tree);
1905   vat_json_init_object (node);
1906
1907   vat_json_object_add_uint (node, "domain_index",
1908                             clib_net_to_host_u32 (mp->domain_index));
1909   clib_memcpy (&ip6, mp->ip6_prefix, sizeof (ip6));
1910   vat_json_object_add_ip6 (node, "ip6_prefix", ip6);
1911   clib_memcpy (&ip4, mp->ip4_prefix, sizeof (ip4));
1912   vat_json_object_add_ip4 (node, "ip4_prefix", ip4);
1913   clib_memcpy (&ip6, mp->ip6_src, sizeof (ip6));
1914   vat_json_object_add_ip6 (node, "ip6_src", ip6);
1915   vat_json_object_add_int (node, "ip6_prefix_len", mp->ip6_prefix_len);
1916   vat_json_object_add_int (node, "ip4_prefix_len", mp->ip4_prefix_len);
1917   vat_json_object_add_int (node, "ip6_src_len", mp->ip6_src_len);
1918   vat_json_object_add_int (node, "ea_bits_len", mp->ea_bits_len);
1919   vat_json_object_add_int (node, "psid_offset", mp->psid_offset);
1920   vat_json_object_add_int (node, "psid_length", mp->psid_length);
1921   vat_json_object_add_uint (node, "flags", mp->flags);
1922   vat_json_object_add_uint (node, "mtu", clib_net_to_host_u16 (mp->mtu));
1923   vat_json_object_add_int (node, "is_translation", mp->is_translation);
1924 }
1925
1926 static void vl_api_map_domain_details_t_handler
1927   (vl_api_map_domain_details_t * mp)
1928 {
1929   vat_main_t *vam = &vat_main;
1930
1931   if (mp->is_translation)
1932     {
1933       print (vam->ofp,
1934              "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U/%d (ip6-src) index: %u",
1935              format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1936              format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1937              format_ip6_address, mp->ip6_src, mp->ip6_src_len,
1938              clib_net_to_host_u32 (mp->domain_index));
1939     }
1940   else
1941     {
1942       print (vam->ofp,
1943              "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U (ip6-src) index: %u",
1944              format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1945              format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1946              format_ip6_address, mp->ip6_src,
1947              clib_net_to_host_u32 (mp->domain_index));
1948     }
1949   print (vam->ofp, "  ea-len %d psid-offset %d psid-len %d mtu %d %s",
1950          mp->ea_bits_len, mp->psid_offset, mp->psid_length, mp->mtu,
1951          mp->is_translation ? "map-t" : "");
1952 }
1953
1954 static void vl_api_map_rule_details_t_handler_json
1955   (vl_api_map_rule_details_t * mp)
1956 {
1957   struct in6_addr ip6;
1958   vat_json_node_t *node = NULL;
1959   vat_main_t *vam = &vat_main;
1960
1961   if (VAT_JSON_ARRAY != vam->json_tree.type)
1962     {
1963       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1964       vat_json_init_array (&vam->json_tree);
1965     }
1966
1967   node = vat_json_array_add (&vam->json_tree);
1968   vat_json_init_object (node);
1969
1970   vat_json_object_add_uint (node, "psid", clib_net_to_host_u16 (mp->psid));
1971   clib_memcpy (&ip6, mp->ip6_dst, sizeof (ip6));
1972   vat_json_object_add_ip6 (node, "ip6_dst", ip6);
1973 }
1974
1975 static void
1976 vl_api_map_rule_details_t_handler (vl_api_map_rule_details_t * mp)
1977 {
1978   vat_main_t *vam = &vat_main;
1979   print (vam->ofp, " %d (psid) %U (ip6-dst)",
1980          clib_net_to_host_u16 (mp->psid), format_ip6_address, mp->ip6_dst);
1981 }
1982
1983 static void
1984 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
1985 {
1986   errmsg ("DHCP compl event: pid %d %s hostname %s host_addr %U "
1987           "router_addr %U host_mac %U",
1988           mp->pid, mp->is_ipv6 ? "ipv6" : "ipv4", mp->hostname,
1989           format_ip4_address, &mp->host_address,
1990           format_ip4_address, &mp->router_address,
1991           format_ethernet_address, mp->host_mac);
1992 }
1993
1994 static void vl_api_dhcp_compl_event_t_handler_json
1995   (vl_api_dhcp_compl_event_t * mp)
1996 {
1997   /* JSON output not supported */
1998 }
1999
2000 static void
2001 set_simple_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
2002                               u32 counter)
2003 {
2004   vat_main_t *vam = &vat_main;
2005   static u64 default_counter = 0;
2006
2007   vec_validate_init_empty (vam->simple_interface_counters, vnet_counter_type,
2008                            NULL);
2009   vec_validate_init_empty (vam->simple_interface_counters[vnet_counter_type],
2010                            sw_if_index, default_counter);
2011   vam->simple_interface_counters[vnet_counter_type][sw_if_index] = counter;
2012 }
2013
2014 static void
2015 set_combined_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
2016                                 interface_counter_t counter)
2017 {
2018   vat_main_t *vam = &vat_main;
2019   static interface_counter_t default_counter = { 0, };
2020
2021   vec_validate_init_empty (vam->combined_interface_counters,
2022                            vnet_counter_type, NULL);
2023   vec_validate_init_empty (vam->combined_interface_counters
2024                            [vnet_counter_type], sw_if_index, default_counter);
2025   vam->combined_interface_counters[vnet_counter_type][sw_if_index] = counter;
2026 }
2027
2028 static void vl_api_vnet_interface_counters_t_handler
2029   (vl_api_vnet_interface_counters_t * mp)
2030 {
2031   /* not supported */
2032 }
2033
2034 static void vl_api_vnet_interface_counters_t_handler_json
2035   (vl_api_vnet_interface_counters_t * mp)
2036 {
2037   interface_counter_t counter;
2038   vlib_counter_t *v;
2039   u64 *v_packets;
2040   u64 packets;
2041   u32 count;
2042   u32 first_sw_if_index;
2043   int i;
2044
2045   count = ntohl (mp->count);
2046   first_sw_if_index = ntohl (mp->first_sw_if_index);
2047
2048   if (!mp->is_combined)
2049     {
2050       v_packets = (u64 *) & mp->data;
2051       for (i = 0; i < count; i++)
2052         {
2053           packets =
2054             clib_net_to_host_u64 (clib_mem_unaligned (v_packets, u64));
2055           set_simple_interface_counter (mp->vnet_counter_type,
2056                                         first_sw_if_index + i, packets);
2057           v_packets++;
2058         }
2059     }
2060   else
2061     {
2062       v = (vlib_counter_t *) & mp->data;
2063       for (i = 0; i < count; i++)
2064         {
2065           counter.packets =
2066             clib_net_to_host_u64 (clib_mem_unaligned (&v->packets, u64));
2067           counter.bytes =
2068             clib_net_to_host_u64 (clib_mem_unaligned (&v->bytes, u64));
2069           set_combined_interface_counter (mp->vnet_counter_type,
2070                                           first_sw_if_index + i, counter);
2071           v++;
2072         }
2073     }
2074 }
2075
2076 static u32
2077 ip4_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2078 {
2079   vat_main_t *vam = &vat_main;
2080   u32 i;
2081
2082   for (i = 0; i < vec_len (vam->ip4_fib_counters_vrf_id_by_index); i++)
2083     {
2084       if (vam->ip4_fib_counters_vrf_id_by_index[i] == vrf_id)
2085         {
2086           return i;
2087         }
2088     }
2089   return ~0;
2090 }
2091
2092 static u32
2093 ip6_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2094 {
2095   vat_main_t *vam = &vat_main;
2096   u32 i;
2097
2098   for (i = 0; i < vec_len (vam->ip6_fib_counters_vrf_id_by_index); i++)
2099     {
2100       if (vam->ip6_fib_counters_vrf_id_by_index[i] == vrf_id)
2101         {
2102           return i;
2103         }
2104     }
2105   return ~0;
2106 }
2107
2108 static void vl_api_vnet_ip4_fib_counters_t_handler
2109   (vl_api_vnet_ip4_fib_counters_t * mp)
2110 {
2111   /* not supported */
2112 }
2113
2114 static void vl_api_vnet_ip4_fib_counters_t_handler_json
2115   (vl_api_vnet_ip4_fib_counters_t * mp)
2116 {
2117   vat_main_t *vam = &vat_main;
2118   vl_api_ip4_fib_counter_t *v;
2119   ip4_fib_counter_t *counter;
2120   struct in_addr ip4;
2121   u32 vrf_id;
2122   u32 vrf_index;
2123   u32 count;
2124   int i;
2125
2126   vrf_id = ntohl (mp->vrf_id);
2127   vrf_index = ip4_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2128   if (~0 == vrf_index)
2129     {
2130       vrf_index = vec_len (vam->ip4_fib_counters_vrf_id_by_index);
2131       vec_validate (vam->ip4_fib_counters_vrf_id_by_index, vrf_index);
2132       vam->ip4_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2133       vec_validate (vam->ip4_fib_counters, vrf_index);
2134       vam->ip4_fib_counters[vrf_index] = NULL;
2135     }
2136
2137   vec_free (vam->ip4_fib_counters[vrf_index]);
2138   v = (vl_api_ip4_fib_counter_t *) & mp->c;
2139   count = ntohl (mp->count);
2140   for (i = 0; i < count; i++)
2141     {
2142       vec_validate (vam->ip4_fib_counters[vrf_index], i);
2143       counter = &vam->ip4_fib_counters[vrf_index][i];
2144       clib_memcpy (&ip4, &v->address, sizeof (ip4));
2145       counter->address = ip4;
2146       counter->address_length = v->address_length;
2147       counter->packets = clib_net_to_host_u64 (v->packets);
2148       counter->bytes = clib_net_to_host_u64 (v->bytes);
2149       v++;
2150     }
2151 }
2152
2153 static void vl_api_vnet_ip4_nbr_counters_t_handler
2154   (vl_api_vnet_ip4_nbr_counters_t * mp)
2155 {
2156   /* not supported */
2157 }
2158
2159 static void vl_api_vnet_ip4_nbr_counters_t_handler_json
2160   (vl_api_vnet_ip4_nbr_counters_t * mp)
2161 {
2162   vat_main_t *vam = &vat_main;
2163   vl_api_ip4_nbr_counter_t *v;
2164   ip4_nbr_counter_t *counter;
2165   u32 sw_if_index;
2166   u32 count;
2167   int i;
2168
2169   sw_if_index = ntohl (mp->sw_if_index);
2170   count = ntohl (mp->count);
2171   vec_validate (vam->ip4_nbr_counters, sw_if_index);
2172
2173   if (mp->begin)
2174     vec_free (vam->ip4_nbr_counters[sw_if_index]);
2175
2176   v = (vl_api_ip4_nbr_counter_t *) & mp->c;
2177   for (i = 0; i < count; i++)
2178     {
2179       vec_validate (vam->ip4_nbr_counters[sw_if_index], i);
2180       counter = &vam->ip4_nbr_counters[sw_if_index][i];
2181       counter->address.s_addr = v->address;
2182       counter->packets = clib_net_to_host_u64 (v->packets);
2183       counter->bytes = clib_net_to_host_u64 (v->bytes);
2184       counter->linkt = v->link_type;
2185       v++;
2186     }
2187 }
2188
2189 static void vl_api_vnet_ip6_fib_counters_t_handler
2190   (vl_api_vnet_ip6_fib_counters_t * mp)
2191 {
2192   /* not supported */
2193 }
2194
2195 static void vl_api_vnet_ip6_fib_counters_t_handler_json
2196   (vl_api_vnet_ip6_fib_counters_t * mp)
2197 {
2198   vat_main_t *vam = &vat_main;
2199   vl_api_ip6_fib_counter_t *v;
2200   ip6_fib_counter_t *counter;
2201   struct in6_addr ip6;
2202   u32 vrf_id;
2203   u32 vrf_index;
2204   u32 count;
2205   int i;
2206
2207   vrf_id = ntohl (mp->vrf_id);
2208   vrf_index = ip6_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2209   if (~0 == vrf_index)
2210     {
2211       vrf_index = vec_len (vam->ip6_fib_counters_vrf_id_by_index);
2212       vec_validate (vam->ip6_fib_counters_vrf_id_by_index, vrf_index);
2213       vam->ip6_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2214       vec_validate (vam->ip6_fib_counters, vrf_index);
2215       vam->ip6_fib_counters[vrf_index] = NULL;
2216     }
2217
2218   vec_free (vam->ip6_fib_counters[vrf_index]);
2219   v = (vl_api_ip6_fib_counter_t *) & mp->c;
2220   count = ntohl (mp->count);
2221   for (i = 0; i < count; i++)
2222     {
2223       vec_validate (vam->ip6_fib_counters[vrf_index], i);
2224       counter = &vam->ip6_fib_counters[vrf_index][i];
2225       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2226       counter->address = ip6;
2227       counter->address_length = v->address_length;
2228       counter->packets = clib_net_to_host_u64 (v->packets);
2229       counter->bytes = clib_net_to_host_u64 (v->bytes);
2230       v++;
2231     }
2232 }
2233
2234 static void vl_api_vnet_ip6_nbr_counters_t_handler
2235   (vl_api_vnet_ip6_nbr_counters_t * mp)
2236 {
2237   /* not supported */
2238 }
2239
2240 static void vl_api_vnet_ip6_nbr_counters_t_handler_json
2241   (vl_api_vnet_ip6_nbr_counters_t * mp)
2242 {
2243   vat_main_t *vam = &vat_main;
2244   vl_api_ip6_nbr_counter_t *v;
2245   ip6_nbr_counter_t *counter;
2246   struct in6_addr ip6;
2247   u32 sw_if_index;
2248   u32 count;
2249   int i;
2250
2251   sw_if_index = ntohl (mp->sw_if_index);
2252   count = ntohl (mp->count);
2253   vec_validate (vam->ip6_nbr_counters, sw_if_index);
2254
2255   if (mp->begin)
2256     vec_free (vam->ip6_nbr_counters[sw_if_index]);
2257
2258   v = (vl_api_ip6_nbr_counter_t *) & mp->c;
2259   for (i = 0; i < count; i++)
2260     {
2261       vec_validate (vam->ip6_nbr_counters[sw_if_index], i);
2262       counter = &vam->ip6_nbr_counters[sw_if_index][i];
2263       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2264       counter->address = ip6;
2265       counter->packets = clib_net_to_host_u64 (v->packets);
2266       counter->bytes = clib_net_to_host_u64 (v->bytes);
2267       v++;
2268     }
2269 }
2270
2271 static void vl_api_get_first_msg_id_reply_t_handler
2272   (vl_api_get_first_msg_id_reply_t * mp)
2273 {
2274   vat_main_t *vam = &vat_main;
2275   i32 retval = ntohl (mp->retval);
2276
2277   if (vam->async_mode)
2278     {
2279       vam->async_errors += (retval < 0);
2280     }
2281   else
2282     {
2283       vam->retval = retval;
2284       vam->result_ready = 1;
2285     }
2286   if (retval >= 0)
2287     {
2288       errmsg ("first message id %d", ntohs (mp->first_msg_id));
2289     }
2290 }
2291
2292 static void vl_api_get_first_msg_id_reply_t_handler_json
2293   (vl_api_get_first_msg_id_reply_t * mp)
2294 {
2295   vat_main_t *vam = &vat_main;
2296   vat_json_node_t node;
2297
2298   vat_json_init_object (&node);
2299   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2300   vat_json_object_add_uint (&node, "first_msg_id",
2301                             (uint) ntohs (mp->first_msg_id));
2302
2303   vat_json_print (vam->ofp, &node);
2304   vat_json_free (&node);
2305
2306   vam->retval = ntohl (mp->retval);
2307   vam->result_ready = 1;
2308 }
2309
2310 static void vl_api_get_node_graph_reply_t_handler
2311   (vl_api_get_node_graph_reply_t * mp)
2312 {
2313   vat_main_t *vam = &vat_main;
2314   api_main_t *am = &api_main;
2315   i32 retval = ntohl (mp->retval);
2316   u8 *pvt_copy, *reply;
2317   void *oldheap;
2318   vlib_node_t *node;
2319   int i;
2320
2321   if (vam->async_mode)
2322     {
2323       vam->async_errors += (retval < 0);
2324     }
2325   else
2326     {
2327       vam->retval = retval;
2328       vam->result_ready = 1;
2329     }
2330
2331   /* "Should never happen..." */
2332   if (retval != 0)
2333     return;
2334
2335   reply = (u8 *) (mp->reply_in_shmem);
2336   pvt_copy = vec_dup (reply);
2337
2338   /* Toss the shared-memory original... */
2339   pthread_mutex_lock (&am->vlib_rp->mutex);
2340   oldheap = svm_push_data_heap (am->vlib_rp);
2341
2342   vec_free (reply);
2343
2344   svm_pop_heap (oldheap);
2345   pthread_mutex_unlock (&am->vlib_rp->mutex);
2346
2347   if (vam->graph_nodes)
2348     {
2349       hash_free (vam->graph_node_index_by_name);
2350
2351       for (i = 0; i < vec_len (vam->graph_nodes); i++)
2352         {
2353           node = vam->graph_nodes[i];
2354           vec_free (node->name);
2355           vec_free (node->next_nodes);
2356           vec_free (node);
2357         }
2358       vec_free (vam->graph_nodes);
2359     }
2360
2361   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2362   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2363   vec_free (pvt_copy);
2364
2365   for (i = 0; i < vec_len (vam->graph_nodes); i++)
2366     {
2367       node = vam->graph_nodes[i];
2368       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2369     }
2370 }
2371
2372 static void vl_api_get_node_graph_reply_t_handler_json
2373   (vl_api_get_node_graph_reply_t * mp)
2374 {
2375   vat_main_t *vam = &vat_main;
2376   api_main_t *am = &api_main;
2377   void *oldheap;
2378   vat_json_node_t node;
2379   u8 *reply;
2380
2381   /* $$$$ make this real? */
2382   vat_json_init_object (&node);
2383   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2384   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2385
2386   reply = (u8 *) (mp->reply_in_shmem);
2387
2388   /* Toss the shared-memory original... */
2389   pthread_mutex_lock (&am->vlib_rp->mutex);
2390   oldheap = svm_push_data_heap (am->vlib_rp);
2391
2392   vec_free (reply);
2393
2394   svm_pop_heap (oldheap);
2395   pthread_mutex_unlock (&am->vlib_rp->mutex);
2396
2397   vat_json_print (vam->ofp, &node);
2398   vat_json_free (&node);
2399
2400   vam->retval = ntohl (mp->retval);
2401   vam->result_ready = 1;
2402 }
2403
2404 static void
2405 vl_api_one_locator_details_t_handler (vl_api_one_locator_details_t * mp)
2406 {
2407   vat_main_t *vam = &vat_main;
2408   u8 *s = 0;
2409
2410   if (mp->local)
2411     {
2412       s = format (s, "%=16d%=16d%=16d",
2413                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
2414     }
2415   else
2416     {
2417       s = format (s, "%=16U%=16d%=16d",
2418                   mp->is_ipv6 ? format_ip6_address :
2419                   format_ip4_address,
2420                   mp->ip_address, mp->priority, mp->weight);
2421     }
2422
2423   print (vam->ofp, "%v", s);
2424   vec_free (s);
2425 }
2426
2427 static void
2428 vl_api_one_locator_details_t_handler_json (vl_api_one_locator_details_t * mp)
2429 {
2430   vat_main_t *vam = &vat_main;
2431   vat_json_node_t *node = NULL;
2432   struct in6_addr ip6;
2433   struct in_addr ip4;
2434
2435   if (VAT_JSON_ARRAY != vam->json_tree.type)
2436     {
2437       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2438       vat_json_init_array (&vam->json_tree);
2439     }
2440   node = vat_json_array_add (&vam->json_tree);
2441   vat_json_init_object (node);
2442
2443   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2444   vat_json_object_add_uint (node, "priority", mp->priority);
2445   vat_json_object_add_uint (node, "weight", mp->weight);
2446
2447   if (mp->local)
2448     vat_json_object_add_uint (node, "sw_if_index",
2449                               clib_net_to_host_u32 (mp->sw_if_index));
2450   else
2451     {
2452       if (mp->is_ipv6)
2453         {
2454           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2455           vat_json_object_add_ip6 (node, "address", ip6);
2456         }
2457       else
2458         {
2459           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2460           vat_json_object_add_ip4 (node, "address", ip4);
2461         }
2462     }
2463 }
2464
2465 static void
2466 vl_api_one_locator_set_details_t_handler (vl_api_one_locator_set_details_t *
2467                                           mp)
2468 {
2469   vat_main_t *vam = &vat_main;
2470   u8 *ls_name = 0;
2471
2472   ls_name = format (0, "%s", mp->ls_name);
2473
2474   print (vam->ofp, "%=10d%=15v", clib_net_to_host_u32 (mp->ls_index),
2475          ls_name);
2476   vec_free (ls_name);
2477 }
2478
2479 static void
2480   vl_api_one_locator_set_details_t_handler_json
2481   (vl_api_one_locator_set_details_t * mp)
2482 {
2483   vat_main_t *vam = &vat_main;
2484   vat_json_node_t *node = 0;
2485   u8 *ls_name = 0;
2486
2487   ls_name = format (0, "%s", mp->ls_name);
2488   vec_add1 (ls_name, 0);
2489
2490   if (VAT_JSON_ARRAY != vam->json_tree.type)
2491     {
2492       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2493       vat_json_init_array (&vam->json_tree);
2494     }
2495   node = vat_json_array_add (&vam->json_tree);
2496
2497   vat_json_init_object (node);
2498   vat_json_object_add_string_copy (node, "ls_name", ls_name);
2499   vat_json_object_add_uint (node, "ls_index",
2500                             clib_net_to_host_u32 (mp->ls_index));
2501   vec_free (ls_name);
2502 }
2503
2504 static u8 *
2505 format_lisp_flat_eid (u8 * s, va_list * args)
2506 {
2507   u32 type = va_arg (*args, u32);
2508   u8 *eid = va_arg (*args, u8 *);
2509   u32 eid_len = va_arg (*args, u32);
2510
2511   switch (type)
2512     {
2513     case 0:
2514       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
2515     case 1:
2516       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
2517     case 2:
2518       return format (s, "%U", format_ethernet_address, eid);
2519     }
2520   return 0;
2521 }
2522
2523 static u8 *
2524 format_lisp_eid_vat (u8 * s, va_list * args)
2525 {
2526   u32 type = va_arg (*args, u32);
2527   u8 *eid = va_arg (*args, u8 *);
2528   u32 eid_len = va_arg (*args, u32);
2529   u8 *seid = va_arg (*args, u8 *);
2530   u32 seid_len = va_arg (*args, u32);
2531   u32 is_src_dst = va_arg (*args, u32);
2532
2533   if (is_src_dst)
2534     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
2535
2536   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
2537
2538   return s;
2539 }
2540
2541 static void
2542 vl_api_one_eid_table_details_t_handler (vl_api_one_eid_table_details_t * mp)
2543 {
2544   vat_main_t *vam = &vat_main;
2545   u8 *s = 0, *eid = 0;
2546
2547   if (~0 == mp->locator_set_index)
2548     s = format (0, "action: %d", mp->action);
2549   else
2550     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
2551
2552   eid = format (0, "%U", format_lisp_eid_vat,
2553                 mp->eid_type,
2554                 mp->eid,
2555                 mp->eid_prefix_len,
2556                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2557   vec_add1 (eid, 0);
2558
2559   print (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s",
2560          clib_net_to_host_u32 (mp->vni),
2561          eid,
2562          mp->is_local ? "local" : "remote",
2563          s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
2564          clib_net_to_host_u16 (mp->key_id), mp->key);
2565
2566   vec_free (s);
2567   vec_free (eid);
2568 }
2569
2570 static void
2571 vl_api_one_eid_table_details_t_handler_json (vl_api_one_eid_table_details_t
2572                                              * mp)
2573 {
2574   vat_main_t *vam = &vat_main;
2575   vat_json_node_t *node = 0;
2576   u8 *eid = 0;
2577
2578   if (VAT_JSON_ARRAY != vam->json_tree.type)
2579     {
2580       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2581       vat_json_init_array (&vam->json_tree);
2582     }
2583   node = vat_json_array_add (&vam->json_tree);
2584
2585   vat_json_init_object (node);
2586   if (~0 == mp->locator_set_index)
2587     vat_json_object_add_uint (node, "action", mp->action);
2588   else
2589     vat_json_object_add_uint (node, "locator_set_index",
2590                               clib_net_to_host_u32 (mp->locator_set_index));
2591
2592   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
2593   eid = format (0, "%U", format_lisp_eid_vat,
2594                 mp->eid_type,
2595                 mp->eid,
2596                 mp->eid_prefix_len,
2597                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2598   vec_add1 (eid, 0);
2599   vat_json_object_add_string_copy (node, "eid", eid);
2600   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2601   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
2602   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
2603
2604   if (mp->key_id)
2605     {
2606       vat_json_object_add_uint (node, "key_id",
2607                                 clib_net_to_host_u16 (mp->key_id));
2608       vat_json_object_add_string_copy (node, "key", mp->key);
2609     }
2610   vec_free (eid);
2611 }
2612
2613 static void
2614   vl_api_one_eid_table_map_details_t_handler
2615   (vl_api_one_eid_table_map_details_t * mp)
2616 {
2617   vat_main_t *vam = &vat_main;
2618
2619   u8 *line = format (0, "%=10d%=10d",
2620                      clib_net_to_host_u32 (mp->vni),
2621                      clib_net_to_host_u32 (mp->dp_table));
2622   print (vam->ofp, "%v", line);
2623   vec_free (line);
2624 }
2625
2626 static void
2627   vl_api_one_eid_table_map_details_t_handler_json
2628   (vl_api_one_eid_table_map_details_t * mp)
2629 {
2630   vat_main_t *vam = &vat_main;
2631   vat_json_node_t *node = NULL;
2632
2633   if (VAT_JSON_ARRAY != vam->json_tree.type)
2634     {
2635       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2636       vat_json_init_array (&vam->json_tree);
2637     }
2638   node = vat_json_array_add (&vam->json_tree);
2639   vat_json_init_object (node);
2640   vat_json_object_add_uint (node, "dp_table",
2641                             clib_net_to_host_u32 (mp->dp_table));
2642   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2643 }
2644
2645 static void
2646   vl_api_one_eid_table_vni_details_t_handler
2647   (vl_api_one_eid_table_vni_details_t * mp)
2648 {
2649   vat_main_t *vam = &vat_main;
2650
2651   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
2652   print (vam->ofp, "%v", line);
2653   vec_free (line);
2654 }
2655
2656 static void
2657   vl_api_one_eid_table_vni_details_t_handler_json
2658   (vl_api_one_eid_table_vni_details_t * mp)
2659 {
2660   vat_main_t *vam = &vat_main;
2661   vat_json_node_t *node = NULL;
2662
2663   if (VAT_JSON_ARRAY != vam->json_tree.type)
2664     {
2665       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2666       vat_json_init_array (&vam->json_tree);
2667     }
2668   node = vat_json_array_add (&vam->json_tree);
2669   vat_json_init_object (node);
2670   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2671 }
2672
2673 static void
2674   vl_api_show_one_map_register_state_reply_t_handler
2675   (vl_api_show_one_map_register_state_reply_t * mp)
2676 {
2677   vat_main_t *vam = &vat_main;
2678   int retval = clib_net_to_host_u32 (mp->retval);
2679
2680   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
2681
2682   vam->retval = retval;
2683   vam->result_ready = 1;
2684 }
2685
2686 static void
2687   vl_api_show_one_map_register_state_reply_t_handler_json
2688   (vl_api_show_one_map_register_state_reply_t * mp)
2689 {
2690   vat_main_t *vam = &vat_main;
2691   vat_json_node_t _node, *node = &_node;
2692   int retval = clib_net_to_host_u32 (mp->retval);
2693
2694   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
2695
2696   vat_json_init_object (node);
2697   vat_json_object_add_string_copy (node, "state", s);
2698
2699   vat_json_print (vam->ofp, node);
2700   vat_json_free (node);
2701
2702   vam->retval = retval;
2703   vam->result_ready = 1;
2704   vec_free (s);
2705 }
2706
2707 static void
2708   vl_api_show_one_rloc_probe_state_reply_t_handler
2709   (vl_api_show_one_rloc_probe_state_reply_t * mp)
2710 {
2711   vat_main_t *vam = &vat_main;
2712   int retval = clib_net_to_host_u32 (mp->retval);
2713
2714   if (retval)
2715     goto end;
2716
2717   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
2718 end:
2719   vam->retval = retval;
2720   vam->result_ready = 1;
2721 }
2722
2723 static void
2724   vl_api_show_one_rloc_probe_state_reply_t_handler_json
2725   (vl_api_show_one_rloc_probe_state_reply_t * mp)
2726 {
2727   vat_main_t *vam = &vat_main;
2728   vat_json_node_t _node, *node = &_node;
2729   int retval = clib_net_to_host_u32 (mp->retval);
2730
2731   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
2732   vat_json_init_object (node);
2733   vat_json_object_add_string_copy (node, "state", s);
2734
2735   vat_json_print (vam->ofp, node);
2736   vat_json_free (node);
2737
2738   vam->retval = retval;
2739   vam->result_ready = 1;
2740   vec_free (s);
2741 }
2742
2743 static void
2744 api_gpe_fwd_entry_net_to_host (vl_api_gpe_fwd_entry_t * e)
2745 {
2746   e->dp_table = clib_net_to_host_u32 (e->dp_table);
2747   e->fwd_entry_index = clib_net_to_host_u32 (e->fwd_entry_index);
2748 }
2749
2750 static void
2751   gpe_fwd_entries_get_reply_t_net_to_host
2752   (vl_api_gpe_fwd_entries_get_reply_t * mp)
2753 {
2754   u32 i;
2755
2756   mp->count = clib_net_to_host_u32 (mp->count);
2757   for (i = 0; i < mp->count; i++)
2758     {
2759       api_gpe_fwd_entry_net_to_host (&mp->entries[i]);
2760     }
2761 }
2762
2763 static u8 *
2764 format_gpe_encap_mode (u8 * s, va_list * args)
2765 {
2766   u32 mode = va_arg (*args, u32);
2767
2768   switch (mode)
2769     {
2770     case 0:
2771       return format (s, "lisp");
2772     case 1:
2773       return format (s, "vxlan");
2774     }
2775   return 0;
2776 }
2777
2778 static void
2779   vl_api_gpe_get_encap_mode_reply_t_handler
2780   (vl_api_gpe_get_encap_mode_reply_t * mp)
2781 {
2782   vat_main_t *vam = &vat_main;
2783
2784   print (vam->ofp, "gpe mode: %U", format_gpe_encap_mode, mp->encap_mode);
2785   vam->retval = ntohl (mp->retval);
2786   vam->result_ready = 1;
2787 }
2788
2789 static void
2790   vl_api_gpe_get_encap_mode_reply_t_handler_json
2791   (vl_api_gpe_get_encap_mode_reply_t * mp)
2792 {
2793   vat_main_t *vam = &vat_main;
2794   vat_json_node_t node;
2795
2796   u8 *encap_mode = format (0, "%U", format_gpe_encap_mode, mp->encap_mode);
2797   vec_add1 (encap_mode, 0);
2798
2799   vat_json_init_object (&node);
2800   vat_json_object_add_string_copy (&node, "gpe_mode", encap_mode);
2801
2802   vec_free (encap_mode);
2803   vat_json_print (vam->ofp, &node);
2804   vat_json_free (&node);
2805
2806   vam->retval = ntohl (mp->retval);
2807   vam->result_ready = 1;
2808 }
2809
2810 static void
2811   vl_api_gpe_fwd_entry_path_details_t_handler
2812   (vl_api_gpe_fwd_entry_path_details_t * mp)
2813 {
2814   vat_main_t *vam = &vat_main;
2815   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
2816
2817   if (mp->lcl_loc.is_ip4)
2818     format_ip_address_fcn = format_ip4_address;
2819   else
2820     format_ip_address_fcn = format_ip6_address;
2821
2822   print (vam->ofp, "w:%d %30U %30U", mp->rmt_loc.weight,
2823          format_ip_address_fcn, &mp->lcl_loc,
2824          format_ip_address_fcn, &mp->rmt_loc);
2825 }
2826
2827 static void
2828 lisp_fill_locator_node (vat_json_node_t * n, vl_api_gpe_locator_t * loc)
2829 {
2830   struct in6_addr ip6;
2831   struct in_addr ip4;
2832
2833   if (loc->is_ip4)
2834     {
2835       clib_memcpy (&ip4, loc->addr, sizeof (ip4));
2836       vat_json_object_add_ip4 (n, "address", ip4);
2837     }
2838   else
2839     {
2840       clib_memcpy (&ip6, loc->addr, sizeof (ip6));
2841       vat_json_object_add_ip6 (n, "address", ip6);
2842     }
2843   vat_json_object_add_uint (n, "weight", loc->weight);
2844 }
2845
2846 static void
2847   vl_api_gpe_fwd_entry_path_details_t_handler_json
2848   (vl_api_gpe_fwd_entry_path_details_t * mp)
2849 {
2850   vat_main_t *vam = &vat_main;
2851   vat_json_node_t *node = NULL;
2852   vat_json_node_t *loc_node;
2853
2854   if (VAT_JSON_ARRAY != vam->json_tree.type)
2855     {
2856       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2857       vat_json_init_array (&vam->json_tree);
2858     }
2859   node = vat_json_array_add (&vam->json_tree);
2860   vat_json_init_object (node);
2861
2862   loc_node = vat_json_object_add (node, "local_locator");
2863   vat_json_init_object (loc_node);
2864   lisp_fill_locator_node (loc_node, &mp->lcl_loc);
2865
2866   loc_node = vat_json_object_add (node, "remote_locator");
2867   vat_json_init_object (loc_node);
2868   lisp_fill_locator_node (loc_node, &mp->rmt_loc);
2869 }
2870
2871 static void
2872   vl_api_gpe_fwd_entries_get_reply_t_handler
2873   (vl_api_gpe_fwd_entries_get_reply_t * mp)
2874 {
2875   vat_main_t *vam = &vat_main;
2876   u32 i;
2877   int retval = clib_net_to_host_u32 (mp->retval);
2878   vl_api_gpe_fwd_entry_t *e;
2879
2880   if (retval)
2881     goto end;
2882
2883   gpe_fwd_entries_get_reply_t_net_to_host (mp);
2884
2885   for (i = 0; i < mp->count; i++)
2886     {
2887       e = &mp->entries[i];
2888       print (vam->ofp, "%10d %10d %U %40U", e->fwd_entry_index, e->dp_table,
2889              format_lisp_flat_eid, e->eid_type, e->leid, e->leid_prefix_len,
2890              format_lisp_flat_eid, e->eid_type, e->reid, e->reid_prefix_len);
2891     }
2892
2893 end:
2894   vam->retval = retval;
2895   vam->result_ready = 1;
2896 }
2897
2898 static void
2899   vl_api_gpe_fwd_entries_get_reply_t_handler_json
2900   (vl_api_gpe_fwd_entries_get_reply_t * mp)
2901 {
2902   u8 *s = 0;
2903   vat_main_t *vam = &vat_main;
2904   vat_json_node_t *e = 0, root;
2905   u32 i;
2906   int retval = clib_net_to_host_u32 (mp->retval);
2907   vl_api_gpe_fwd_entry_t *fwd;
2908
2909   if (retval)
2910     goto end;
2911
2912   gpe_fwd_entries_get_reply_t_net_to_host (mp);
2913   vat_json_init_array (&root);
2914
2915   for (i = 0; i < mp->count; i++)
2916     {
2917       e = vat_json_array_add (&root);
2918       fwd = &mp->entries[i];
2919
2920       vat_json_init_object (e);
2921       vat_json_object_add_int (e, "fwd_entry_index", fwd->fwd_entry_index);
2922       vat_json_object_add_int (e, "dp_table", fwd->dp_table);
2923
2924       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->leid,
2925                   fwd->leid_prefix_len);
2926       vec_add1 (s, 0);
2927       vat_json_object_add_string_copy (e, "leid", s);
2928       vec_free (s);
2929
2930       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->reid,
2931                   fwd->reid_prefix_len);
2932       vec_add1 (s, 0);
2933       vat_json_object_add_string_copy (e, "reid", s);
2934       vec_free (s);
2935     }
2936
2937   vat_json_print (vam->ofp, &root);
2938   vat_json_free (&root);
2939
2940 end:
2941   vam->retval = retval;
2942   vam->result_ready = 1;
2943 }
2944
2945 static void
2946   vl_api_one_adjacencies_get_reply_t_handler
2947   (vl_api_one_adjacencies_get_reply_t * mp)
2948 {
2949   vat_main_t *vam = &vat_main;
2950   u32 i, n;
2951   int retval = clib_net_to_host_u32 (mp->retval);
2952   vl_api_one_adjacency_t *a;
2953
2954   if (retval)
2955     goto end;
2956
2957   n = clib_net_to_host_u32 (mp->count);
2958
2959   for (i = 0; i < n; i++)
2960     {
2961       a = &mp->adjacencies[i];
2962       print (vam->ofp, "%U %40U",
2963              format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
2964              format_lisp_flat_eid, a->eid_type, a->reid, a->reid_prefix_len);
2965     }
2966
2967 end:
2968   vam->retval = retval;
2969   vam->result_ready = 1;
2970 }
2971
2972 static void
2973   vl_api_one_adjacencies_get_reply_t_handler_json
2974   (vl_api_one_adjacencies_get_reply_t * mp)
2975 {
2976   u8 *s = 0;
2977   vat_main_t *vam = &vat_main;
2978   vat_json_node_t *e = 0, root;
2979   u32 i, n;
2980   int retval = clib_net_to_host_u32 (mp->retval);
2981   vl_api_one_adjacency_t *a;
2982
2983   if (retval)
2984     goto end;
2985
2986   n = clib_net_to_host_u32 (mp->count);
2987   vat_json_init_array (&root);
2988
2989   for (i = 0; i < n; i++)
2990     {
2991       e = vat_json_array_add (&root);
2992       a = &mp->adjacencies[i];
2993
2994       vat_json_init_object (e);
2995       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
2996                   a->leid_prefix_len);
2997       vec_add1 (s, 0);
2998       vat_json_object_add_string_copy (e, "leid", s);
2999       vec_free (s);
3000
3001       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
3002                   a->reid_prefix_len);
3003       vec_add1 (s, 0);
3004       vat_json_object_add_string_copy (e, "reid", s);
3005       vec_free (s);
3006     }
3007
3008   vat_json_print (vam->ofp, &root);
3009   vat_json_free (&root);
3010
3011 end:
3012   vam->retval = retval;
3013   vam->result_ready = 1;
3014 }
3015
3016 static void
3017 vl_api_one_map_server_details_t_handler (vl_api_one_map_server_details_t * mp)
3018 {
3019   vat_main_t *vam = &vat_main;
3020
3021   print (vam->ofp, "%=20U",
3022          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
3023          mp->ip_address);
3024 }
3025
3026 static void
3027   vl_api_one_map_server_details_t_handler_json
3028   (vl_api_one_map_server_details_t * mp)
3029 {
3030   vat_main_t *vam = &vat_main;
3031   vat_json_node_t *node = NULL;
3032   struct in6_addr ip6;
3033   struct in_addr ip4;
3034
3035   if (VAT_JSON_ARRAY != vam->json_tree.type)
3036     {
3037       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3038       vat_json_init_array (&vam->json_tree);
3039     }
3040   node = vat_json_array_add (&vam->json_tree);
3041
3042   vat_json_init_object (node);
3043   if (mp->is_ipv6)
3044     {
3045       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
3046       vat_json_object_add_ip6 (node, "map-server", ip6);
3047     }
3048   else
3049     {
3050       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
3051       vat_json_object_add_ip4 (node, "map-server", ip4);
3052     }
3053 }
3054
3055 static void
3056 vl_api_one_map_resolver_details_t_handler (vl_api_one_map_resolver_details_t
3057                                            * mp)
3058 {
3059   vat_main_t *vam = &vat_main;
3060
3061   print (vam->ofp, "%=20U",
3062          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
3063          mp->ip_address);
3064 }
3065
3066 static void
3067   vl_api_one_map_resolver_details_t_handler_json
3068   (vl_api_one_map_resolver_details_t * mp)
3069 {
3070   vat_main_t *vam = &vat_main;
3071   vat_json_node_t *node = NULL;
3072   struct in6_addr ip6;
3073   struct in_addr ip4;
3074
3075   if (VAT_JSON_ARRAY != vam->json_tree.type)
3076     {
3077       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3078       vat_json_init_array (&vam->json_tree);
3079     }
3080   node = vat_json_array_add (&vam->json_tree);
3081
3082   vat_json_init_object (node);
3083   if (mp->is_ipv6)
3084     {
3085       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
3086       vat_json_object_add_ip6 (node, "map resolver", ip6);
3087     }
3088   else
3089     {
3090       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
3091       vat_json_object_add_ip4 (node, "map resolver", ip4);
3092     }
3093 }
3094
3095 static void
3096 vl_api_show_one_status_reply_t_handler (vl_api_show_one_status_reply_t * mp)
3097 {
3098   vat_main_t *vam = &vat_main;
3099   i32 retval = ntohl (mp->retval);
3100
3101   if (0 <= retval)
3102     {
3103       print (vam->ofp, "feature: %s\ngpe: %s",
3104              mp->feature_status ? "enabled" : "disabled",
3105              mp->gpe_status ? "enabled" : "disabled");
3106     }
3107
3108   vam->retval = retval;
3109   vam->result_ready = 1;
3110 }
3111
3112 static void
3113   vl_api_show_one_status_reply_t_handler_json
3114   (vl_api_show_one_status_reply_t * mp)
3115 {
3116   vat_main_t *vam = &vat_main;
3117   vat_json_node_t node;
3118   u8 *gpe_status = NULL;
3119   u8 *feature_status = NULL;
3120
3121   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
3122   feature_status = format (0, "%s",
3123                            mp->feature_status ? "enabled" : "disabled");
3124   vec_add1 (gpe_status, 0);
3125   vec_add1 (feature_status, 0);
3126
3127   vat_json_init_object (&node);
3128   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
3129   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
3130
3131   vec_free (gpe_status);
3132   vec_free (feature_status);
3133
3134   vat_json_print (vam->ofp, &node);
3135   vat_json_free (&node);
3136
3137   vam->retval = ntohl (mp->retval);
3138   vam->result_ready = 1;
3139 }
3140
3141 static void
3142   vl_api_one_get_map_request_itr_rlocs_reply_t_handler
3143   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
3144 {
3145   vat_main_t *vam = &vat_main;
3146   i32 retval = ntohl (mp->retval);
3147
3148   if (retval >= 0)
3149     {
3150       print (vam->ofp, "%=20s", mp->locator_set_name);
3151     }
3152
3153   vam->retval = retval;
3154   vam->result_ready = 1;
3155 }
3156
3157 static void
3158   vl_api_one_get_map_request_itr_rlocs_reply_t_handler_json
3159   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
3160 {
3161   vat_main_t *vam = &vat_main;
3162   vat_json_node_t *node = NULL;
3163
3164   if (VAT_JSON_ARRAY != vam->json_tree.type)
3165     {
3166       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3167       vat_json_init_array (&vam->json_tree);
3168     }
3169   node = vat_json_array_add (&vam->json_tree);
3170
3171   vat_json_init_object (node);
3172   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
3173
3174   vat_json_print (vam->ofp, node);
3175   vat_json_free (node);
3176
3177   vam->retval = ntohl (mp->retval);
3178   vam->result_ready = 1;
3179 }
3180
3181 static u8 *
3182 format_lisp_map_request_mode (u8 * s, va_list * args)
3183 {
3184   u32 mode = va_arg (*args, u32);
3185
3186   switch (mode)
3187     {
3188     case 0:
3189       return format (0, "dst-only");
3190     case 1:
3191       return format (0, "src-dst");
3192     }
3193   return 0;
3194 }
3195
3196 static void
3197   vl_api_show_one_map_request_mode_reply_t_handler
3198   (vl_api_show_one_map_request_mode_reply_t * mp)
3199 {
3200   vat_main_t *vam = &vat_main;
3201   i32 retval = ntohl (mp->retval);
3202
3203   if (0 <= retval)
3204     {
3205       u32 mode = mp->mode;
3206       print (vam->ofp, "map_request_mode: %U",
3207              format_lisp_map_request_mode, mode);
3208     }
3209
3210   vam->retval = retval;
3211   vam->result_ready = 1;
3212 }
3213
3214 static void
3215   vl_api_show_one_map_request_mode_reply_t_handler_json
3216   (vl_api_show_one_map_request_mode_reply_t * mp)
3217 {
3218   vat_main_t *vam = &vat_main;
3219   vat_json_node_t node;
3220   u8 *s = 0;
3221   u32 mode;
3222
3223   mode = mp->mode;
3224   s = format (0, "%U", format_lisp_map_request_mode, mode);
3225   vec_add1 (s, 0);
3226
3227   vat_json_init_object (&node);
3228   vat_json_object_add_string_copy (&node, "map_request_mode", s);
3229   vat_json_print (vam->ofp, &node);
3230   vat_json_free (&node);
3231
3232   vec_free (s);
3233   vam->retval = ntohl (mp->retval);
3234   vam->result_ready = 1;
3235 }
3236
3237 static void
3238 vl_api_show_one_pitr_reply_t_handler (vl_api_show_one_pitr_reply_t * mp)
3239 {
3240   vat_main_t *vam = &vat_main;
3241   i32 retval = ntohl (mp->retval);
3242
3243   if (0 <= retval)
3244     {
3245       print (vam->ofp, "%-20s%-16s",
3246              mp->status ? "enabled" : "disabled",
3247              mp->status ? (char *) mp->locator_set_name : "");
3248     }
3249
3250   vam->retval = retval;
3251   vam->result_ready = 1;
3252 }
3253
3254 static void
3255 vl_api_show_one_pitr_reply_t_handler_json (vl_api_show_one_pitr_reply_t * mp)
3256 {
3257   vat_main_t *vam = &vat_main;
3258   vat_json_node_t node;
3259   u8 *status = 0;
3260
3261   status = format (0, "%s", mp->status ? "enabled" : "disabled");
3262   vec_add1 (status, 0);
3263
3264   vat_json_init_object (&node);
3265   vat_json_object_add_string_copy (&node, "status", status);
3266   if (mp->status)
3267     {
3268       vat_json_object_add_string_copy (&node, "locator_set",
3269                                        mp->locator_set_name);
3270     }
3271
3272   vec_free (status);
3273
3274   vat_json_print (vam->ofp, &node);
3275   vat_json_free (&node);
3276
3277   vam->retval = ntohl (mp->retval);
3278   vam->result_ready = 1;
3279 }
3280
3281 static u8 *
3282 format_policer_type (u8 * s, va_list * va)
3283 {
3284   u32 i = va_arg (*va, u32);
3285
3286   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
3287     s = format (s, "1r2c");
3288   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
3289     s = format (s, "1r3c");
3290   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
3291     s = format (s, "2r3c-2698");
3292   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
3293     s = format (s, "2r3c-4115");
3294   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
3295     s = format (s, "2r3c-mef5cf1");
3296   else
3297     s = format (s, "ILLEGAL");
3298   return s;
3299 }
3300
3301 static u8 *
3302 format_policer_rate_type (u8 * s, va_list * va)
3303 {
3304   u32 i = va_arg (*va, u32);
3305
3306   if (i == SSE2_QOS_RATE_KBPS)
3307     s = format (s, "kbps");
3308   else if (i == SSE2_QOS_RATE_PPS)
3309     s = format (s, "pps");
3310   else
3311     s = format (s, "ILLEGAL");
3312   return s;
3313 }
3314
3315 static u8 *
3316 format_policer_round_type (u8 * s, va_list * va)
3317 {
3318   u32 i = va_arg (*va, u32);
3319
3320   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
3321     s = format (s, "closest");
3322   else if (i == SSE2_QOS_ROUND_TO_UP)
3323     s = format (s, "up");
3324   else if (i == SSE2_QOS_ROUND_TO_DOWN)
3325     s = format (s, "down");
3326   else
3327     s = format (s, "ILLEGAL");
3328   return s;
3329 }
3330
3331 static u8 *
3332 format_policer_action_type (u8 * s, va_list * va)
3333 {
3334   u32 i = va_arg (*va, u32);
3335
3336   if (i == SSE2_QOS_ACTION_DROP)
3337     s = format (s, "drop");
3338   else if (i == SSE2_QOS_ACTION_TRANSMIT)
3339     s = format (s, "transmit");
3340   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3341     s = format (s, "mark-and-transmit");
3342   else
3343     s = format (s, "ILLEGAL");
3344   return s;
3345 }
3346
3347 static u8 *
3348 format_dscp (u8 * s, va_list * va)
3349 {
3350   u32 i = va_arg (*va, u32);
3351   char *t = 0;
3352
3353   switch (i)
3354     {
3355 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
3356       foreach_vnet_dscp
3357 #undef _
3358     default:
3359       return format (s, "ILLEGAL");
3360     }
3361   s = format (s, "%s", t);
3362   return s;
3363 }
3364
3365 static void
3366 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
3367 {
3368   vat_main_t *vam = &vat_main;
3369   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
3370
3371   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3372     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
3373   else
3374     conform_dscp_str = format (0, "");
3375
3376   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3377     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
3378   else
3379     exceed_dscp_str = format (0, "");
3380
3381   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3382     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
3383   else
3384     violate_dscp_str = format (0, "");
3385
3386   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
3387          "rate type %U, round type %U, %s rate, %s color-aware, "
3388          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
3389          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
3390          "conform action %U%s, exceed action %U%s, violate action %U%s",
3391          mp->name,
3392          format_policer_type, mp->type,
3393          ntohl (mp->cir),
3394          ntohl (mp->eir),
3395          clib_net_to_host_u64 (mp->cb),
3396          clib_net_to_host_u64 (mp->eb),
3397          format_policer_rate_type, mp->rate_type,
3398          format_policer_round_type, mp->round_type,
3399          mp->single_rate ? "single" : "dual",
3400          mp->color_aware ? "is" : "not",
3401          ntohl (mp->cir_tokens_per_period),
3402          ntohl (mp->pir_tokens_per_period),
3403          ntohl (mp->scale),
3404          ntohl (mp->current_limit),
3405          ntohl (mp->current_bucket),
3406          ntohl (mp->extended_limit),
3407          ntohl (mp->extended_bucket),
3408          clib_net_to_host_u64 (mp->last_update_time),
3409          format_policer_action_type, mp->conform_action_type,
3410          conform_dscp_str,
3411          format_policer_action_type, mp->exceed_action_type,
3412          exceed_dscp_str,
3413          format_policer_action_type, mp->violate_action_type,
3414          violate_dscp_str);
3415
3416   vec_free (conform_dscp_str);
3417   vec_free (exceed_dscp_str);
3418   vec_free (violate_dscp_str);
3419 }
3420
3421 static void vl_api_policer_details_t_handler_json
3422   (vl_api_policer_details_t * mp)
3423 {
3424   vat_main_t *vam = &vat_main;
3425   vat_json_node_t *node;
3426   u8 *rate_type_str, *round_type_str, *type_str;
3427   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
3428
3429   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
3430   round_type_str =
3431     format (0, "%U", format_policer_round_type, mp->round_type);
3432   type_str = format (0, "%U", format_policer_type, mp->type);
3433   conform_action_str = format (0, "%U", format_policer_action_type,
3434                                mp->conform_action_type);
3435   exceed_action_str = format (0, "%U", format_policer_action_type,
3436                               mp->exceed_action_type);
3437   violate_action_str = format (0, "%U", format_policer_action_type,
3438                                mp->violate_action_type);
3439
3440   if (VAT_JSON_ARRAY != vam->json_tree.type)
3441     {
3442       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3443       vat_json_init_array (&vam->json_tree);
3444     }
3445   node = vat_json_array_add (&vam->json_tree);
3446
3447   vat_json_init_object (node);
3448   vat_json_object_add_string_copy (node, "name", mp->name);
3449   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
3450   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
3451   vat_json_object_add_uint (node, "cb", ntohl (mp->cb));
3452   vat_json_object_add_uint (node, "eb", ntohl (mp->eb));
3453   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
3454   vat_json_object_add_string_copy (node, "round_type", round_type_str);
3455   vat_json_object_add_string_copy (node, "type", type_str);
3456   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
3457   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
3458   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
3459   vat_json_object_add_uint (node, "cir_tokens_per_period",
3460                             ntohl (mp->cir_tokens_per_period));
3461   vat_json_object_add_uint (node, "eir_tokens_per_period",
3462                             ntohl (mp->pir_tokens_per_period));
3463   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
3464   vat_json_object_add_uint (node, "current_bucket",
3465                             ntohl (mp->current_bucket));
3466   vat_json_object_add_uint (node, "extended_limit",
3467                             ntohl (mp->extended_limit));
3468   vat_json_object_add_uint (node, "extended_bucket",
3469                             ntohl (mp->extended_bucket));
3470   vat_json_object_add_uint (node, "last_update_time",
3471                             ntohl (mp->last_update_time));
3472   vat_json_object_add_string_copy (node, "conform_action",
3473                                    conform_action_str);
3474   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3475     {
3476       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
3477       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
3478       vec_free (dscp_str);
3479     }
3480   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
3481   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3482     {
3483       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
3484       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
3485       vec_free (dscp_str);
3486     }
3487   vat_json_object_add_string_copy (node, "violate_action",
3488                                    violate_action_str);
3489   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3490     {
3491       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
3492       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
3493       vec_free (dscp_str);
3494     }
3495
3496   vec_free (rate_type_str);
3497   vec_free (round_type_str);
3498   vec_free (type_str);
3499   vec_free (conform_action_str);
3500   vec_free (exceed_action_str);
3501   vec_free (violate_action_str);
3502 }
3503
3504 static void
3505 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
3506                                            mp)
3507 {
3508   vat_main_t *vam = &vat_main;
3509   int i, count = ntohl (mp->count);
3510
3511   if (count > 0)
3512     print (vam->ofp, "classify table ids (%d) : ", count);
3513   for (i = 0; i < count; i++)
3514     {
3515       print (vam->ofp, "%d", ntohl (mp->ids[i]));
3516       print (vam->ofp, (i < count - 1) ? "," : "");
3517     }
3518   vam->retval = ntohl (mp->retval);
3519   vam->result_ready = 1;
3520 }
3521
3522 static void
3523   vl_api_classify_table_ids_reply_t_handler_json
3524   (vl_api_classify_table_ids_reply_t * mp)
3525 {
3526   vat_main_t *vam = &vat_main;
3527   int i, count = ntohl (mp->count);
3528
3529   if (count > 0)
3530     {
3531       vat_json_node_t node;
3532
3533       vat_json_init_object (&node);
3534       for (i = 0; i < count; i++)
3535         {
3536           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
3537         }
3538       vat_json_print (vam->ofp, &node);
3539       vat_json_free (&node);
3540     }
3541   vam->retval = ntohl (mp->retval);
3542   vam->result_ready = 1;
3543 }
3544
3545 static void
3546   vl_api_classify_table_by_interface_reply_t_handler
3547   (vl_api_classify_table_by_interface_reply_t * mp)
3548 {
3549   vat_main_t *vam = &vat_main;
3550   u32 table_id;
3551
3552   table_id = ntohl (mp->l2_table_id);
3553   if (table_id != ~0)
3554     print (vam->ofp, "l2 table id : %d", table_id);
3555   else
3556     print (vam->ofp, "l2 table id : No input ACL tables configured");
3557   table_id = ntohl (mp->ip4_table_id);
3558   if (table_id != ~0)
3559     print (vam->ofp, "ip4 table id : %d", table_id);
3560   else
3561     print (vam->ofp, "ip4 table id : No input ACL tables configured");
3562   table_id = ntohl (mp->ip6_table_id);
3563   if (table_id != ~0)
3564     print (vam->ofp, "ip6 table id : %d", table_id);
3565   else
3566     print (vam->ofp, "ip6 table id : No input ACL tables configured");
3567   vam->retval = ntohl (mp->retval);
3568   vam->result_ready = 1;
3569 }
3570
3571 static void
3572   vl_api_classify_table_by_interface_reply_t_handler_json
3573   (vl_api_classify_table_by_interface_reply_t * mp)
3574 {
3575   vat_main_t *vam = &vat_main;
3576   vat_json_node_t node;
3577
3578   vat_json_init_object (&node);
3579
3580   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
3581   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
3582   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
3583
3584   vat_json_print (vam->ofp, &node);
3585   vat_json_free (&node);
3586
3587   vam->retval = ntohl (mp->retval);
3588   vam->result_ready = 1;
3589 }
3590
3591 static void vl_api_policer_add_del_reply_t_handler
3592   (vl_api_policer_add_del_reply_t * mp)
3593 {
3594   vat_main_t *vam = &vat_main;
3595   i32 retval = ntohl (mp->retval);
3596   if (vam->async_mode)
3597     {
3598       vam->async_errors += (retval < 0);
3599     }
3600   else
3601     {
3602       vam->retval = retval;
3603       vam->result_ready = 1;
3604       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
3605         /*
3606          * Note: this is just barely thread-safe, depends on
3607          * the main thread spinning waiting for an answer...
3608          */
3609         errmsg ("policer index %d", ntohl (mp->policer_index));
3610     }
3611 }
3612
3613 static void vl_api_policer_add_del_reply_t_handler_json
3614   (vl_api_policer_add_del_reply_t * mp)
3615 {
3616   vat_main_t *vam = &vat_main;
3617   vat_json_node_t node;
3618
3619   vat_json_init_object (&node);
3620   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3621   vat_json_object_add_uint (&node, "policer_index",
3622                             ntohl (mp->policer_index));
3623
3624   vat_json_print (vam->ofp, &node);
3625   vat_json_free (&node);
3626
3627   vam->retval = ntohl (mp->retval);
3628   vam->result_ready = 1;
3629 }
3630
3631 /* Format hex dump. */
3632 u8 *
3633 format_hex_bytes (u8 * s, va_list * va)
3634 {
3635   u8 *bytes = va_arg (*va, u8 *);
3636   int n_bytes = va_arg (*va, int);
3637   uword i;
3638
3639   /* Print short or long form depending on byte count. */
3640   uword short_form = n_bytes <= 32;
3641   uword indent = format_get_indent (s);
3642
3643   if (n_bytes == 0)
3644     return s;
3645
3646   for (i = 0; i < n_bytes; i++)
3647     {
3648       if (!short_form && (i % 32) == 0)
3649         s = format (s, "%08x: ", i);
3650       s = format (s, "%02x", bytes[i]);
3651       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
3652         s = format (s, "\n%U", format_white_space, indent);
3653     }
3654
3655   return s;
3656 }
3657
3658 static void
3659 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
3660                                             * mp)
3661 {
3662   vat_main_t *vam = &vat_main;
3663   i32 retval = ntohl (mp->retval);
3664   if (retval == 0)
3665     {
3666       print (vam->ofp, "classify table info :");
3667       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
3668              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
3669              ntohl (mp->miss_next_index));
3670       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
3671              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
3672              ntohl (mp->match_n_vectors));
3673       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
3674              ntohl (mp->mask_length));
3675     }
3676   vam->retval = retval;
3677   vam->result_ready = 1;
3678 }
3679
3680 static void
3681   vl_api_classify_table_info_reply_t_handler_json
3682   (vl_api_classify_table_info_reply_t * mp)
3683 {
3684   vat_main_t *vam = &vat_main;
3685   vat_json_node_t node;
3686
3687   i32 retval = ntohl (mp->retval);
3688   if (retval == 0)
3689     {
3690       vat_json_init_object (&node);
3691
3692       vat_json_object_add_int (&node, "sessions",
3693                                ntohl (mp->active_sessions));
3694       vat_json_object_add_int (&node, "nexttbl",
3695                                ntohl (mp->next_table_index));
3696       vat_json_object_add_int (&node, "nextnode",
3697                                ntohl (mp->miss_next_index));
3698       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
3699       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
3700       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
3701       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
3702                       ntohl (mp->mask_length), 0);
3703       vat_json_object_add_string_copy (&node, "mask", s);
3704
3705       vat_json_print (vam->ofp, &node);
3706       vat_json_free (&node);
3707     }
3708   vam->retval = ntohl (mp->retval);
3709   vam->result_ready = 1;
3710 }
3711
3712 static void
3713 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
3714                                            mp)
3715 {
3716   vat_main_t *vam = &vat_main;
3717
3718   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
3719          ntohl (mp->hit_next_index), ntohl (mp->advance),
3720          ntohl (mp->opaque_index));
3721   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
3722          ntohl (mp->match_length));
3723 }
3724
3725 static void
3726   vl_api_classify_session_details_t_handler_json
3727   (vl_api_classify_session_details_t * mp)
3728 {
3729   vat_main_t *vam = &vat_main;
3730   vat_json_node_t *node = NULL;
3731
3732   if (VAT_JSON_ARRAY != vam->json_tree.type)
3733     {
3734       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3735       vat_json_init_array (&vam->json_tree);
3736     }
3737   node = vat_json_array_add (&vam->json_tree);
3738
3739   vat_json_init_object (node);
3740   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
3741   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
3742   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
3743   u8 *s =
3744     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
3745             0);
3746   vat_json_object_add_string_copy (node, "match", s);
3747 }
3748
3749 static void vl_api_pg_create_interface_reply_t_handler
3750   (vl_api_pg_create_interface_reply_t * mp)
3751 {
3752   vat_main_t *vam = &vat_main;
3753
3754   vam->retval = ntohl (mp->retval);
3755   vam->result_ready = 1;
3756 }
3757
3758 static void vl_api_pg_create_interface_reply_t_handler_json
3759   (vl_api_pg_create_interface_reply_t * mp)
3760 {
3761   vat_main_t *vam = &vat_main;
3762   vat_json_node_t node;
3763
3764   i32 retval = ntohl (mp->retval);
3765   if (retval == 0)
3766     {
3767       vat_json_init_object (&node);
3768
3769       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
3770
3771       vat_json_print (vam->ofp, &node);
3772       vat_json_free (&node);
3773     }
3774   vam->retval = ntohl (mp->retval);
3775   vam->result_ready = 1;
3776 }
3777
3778 static void vl_api_policer_classify_details_t_handler
3779   (vl_api_policer_classify_details_t * mp)
3780 {
3781   vat_main_t *vam = &vat_main;
3782
3783   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
3784          ntohl (mp->table_index));
3785 }
3786
3787 static void vl_api_policer_classify_details_t_handler_json
3788   (vl_api_policer_classify_details_t * mp)
3789 {
3790   vat_main_t *vam = &vat_main;
3791   vat_json_node_t *node;
3792
3793   if (VAT_JSON_ARRAY != vam->json_tree.type)
3794     {
3795       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3796       vat_json_init_array (&vam->json_tree);
3797     }
3798   node = vat_json_array_add (&vam->json_tree);
3799
3800   vat_json_init_object (node);
3801   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
3802   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
3803 }
3804
3805 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler
3806   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
3807 {
3808   vat_main_t *vam = &vat_main;
3809   i32 retval = ntohl (mp->retval);
3810   if (vam->async_mode)
3811     {
3812       vam->async_errors += (retval < 0);
3813     }
3814   else
3815     {
3816       vam->retval = retval;
3817       vam->sw_if_index = ntohl (mp->sw_if_index);
3818       vam->result_ready = 1;
3819     }
3820 }
3821
3822 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler_json
3823   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
3824 {
3825   vat_main_t *vam = &vat_main;
3826   vat_json_node_t node;
3827
3828   vat_json_init_object (&node);
3829   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3830   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
3831
3832   vat_json_print (vam->ofp, &node);
3833   vat_json_free (&node);
3834
3835   vam->retval = ntohl (mp->retval);
3836   vam->result_ready = 1;
3837 }
3838
3839 static void vl_api_flow_classify_details_t_handler
3840   (vl_api_flow_classify_details_t * mp)
3841 {
3842   vat_main_t *vam = &vat_main;
3843
3844   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
3845          ntohl (mp->table_index));
3846 }
3847
3848 static void vl_api_flow_classify_details_t_handler_json
3849   (vl_api_flow_classify_details_t * mp)
3850 {
3851   vat_main_t *vam = &vat_main;
3852   vat_json_node_t *node;
3853
3854   if (VAT_JSON_ARRAY != vam->json_tree.type)
3855     {
3856       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3857       vat_json_init_array (&vam->json_tree);
3858     }
3859   node = vat_json_array_add (&vam->json_tree);
3860
3861   vat_json_init_object (node);
3862   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
3863   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
3864 }
3865
3866
3867
3868 #define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
3869 #define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler
3870 #define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler
3871 #define vl_api_vnet_ip6_fib_counters_t_print vl_noop_handler
3872 #define vl_api_vnet_ip4_nbr_counters_t_endian vl_noop_handler
3873 #define vl_api_vnet_ip4_nbr_counters_t_print vl_noop_handler
3874 #define vl_api_vnet_ip6_nbr_counters_t_endian vl_noop_handler
3875 #define vl_api_vnet_ip6_nbr_counters_t_print vl_noop_handler
3876 #define vl_api_one_adjacencies_get_reply_t_endian vl_noop_handler
3877 #define vl_api_one_adjacencies_get_reply_t_print vl_noop_handler
3878
3879 /*
3880  * Generate boilerplate reply handlers, which
3881  * dig the return value out of the xxx_reply_t API message,
3882  * stick it into vam->retval, and set vam->result_ready
3883  *
3884  * Could also do this by pointing N message decode slots at
3885  * a single function, but that could break in subtle ways.
3886  */
3887
3888 #define foreach_standard_reply_retval_handler           \
3889 _(sw_interface_set_flags_reply)                         \
3890 _(sw_interface_add_del_address_reply)                   \
3891 _(sw_interface_set_table_reply)                         \
3892 _(sw_interface_set_mpls_enable_reply)                   \
3893 _(sw_interface_set_vpath_reply)                         \
3894 _(sw_interface_set_vxlan_bypass_reply)                  \
3895 _(sw_interface_set_l2_bridge_reply)                     \
3896 _(bridge_domain_add_del_reply)                          \
3897 _(sw_interface_set_l2_xconnect_reply)                   \
3898 _(l2fib_add_del_reply)                                  \
3899 _(ip_add_del_route_reply)                               \
3900 _(ip_mroute_add_del_reply)                              \
3901 _(mpls_route_add_del_reply)                             \
3902 _(mpls_ip_bind_unbind_reply)                            \
3903 _(proxy_arp_add_del_reply)                              \
3904 _(proxy_arp_intfc_enable_disable_reply)                 \
3905 _(sw_interface_set_unnumbered_reply)                    \
3906 _(ip_neighbor_add_del_reply)                            \
3907 _(reset_vrf_reply)                                      \
3908 _(oam_add_del_reply)                                    \
3909 _(reset_fib_reply)                                      \
3910 _(dhcp_proxy_config_reply)                              \
3911 _(dhcp_proxy_set_vss_reply)                             \
3912 _(dhcp_client_config_reply)                             \
3913 _(set_ip_flow_hash_reply)                               \
3914 _(sw_interface_ip6_enable_disable_reply)                \
3915 _(sw_interface_ip6_set_link_local_address_reply)        \
3916 _(sw_interface_ip6nd_ra_prefix_reply)                   \
3917 _(sw_interface_ip6nd_ra_config_reply)                   \
3918 _(set_arp_neighbor_limit_reply)                         \
3919 _(l2_patch_add_del_reply)                               \
3920 _(sr_policy_add_reply)                                  \
3921 _(sr_policy_mod_reply)                                  \
3922 _(sr_policy_del_reply)                                  \
3923 _(sr_localsid_add_del_reply)                            \
3924 _(sr_steering_add_del_reply)                            \
3925 _(classify_add_del_session_reply)                       \
3926 _(classify_set_interface_ip_table_reply)                \
3927 _(classify_set_interface_l2_tables_reply)               \
3928 _(l2tpv3_set_tunnel_cookies_reply)                      \
3929 _(l2tpv3_interface_enable_disable_reply)                \
3930 _(l2tpv3_set_lookup_key_reply)                          \
3931 _(l2_fib_clear_table_reply)                             \
3932 _(l2_interface_efp_filter_reply)                        \
3933 _(l2_interface_vlan_tag_rewrite_reply)                  \
3934 _(modify_vhost_user_if_reply)                           \
3935 _(delete_vhost_user_if_reply)                           \
3936 _(want_ip4_arp_events_reply)                            \
3937 _(want_ip6_nd_events_reply)                             \
3938 _(input_acl_set_interface_reply)                        \
3939 _(ipsec_spd_add_del_reply)                              \
3940 _(ipsec_interface_add_del_spd_reply)                    \
3941 _(ipsec_spd_add_del_entry_reply)                        \
3942 _(ipsec_sad_add_del_entry_reply)                        \
3943 _(ipsec_sa_set_key_reply)                               \
3944 _(ikev2_profile_add_del_reply)                          \
3945 _(ikev2_profile_set_auth_reply)                         \
3946 _(ikev2_profile_set_id_reply)                           \
3947 _(ikev2_profile_set_ts_reply)                           \
3948 _(ikev2_set_local_key_reply)                            \
3949 _(ikev2_set_responder_reply)                            \
3950 _(ikev2_set_ike_transforms_reply)                       \
3951 _(ikev2_set_esp_transforms_reply)                       \
3952 _(ikev2_set_sa_lifetime_reply)                          \
3953 _(ikev2_initiate_sa_init_reply)                         \
3954 _(ikev2_initiate_del_ike_sa_reply)                      \
3955 _(ikev2_initiate_del_child_sa_reply)                    \
3956 _(ikev2_initiate_rekey_child_sa_reply)                  \
3957 _(delete_loopback_reply)                                \
3958 _(bd_ip_mac_add_del_reply)                              \
3959 _(map_del_domain_reply)                                 \
3960 _(map_add_del_rule_reply)                               \
3961 _(want_interface_events_reply)                          \
3962 _(want_stats_reply)                                     \
3963 _(cop_interface_enable_disable_reply)                   \
3964 _(cop_whitelist_enable_disable_reply)                   \
3965 _(sw_interface_clear_stats_reply)                       \
3966 _(ioam_enable_reply)                              \
3967 _(ioam_disable_reply)                              \
3968 _(one_add_del_locator_reply)                            \
3969 _(one_add_del_local_eid_reply)                          \
3970 _(one_add_del_remote_mapping_reply)                     \
3971 _(one_add_del_adjacency_reply)                          \
3972 _(one_add_del_map_resolver_reply)                       \
3973 _(one_add_del_map_server_reply)                         \
3974 _(one_enable_disable_reply)                             \
3975 _(one_rloc_probe_enable_disable_reply)                  \
3976 _(one_map_register_enable_disable_reply)                \
3977 _(one_pitr_set_locator_set_reply)                       \
3978 _(one_map_request_mode_reply)                           \
3979 _(one_add_del_map_request_itr_rlocs_reply)              \
3980 _(one_eid_table_add_del_map_reply)                      \
3981 _(gpe_add_del_fwd_entry_reply)                          \
3982 _(gpe_enable_disable_reply)                             \
3983 _(gpe_set_encap_mode_reply)                             \
3984 _(gpe_add_del_iface_reply)                              \
3985 _(vxlan_gpe_add_del_tunnel_reply)                       \
3986 _(af_packet_delete_reply)                               \
3987 _(policer_classify_set_interface_reply)                 \
3988 _(netmap_create_reply)                                  \
3989 _(netmap_delete_reply)                                  \
3990 _(set_ipfix_exporter_reply)                             \
3991 _(set_ipfix_classify_stream_reply)                      \
3992 _(ipfix_classify_table_add_del_reply)                   \
3993 _(flow_classify_set_interface_reply)                    \
3994 _(sw_interface_span_enable_disable_reply)               \
3995 _(pg_capture_reply)                                     \
3996 _(pg_enable_disable_reply)                              \
3997 _(ip_source_and_port_range_check_add_del_reply)         \
3998 _(ip_source_and_port_range_check_interface_add_del_reply)\
3999 _(delete_subif_reply)                                   \
4000 _(l2_interface_pbb_tag_rewrite_reply)                   \
4001 _(punt_reply)                                           \
4002 _(feature_enable_disable_reply)                         \
4003 _(sw_interface_tag_add_del_reply)                       \
4004 _(sw_interface_set_mtu_reply)
4005
4006 #define _(n)                                    \
4007     static void vl_api_##n##_t_handler          \
4008     (vl_api_##n##_t * mp)                       \
4009     {                                           \
4010         vat_main_t * vam = &vat_main;           \
4011         i32 retval = ntohl(mp->retval);         \
4012         if (vam->async_mode) {                  \
4013             vam->async_errors += (retval < 0);  \
4014         } else {                                \
4015             vam->retval = retval;               \
4016             vam->result_ready = 1;              \
4017         }                                       \
4018     }
4019 foreach_standard_reply_retval_handler;
4020 #undef _
4021
4022 #define _(n)                                    \
4023     static void vl_api_##n##_t_handler_json     \
4024     (vl_api_##n##_t * mp)                       \
4025     {                                           \
4026         vat_main_t * vam = &vat_main;           \
4027         vat_json_node_t node;                   \
4028         vat_json_init_object(&node);            \
4029         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
4030         vat_json_print(vam->ofp, &node);        \
4031         vam->retval = ntohl(mp->retval);        \
4032         vam->result_ready = 1;                  \
4033     }
4034 foreach_standard_reply_retval_handler;
4035 #undef _
4036
4037 /*
4038  * Table of message reply handlers, must include boilerplate handlers
4039  * we just generated
4040  */
4041
4042 #define foreach_vpe_api_reply_msg                                       \
4043 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
4044 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
4045 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
4046 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
4047 _(CONTROL_PING_REPLY, control_ping_reply)                               \
4048 _(CLI_REPLY, cli_reply)                                                 \
4049 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
4050 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
4051   sw_interface_add_del_address_reply)                                   \
4052 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
4053 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
4054 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
4055 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
4056 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
4057   sw_interface_set_l2_xconnect_reply)                                   \
4058 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
4059   sw_interface_set_l2_bridge_reply)                                     \
4060 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
4061 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
4062 _(BRIDGE_DOMAIN_SW_IF_DETAILS, bridge_domain_sw_if_details)             \
4063 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
4064 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
4065 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
4066 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
4067 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
4068 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
4069 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
4070 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
4071 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
4072 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
4073 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
4074 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
4075 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
4076   proxy_arp_intfc_enable_disable_reply)                                 \
4077 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
4078 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
4079   sw_interface_set_unnumbered_reply)                                    \
4080 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
4081 _(RESET_VRF_REPLY, reset_vrf_reply)                                     \
4082 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
4083 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
4084 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
4085 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
4086 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
4087 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
4088 _(DHCP_PROXY_DETAILS, dhcp_proxy_details)                               \
4089 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
4090 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
4091 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
4092   sw_interface_ip6_enable_disable_reply)                                \
4093 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY,                        \
4094   sw_interface_ip6_set_link_local_address_reply)                        \
4095 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
4096   sw_interface_ip6nd_ra_prefix_reply)                                   \
4097 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
4098   sw_interface_ip6nd_ra_config_reply)                                   \
4099 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
4100 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
4101 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
4102 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
4103 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
4104 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
4105 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
4106 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
4107 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
4108 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
4109 classify_set_interface_ip_table_reply)                                  \
4110 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
4111   classify_set_interface_l2_tables_reply)                               \
4112 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
4113 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
4114 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
4115 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
4116 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
4117   l2tpv3_interface_enable_disable_reply)                                \
4118 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
4119 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
4120 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
4121 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
4122 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
4123 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
4124 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
4125 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
4126 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
4127 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
4128 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
4129 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
4130 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
4131 _(SHOW_VERSION_REPLY, show_version_reply)                               \
4132 _(L2_FIB_TABLE_ENTRY, l2_fib_table_entry)                               \
4133 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)           \
4134 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
4135 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
4136 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
4137 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
4138 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
4139 _(IP6_ND_EVENT, ip6_nd_event)                                           \
4140 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
4141 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
4142 _(IP_DETAILS, ip_details)                                               \
4143 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
4144 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
4145 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
4146 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
4147 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
4148 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
4149 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
4150 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
4151 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
4152 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
4153 _(IKEV2_SET_RESPONDER_REPLY, ikev2_set_responder_reply)                 \
4154 _(IKEV2_SET_IKE_TRANSFORMS_REPLY, ikev2_set_ike_transforms_reply)       \
4155 _(IKEV2_SET_ESP_TRANSFORMS_REPLY, ikev2_set_esp_transforms_reply)       \
4156 _(IKEV2_SET_SA_LIFETIME_REPLY, ikev2_set_sa_lifetime_reply)             \
4157 _(IKEV2_INITIATE_SA_INIT_REPLY, ikev2_initiate_sa_init_reply)           \
4158 _(IKEV2_INITIATE_DEL_IKE_SA_REPLY, ikev2_initiate_del_ike_sa_reply)     \
4159 _(IKEV2_INITIATE_DEL_CHILD_SA_REPLY, ikev2_initiate_del_child_sa_reply) \
4160 _(IKEV2_INITIATE_REKEY_CHILD_SA_REPLY, ikev2_initiate_rekey_child_sa_reply) \
4161 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
4162 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
4163 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
4164 _(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply)                           \
4165 _(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply)                           \
4166 _(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply)                       \
4167 _(MAP_DOMAIN_DETAILS, map_domain_details)                               \
4168 _(MAP_RULE_DETAILS, map_rule_details)                                   \
4169 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
4170 _(WANT_STATS_REPLY, want_stats_reply)                                   \
4171 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
4172 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
4173 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
4174 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
4175 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
4176 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
4177 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
4178 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
4179 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
4180 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
4181 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
4182 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
4183 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
4184 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
4185 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
4186 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
4187   one_map_register_enable_disable_reply)                                \
4188 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
4189   one_rloc_probe_enable_disable_reply)                                  \
4190 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
4191 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
4192 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
4193 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
4194 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
4195 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
4196 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
4197 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
4198 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
4199 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
4200 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
4201 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
4202 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
4203 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
4204 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
4205 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
4206 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
4207 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
4208   gpe_fwd_entry_path_details)                                           \
4209 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
4210 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
4211   one_add_del_map_request_itr_rlocs_reply)                              \
4212 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
4213   one_get_map_request_itr_rlocs_reply)                                  \
4214 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
4215 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
4216 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
4217 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
4218   show_one_map_register_state_reply)                                    \
4219 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
4220 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
4221 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
4222 _(POLICER_DETAILS, policer_details)                                     \
4223 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
4224 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
4225 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
4226 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
4227 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
4228 _(MPLS_FIB_DETAILS, mpls_fib_details)                                   \
4229 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
4230 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
4231 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
4232 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
4233 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
4234 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
4235 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
4236 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
4237 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
4238 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
4239 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
4240 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
4241 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
4242 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
4243 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
4244 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
4245 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
4246 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
4247 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
4248  ip_source_and_port_range_check_add_del_reply)                          \
4249 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
4250  ip_source_and_port_range_check_interface_add_del_reply)                \
4251 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
4252 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
4253 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
4254 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
4255 _(PUNT_REPLY, punt_reply)                                               \
4256 _(IP_FIB_DETAILS, ip_fib_details)                                       \
4257 _(IP6_FIB_DETAILS, ip6_fib_details)                                     \
4258 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
4259 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
4260 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
4261 _(SW_INTERFACE_SET_MTU_REPLY, sw_interface_set_mtu_reply)               \
4262 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
4263 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)
4264
4265 #define foreach_standalone_reply_msg                                    \
4266 _(SW_INTERFACE_SET_FLAGS, sw_interface_set_flags)                       \
4267 _(VNET_INTERFACE_COUNTERS, vnet_interface_counters)                     \
4268 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
4269 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
4270 _(VNET_IP4_NBR_COUNTERS, vnet_ip4_nbr_counters)                         \
4271 _(VNET_IP6_NBR_COUNTERS, vnet_ip6_nbr_counters)
4272
4273 typedef struct
4274 {
4275   u8 *name;
4276   u32 value;
4277 } name_sort_t;
4278
4279
4280 #define STR_VTR_OP_CASE(op)     \
4281     case L2_VTR_ ## op:         \
4282         return "" # op;
4283
4284 static const char *
4285 str_vtr_op (u32 vtr_op)
4286 {
4287   switch (vtr_op)
4288     {
4289       STR_VTR_OP_CASE (DISABLED);
4290       STR_VTR_OP_CASE (PUSH_1);
4291       STR_VTR_OP_CASE (PUSH_2);
4292       STR_VTR_OP_CASE (POP_1);
4293       STR_VTR_OP_CASE (POP_2);
4294       STR_VTR_OP_CASE (TRANSLATE_1_1);
4295       STR_VTR_OP_CASE (TRANSLATE_1_2);
4296       STR_VTR_OP_CASE (TRANSLATE_2_1);
4297       STR_VTR_OP_CASE (TRANSLATE_2_2);
4298     }
4299
4300   return "UNKNOWN";
4301 }
4302
4303 static int
4304 dump_sub_interface_table (vat_main_t * vam)
4305 {
4306   const sw_interface_subif_t *sub = NULL;
4307
4308   if (vam->json_output)
4309     {
4310       clib_warning
4311         ("JSON output supported only for VPE API calls and dump_stats_table");
4312       return -99;
4313     }
4314
4315   print (vam->ofp,
4316          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
4317          "Interface", "sw_if_index",
4318          "sub id", "dot1ad", "tags", "outer id",
4319          "inner id", "exact", "default", "outer any", "inner any");
4320
4321   vec_foreach (sub, vam->sw_if_subif_table)
4322   {
4323     print (vam->ofp,
4324            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
4325            sub->interface_name,
4326            sub->sw_if_index,
4327            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
4328            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
4329            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
4330            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
4331     if (sub->vtr_op != L2_VTR_DISABLED)
4332       {
4333         print (vam->ofp,
4334                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
4335                "tag1: %d tag2: %d ]",
4336                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
4337                sub->vtr_tag1, sub->vtr_tag2);
4338       }
4339   }
4340
4341   return 0;
4342 }
4343
4344 static int
4345 name_sort_cmp (void *a1, void *a2)
4346 {
4347   name_sort_t *n1 = a1;
4348   name_sort_t *n2 = a2;
4349
4350   return strcmp ((char *) n1->name, (char *) n2->name);
4351 }
4352
4353 static int
4354 dump_interface_table (vat_main_t * vam)
4355 {
4356   hash_pair_t *p;
4357   name_sort_t *nses = 0, *ns;
4358
4359   if (vam->json_output)
4360     {
4361       clib_warning
4362         ("JSON output supported only for VPE API calls and dump_stats_table");
4363       return -99;
4364     }
4365
4366   /* *INDENT-OFF* */
4367   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
4368   ({
4369     vec_add2 (nses, ns, 1);
4370     ns->name = (u8 *)(p->key);
4371     ns->value = (u32) p->value[0];
4372   }));
4373   /* *INDENT-ON* */
4374
4375   vec_sort_with_function (nses, name_sort_cmp);
4376
4377   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
4378   vec_foreach (ns, nses)
4379   {
4380     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
4381   }
4382   vec_free (nses);
4383   return 0;
4384 }
4385
4386 static int
4387 dump_ip_table (vat_main_t * vam, int is_ipv6)
4388 {
4389   const ip_details_t *det = NULL;
4390   const ip_address_details_t *address = NULL;
4391   u32 i = ~0;
4392
4393   print (vam->ofp, "%-12s", "sw_if_index");
4394
4395   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
4396   {
4397     i++;
4398     if (!det->present)
4399       {
4400         continue;
4401       }
4402     print (vam->ofp, "%-12d", i);
4403     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
4404     if (!det->addr)
4405       {
4406         continue;
4407       }
4408     vec_foreach (address, det->addr)
4409     {
4410       print (vam->ofp,
4411              "            %-30U%-13d",
4412              is_ipv6 ? format_ip6_address : format_ip4_address,
4413              address->ip, address->prefix_length);
4414     }
4415   }
4416
4417   return 0;
4418 }
4419
4420 static int
4421 dump_ipv4_table (vat_main_t * vam)
4422 {
4423   if (vam->json_output)
4424     {
4425       clib_warning
4426         ("JSON output supported only for VPE API calls and dump_stats_table");
4427       return -99;
4428     }
4429
4430   return dump_ip_table (vam, 0);
4431 }
4432
4433 static int
4434 dump_ipv6_table (vat_main_t * vam)
4435 {
4436   if (vam->json_output)
4437     {
4438       clib_warning
4439         ("JSON output supported only for VPE API calls and dump_stats_table");
4440       return -99;
4441     }
4442
4443   return dump_ip_table (vam, 1);
4444 }
4445
4446 static char *
4447 counter_type_to_str (u8 counter_type, u8 is_combined)
4448 {
4449   if (!is_combined)
4450     {
4451       switch (counter_type)
4452         {
4453         case VNET_INTERFACE_COUNTER_DROP:
4454           return "drop";
4455         case VNET_INTERFACE_COUNTER_PUNT:
4456           return "punt";
4457         case VNET_INTERFACE_COUNTER_IP4:
4458           return "ip4";
4459         case VNET_INTERFACE_COUNTER_IP6:
4460           return "ip6";
4461         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
4462           return "rx-no-buf";
4463         case VNET_INTERFACE_COUNTER_RX_MISS:
4464           return "rx-miss";
4465         case VNET_INTERFACE_COUNTER_RX_ERROR:
4466           return "rx-error";
4467         case VNET_INTERFACE_COUNTER_TX_ERROR:
4468           return "tx-error";
4469         default:
4470           return "INVALID-COUNTER-TYPE";
4471         }
4472     }
4473   else
4474     {
4475       switch (counter_type)
4476         {
4477         case VNET_INTERFACE_COUNTER_RX:
4478           return "rx";
4479         case VNET_INTERFACE_COUNTER_TX:
4480           return "tx";
4481         default:
4482           return "INVALID-COUNTER-TYPE";
4483         }
4484     }
4485 }
4486
4487 static int
4488 dump_stats_table (vat_main_t * vam)
4489 {
4490   vat_json_node_t node;
4491   vat_json_node_t *msg_array;
4492   vat_json_node_t *msg;
4493   vat_json_node_t *counter_array;
4494   vat_json_node_t *counter;
4495   interface_counter_t c;
4496   u64 packets;
4497   ip4_fib_counter_t *c4;
4498   ip6_fib_counter_t *c6;
4499   ip4_nbr_counter_t *n4;
4500   ip6_nbr_counter_t *n6;
4501   int i, j;
4502
4503   if (!vam->json_output)
4504     {
4505       clib_warning ("dump_stats_table supported only in JSON format");
4506       return -99;
4507     }
4508
4509   vat_json_init_object (&node);
4510
4511   /* interface counters */
4512   msg_array = vat_json_object_add (&node, "interface_counters");
4513   vat_json_init_array (msg_array);
4514   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
4515     {
4516       msg = vat_json_array_add (msg_array);
4517       vat_json_init_object (msg);
4518       vat_json_object_add_string_copy (msg, "vnet_counter_type",
4519                                        (u8 *) counter_type_to_str (i, 0));
4520       vat_json_object_add_int (msg, "is_combined", 0);
4521       counter_array = vat_json_object_add (msg, "data");
4522       vat_json_init_array (counter_array);
4523       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
4524         {
4525           packets = vam->simple_interface_counters[i][j];
4526           vat_json_array_add_uint (counter_array, packets);
4527         }
4528     }
4529   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
4530     {
4531       msg = vat_json_array_add (msg_array);
4532       vat_json_init_object (msg);
4533       vat_json_object_add_string_copy (msg, "vnet_counter_type",
4534                                        (u8 *) counter_type_to_str (i, 1));
4535       vat_json_object_add_int (msg, "is_combined", 1);
4536       counter_array = vat_json_object_add (msg, "data");
4537       vat_json_init_array (counter_array);
4538       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
4539         {
4540           c = vam->combined_interface_counters[i][j];
4541           counter = vat_json_array_add (counter_array);
4542           vat_json_init_object (counter);
4543           vat_json_object_add_uint (counter, "packets", c.packets);
4544           vat_json_object_add_uint (counter, "bytes", c.bytes);
4545         }
4546     }
4547
4548   /* ip4 fib counters */
4549   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
4550   vat_json_init_array (msg_array);
4551   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
4552     {
4553       msg = vat_json_array_add (msg_array);
4554       vat_json_init_object (msg);
4555       vat_json_object_add_uint (msg, "vrf_id",
4556                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
4557       counter_array = vat_json_object_add (msg, "c");
4558       vat_json_init_array (counter_array);
4559       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
4560         {
4561           counter = vat_json_array_add (counter_array);
4562           vat_json_init_object (counter);
4563           c4 = &vam->ip4_fib_counters[i][j];
4564           vat_json_object_add_ip4 (counter, "address", c4->address);
4565           vat_json_object_add_uint (counter, "address_length",
4566                                     c4->address_length);
4567           vat_json_object_add_uint (counter, "packets", c4->packets);
4568           vat_json_object_add_uint (counter, "bytes", c4->bytes);
4569         }
4570     }
4571
4572   /* ip6 fib counters */
4573   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
4574   vat_json_init_array (msg_array);
4575   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
4576     {
4577       msg = vat_json_array_add (msg_array);
4578       vat_json_init_object (msg);
4579       vat_json_object_add_uint (msg, "vrf_id",
4580                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
4581       counter_array = vat_json_object_add (msg, "c");
4582       vat_json_init_array (counter_array);
4583       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
4584         {
4585           counter = vat_json_array_add (counter_array);
4586           vat_json_init_object (counter);
4587           c6 = &vam->ip6_fib_counters[i][j];
4588           vat_json_object_add_ip6 (counter, "address", c6->address);
4589           vat_json_object_add_uint (counter, "address_length",
4590                                     c6->address_length);
4591           vat_json_object_add_uint (counter, "packets", c6->packets);
4592           vat_json_object_add_uint (counter, "bytes", c6->bytes);
4593         }
4594     }
4595
4596   /* ip4 nbr counters */
4597   msg_array = vat_json_object_add (&node, "ip4_nbr_counters");
4598   vat_json_init_array (msg_array);
4599   for (i = 0; i < vec_len (vam->ip4_nbr_counters); i++)
4600     {
4601       msg = vat_json_array_add (msg_array);
4602       vat_json_init_object (msg);
4603       vat_json_object_add_uint (msg, "sw_if_index", i);
4604       counter_array = vat_json_object_add (msg, "c");
4605       vat_json_init_array (counter_array);
4606       for (j = 0; j < vec_len (vam->ip4_nbr_counters[i]); j++)
4607         {
4608           counter = vat_json_array_add (counter_array);
4609           vat_json_init_object (counter);
4610           n4 = &vam->ip4_nbr_counters[i][j];
4611           vat_json_object_add_ip4 (counter, "address", n4->address);
4612           vat_json_object_add_uint (counter, "link-type", n4->linkt);
4613           vat_json_object_add_uint (counter, "packets", n4->packets);
4614           vat_json_object_add_uint (counter, "bytes", n4->bytes);
4615         }
4616     }
4617
4618   /* ip6 nbr counters */
4619   msg_array = vat_json_object_add (&node, "ip6_nbr_counters");
4620   vat_json_init_array (msg_array);
4621   for (i = 0; i < vec_len (vam->ip6_nbr_counters); i++)
4622     {
4623       msg = vat_json_array_add (msg_array);
4624       vat_json_init_object (msg);
4625       vat_json_object_add_uint (msg, "sw_if_index", i);
4626       counter_array = vat_json_object_add (msg, "c");
4627       vat_json_init_array (counter_array);
4628       for (j = 0; j < vec_len (vam->ip6_nbr_counters[i]); j++)
4629         {
4630           counter = vat_json_array_add (counter_array);
4631           vat_json_init_object (counter);
4632           n6 = &vam->ip6_nbr_counters[i][j];
4633           vat_json_object_add_ip6 (counter, "address", n6->address);
4634           vat_json_object_add_uint (counter, "packets", n6->packets);
4635           vat_json_object_add_uint (counter, "bytes", n6->bytes);
4636         }
4637     }
4638
4639   vat_json_print (vam->ofp, &node);
4640   vat_json_free (&node);
4641
4642   return 0;
4643 }
4644
4645 int
4646 exec (vat_main_t * vam)
4647 {
4648   api_main_t *am = &api_main;
4649   vl_api_cli_request_t *mp;
4650   f64 timeout;
4651   void *oldheap;
4652   u8 *cmd = 0;
4653   unformat_input_t *i = vam->input;
4654
4655   if (vec_len (i->buffer) == 0)
4656     return -1;
4657
4658   if (vam->exec_mode == 0 && unformat (i, "mode"))
4659     {
4660       vam->exec_mode = 1;
4661       return 0;
4662     }
4663   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4664     {
4665       vam->exec_mode = 0;
4666       return 0;
4667     }
4668
4669
4670   M (CLI_REQUEST, mp);
4671
4672   /*
4673    * Copy cmd into shared memory.
4674    * In order for the CLI command to work, it
4675    * must be a vector ending in \n, not a C-string ending
4676    * in \n\0.
4677    */
4678   pthread_mutex_lock (&am->vlib_rp->mutex);
4679   oldheap = svm_push_data_heap (am->vlib_rp);
4680
4681   vec_validate (cmd, vec_len (vam->input->buffer) - 1);
4682   clib_memcpy (cmd, vam->input->buffer, vec_len (vam->input->buffer));
4683
4684   svm_pop_heap (oldheap);
4685   pthread_mutex_unlock (&am->vlib_rp->mutex);
4686
4687   mp->cmd_in_shmem = (u64) cmd;
4688   S (mp);
4689   timeout = vat_time_now (vam) + 10.0;
4690
4691   while (vat_time_now (vam) < timeout)
4692     {
4693       if (vam->result_ready == 1)
4694         {
4695           u8 *free_me;
4696           if (vam->shmem_result != NULL)
4697             print (vam->ofp, "%s", vam->shmem_result);
4698           pthread_mutex_lock (&am->vlib_rp->mutex);
4699           oldheap = svm_push_data_heap (am->vlib_rp);
4700
4701           free_me = (u8 *) vam->shmem_result;
4702           vec_free (free_me);
4703
4704           svm_pop_heap (oldheap);
4705           pthread_mutex_unlock (&am->vlib_rp->mutex);
4706           return 0;
4707         }
4708     }
4709   return -99;
4710 }
4711
4712 /*
4713  * Future replacement of exec() that passes CLI buffers directly in
4714  * the API messages instead of an additional shared memory area.
4715  */
4716 static int
4717 exec_inband (vat_main_t * vam)
4718 {
4719   vl_api_cli_inband_t *mp;
4720   unformat_input_t *i = vam->input;
4721   int ret;
4722
4723   if (vec_len (i->buffer) == 0)
4724     return -1;
4725
4726   if (vam->exec_mode == 0 && unformat (i, "mode"))
4727     {
4728       vam->exec_mode = 1;
4729       return 0;
4730     }
4731   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4732     {
4733       vam->exec_mode = 0;
4734       return 0;
4735     }
4736
4737   /*
4738    * In order for the CLI command to work, it
4739    * must be a vector ending in \n, not a C-string ending
4740    * in \n\0.
4741    */
4742   u32 len = vec_len (vam->input->buffer);
4743   M2 (CLI_INBAND, mp, len);
4744   clib_memcpy (mp->cmd, vam->input->buffer, len);
4745   mp->length = htonl (len);
4746
4747   S (mp);
4748   W2 (ret, print (vam->ofp, "%s", vam->cmd_reply));
4749   return ret;
4750 }
4751
4752 static int
4753 api_create_loopback (vat_main_t * vam)
4754 {
4755   unformat_input_t *i = vam->input;
4756   vl_api_create_loopback_t *mp;
4757   vl_api_create_loopback_instance_t *mp_lbi;
4758   u8 mac_address[6];
4759   u8 mac_set = 0;
4760   u8 is_specified = 0;
4761   u32 user_instance = 0;
4762   int ret;
4763
4764   memset (mac_address, 0, sizeof (mac_address));
4765
4766   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4767     {
4768       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
4769         mac_set = 1;
4770       if (unformat (i, "instance %d", &user_instance))
4771         is_specified = 1;
4772       else
4773         break;
4774     }
4775
4776   if (is_specified)
4777     {
4778       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
4779       mp_lbi->is_specified = is_specified;
4780       if (is_specified)
4781         mp_lbi->user_instance = htonl (user_instance);
4782       if (mac_set)
4783         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
4784       S (mp_lbi);
4785     }
4786   else
4787     {
4788       /* Construct the API message */
4789       M (CREATE_LOOPBACK, mp);
4790       if (mac_set)
4791         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
4792       S (mp);
4793     }
4794
4795   W (ret);
4796   return ret;
4797 }
4798
4799 static int
4800 api_delete_loopback (vat_main_t * vam)
4801 {
4802   unformat_input_t *i = vam->input;
4803   vl_api_delete_loopback_t *mp;
4804   u32 sw_if_index = ~0;
4805   int ret;
4806
4807   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4808     {
4809       if (unformat (i, "sw_if_index %d", &sw_if_index))
4810         ;
4811       else
4812         break;
4813     }
4814
4815   if (sw_if_index == ~0)
4816     {
4817       errmsg ("missing sw_if_index");
4818       return -99;
4819     }
4820
4821   /* Construct the API message */
4822   M (DELETE_LOOPBACK, mp);
4823   mp->sw_if_index = ntohl (sw_if_index);
4824
4825   S (mp);
4826   W (ret);
4827   return ret;
4828 }
4829
4830 static int
4831 api_want_stats (vat_main_t * vam)
4832 {
4833   unformat_input_t *i = vam->input;
4834   vl_api_want_stats_t *mp;
4835   int enable = -1;
4836   int ret;
4837
4838   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4839     {
4840       if (unformat (i, "enable"))
4841         enable = 1;
4842       else if (unformat (i, "disable"))
4843         enable = 0;
4844       else
4845         break;
4846     }
4847
4848   if (enable == -1)
4849     {
4850       errmsg ("missing enable|disable");
4851       return -99;
4852     }
4853
4854   M (WANT_STATS, mp);
4855   mp->enable_disable = enable;
4856
4857   S (mp);
4858   W (ret);
4859   return ret;
4860 }
4861
4862 static int
4863 api_want_interface_events (vat_main_t * vam)
4864 {
4865   unformat_input_t *i = vam->input;
4866   vl_api_want_interface_events_t *mp;
4867   int enable = -1;
4868   int ret;
4869
4870   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4871     {
4872       if (unformat (i, "enable"))
4873         enable = 1;
4874       else if (unformat (i, "disable"))
4875         enable = 0;
4876       else
4877         break;
4878     }
4879
4880   if (enable == -1)
4881     {
4882       errmsg ("missing enable|disable");
4883       return -99;
4884     }
4885
4886   M (WANT_INTERFACE_EVENTS, mp);
4887   mp->enable_disable = enable;
4888
4889   vam->interface_event_display = enable;
4890
4891   S (mp);
4892   W (ret);
4893   return ret;
4894 }
4895
4896
4897 /* Note: non-static, called once to set up the initial intfc table */
4898 int
4899 api_sw_interface_dump (vat_main_t * vam)
4900 {
4901   vl_api_sw_interface_dump_t *mp;
4902   vl_api_control_ping_t *mp_ping;
4903   hash_pair_t *p;
4904   name_sort_t *nses = 0, *ns;
4905   sw_interface_subif_t *sub = NULL;
4906   int ret;
4907
4908   /* Toss the old name table */
4909   /* *INDENT-OFF* */
4910   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
4911   ({
4912     vec_add2 (nses, ns, 1);
4913     ns->name = (u8 *)(p->key);
4914     ns->value = (u32) p->value[0];
4915   }));
4916   /* *INDENT-ON* */
4917
4918   hash_free (vam->sw_if_index_by_interface_name);
4919
4920   vec_foreach (ns, nses) vec_free (ns->name);
4921
4922   vec_free (nses);
4923
4924   vec_foreach (sub, vam->sw_if_subif_table)
4925   {
4926     vec_free (sub->interface_name);
4927   }
4928   vec_free (vam->sw_if_subif_table);
4929
4930   /* recreate the interface name hash table */
4931   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
4932
4933   /* Get list of ethernets */
4934   M (SW_INTERFACE_DUMP, mp);
4935   mp->name_filter_valid = 1;
4936   strncpy ((char *) mp->name_filter, "Ether", sizeof (mp->name_filter) - 1);
4937   S (mp);
4938
4939   /* and local / loopback interfaces */
4940   M (SW_INTERFACE_DUMP, mp);
4941   mp->name_filter_valid = 1;
4942   strncpy ((char *) mp->name_filter, "lo", sizeof (mp->name_filter) - 1);
4943   S (mp);
4944
4945   /* and packet-generator interfaces */
4946   M (SW_INTERFACE_DUMP, mp);
4947   mp->name_filter_valid = 1;
4948   strncpy ((char *) mp->name_filter, "pg", sizeof (mp->name_filter) - 1);
4949   S (mp);
4950
4951   /* and vxlan-gpe tunnel interfaces */
4952   M (SW_INTERFACE_DUMP, mp);
4953   mp->name_filter_valid = 1;
4954   strncpy ((char *) mp->name_filter, "vxlan_gpe",
4955            sizeof (mp->name_filter) - 1);
4956   S (mp);
4957
4958   /* and vxlan tunnel interfaces */
4959   M (SW_INTERFACE_DUMP, mp);
4960   mp->name_filter_valid = 1;
4961   strncpy ((char *) mp->name_filter, "vxlan", sizeof (mp->name_filter) - 1);
4962   S (mp);
4963
4964   /* and host (af_packet) interfaces */
4965   M (SW_INTERFACE_DUMP, mp);
4966   mp->name_filter_valid = 1;
4967   strncpy ((char *) mp->name_filter, "host", sizeof (mp->name_filter) - 1);
4968   S (mp);
4969
4970   /* and l2tpv3 tunnel interfaces */
4971   M (SW_INTERFACE_DUMP, mp);
4972   mp->name_filter_valid = 1;
4973   strncpy ((char *) mp->name_filter, "l2tpv3_tunnel",
4974            sizeof (mp->name_filter) - 1);
4975   S (mp);
4976
4977   /* and GRE tunnel interfaces */
4978   M (SW_INTERFACE_DUMP, mp);
4979   mp->name_filter_valid = 1;
4980   strncpy ((char *) mp->name_filter, "gre", sizeof (mp->name_filter) - 1);
4981   S (mp);
4982
4983   /* and LISP-GPE interfaces */
4984   M (SW_INTERFACE_DUMP, mp);
4985   mp->name_filter_valid = 1;
4986   strncpy ((char *) mp->name_filter, "lisp_gpe",
4987            sizeof (mp->name_filter) - 1);
4988   S (mp);
4989
4990   /* and IPSEC tunnel interfaces */
4991   M (SW_INTERFACE_DUMP, mp);
4992   mp->name_filter_valid = 1;
4993   strncpy ((char *) mp->name_filter, "ipsec", sizeof (mp->name_filter) - 1);
4994   S (mp);
4995
4996   /* Use a control ping for synchronization */
4997   M (CONTROL_PING, mp_ping);
4998   S (mp_ping);
4999
5000   W (ret);
5001   return ret;
5002 }
5003
5004 static int
5005 api_sw_interface_set_flags (vat_main_t * vam)
5006 {
5007   unformat_input_t *i = vam->input;
5008   vl_api_sw_interface_set_flags_t *mp;
5009   u32 sw_if_index;
5010   u8 sw_if_index_set = 0;
5011   u8 admin_up = 0, link_up = 0;
5012   int ret;
5013
5014   /* Parse args required to build the message */
5015   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5016     {
5017       if (unformat (i, "admin-up"))
5018         admin_up = 1;
5019       else if (unformat (i, "admin-down"))
5020         admin_up = 0;
5021       else if (unformat (i, "link-up"))
5022         link_up = 1;
5023       else if (unformat (i, "link-down"))
5024         link_up = 0;
5025       else
5026         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5027         sw_if_index_set = 1;
5028       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5029         sw_if_index_set = 1;
5030       else
5031         break;
5032     }
5033
5034   if (sw_if_index_set == 0)
5035     {
5036       errmsg ("missing interface name or sw_if_index");
5037       return -99;
5038     }
5039
5040   /* Construct the API message */
5041   M (SW_INTERFACE_SET_FLAGS, mp);
5042   mp->sw_if_index = ntohl (sw_if_index);
5043   mp->admin_up_down = admin_up;
5044   mp->link_up_down = link_up;
5045
5046   /* send it... */
5047   S (mp);
5048
5049   /* Wait for a reply, return the good/bad news... */
5050   W (ret);
5051   return ret;
5052 }
5053
5054 static int
5055 api_sw_interface_clear_stats (vat_main_t * vam)
5056 {
5057   unformat_input_t *i = vam->input;
5058   vl_api_sw_interface_clear_stats_t *mp;
5059   u32 sw_if_index;
5060   u8 sw_if_index_set = 0;
5061   int ret;
5062
5063   /* Parse args required to build the message */
5064   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5065     {
5066       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5067         sw_if_index_set = 1;
5068       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5069         sw_if_index_set = 1;
5070       else
5071         break;
5072     }
5073
5074   /* Construct the API message */
5075   M (SW_INTERFACE_CLEAR_STATS, mp);
5076
5077   if (sw_if_index_set == 1)
5078     mp->sw_if_index = ntohl (sw_if_index);
5079   else
5080     mp->sw_if_index = ~0;
5081
5082   /* send it... */
5083   S (mp);
5084
5085   /* Wait for a reply, return the good/bad news... */
5086   W (ret);
5087   return ret;
5088 }
5089
5090 static int
5091 api_sw_interface_add_del_address (vat_main_t * vam)
5092 {
5093   unformat_input_t *i = vam->input;
5094   vl_api_sw_interface_add_del_address_t *mp;
5095   u32 sw_if_index;
5096   u8 sw_if_index_set = 0;
5097   u8 is_add = 1, del_all = 0;
5098   u32 address_length = 0;
5099   u8 v4_address_set = 0;
5100   u8 v6_address_set = 0;
5101   ip4_address_t v4address;
5102   ip6_address_t v6address;
5103   int ret;
5104
5105   /* Parse args required to build the message */
5106   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5107     {
5108       if (unformat (i, "del-all"))
5109         del_all = 1;
5110       else if (unformat (i, "del"))
5111         is_add = 0;
5112       else
5113         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5114         sw_if_index_set = 1;
5115       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5116         sw_if_index_set = 1;
5117       else if (unformat (i, "%U/%d",
5118                          unformat_ip4_address, &v4address, &address_length))
5119         v4_address_set = 1;
5120       else if (unformat (i, "%U/%d",
5121                          unformat_ip6_address, &v6address, &address_length))
5122         v6_address_set = 1;
5123       else
5124         break;
5125     }
5126
5127   if (sw_if_index_set == 0)
5128     {
5129       errmsg ("missing interface name or sw_if_index");
5130       return -99;
5131     }
5132   if (v4_address_set && v6_address_set)
5133     {
5134       errmsg ("both v4 and v6 addresses set");
5135       return -99;
5136     }
5137   if (!v4_address_set && !v6_address_set && !del_all)
5138     {
5139       errmsg ("no addresses set");
5140       return -99;
5141     }
5142
5143   /* Construct the API message */
5144   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
5145
5146   mp->sw_if_index = ntohl (sw_if_index);
5147   mp->is_add = is_add;
5148   mp->del_all = del_all;
5149   if (v6_address_set)
5150     {
5151       mp->is_ipv6 = 1;
5152       clib_memcpy (mp->address, &v6address, sizeof (v6address));
5153     }
5154   else
5155     {
5156       clib_memcpy (mp->address, &v4address, sizeof (v4address));
5157     }
5158   mp->address_length = address_length;
5159
5160   /* send it... */
5161   S (mp);
5162
5163   /* Wait for a reply, return good/bad news  */
5164   W (ret);
5165   return ret;
5166 }
5167
5168 static int
5169 api_sw_interface_set_mpls_enable (vat_main_t * vam)
5170 {
5171   unformat_input_t *i = vam->input;
5172   vl_api_sw_interface_set_mpls_enable_t *mp;
5173   u32 sw_if_index;
5174   u8 sw_if_index_set = 0;
5175   u8 enable = 1;
5176   int ret;
5177
5178   /* Parse args required to build the message */
5179   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5180     {
5181       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5182         sw_if_index_set = 1;
5183       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5184         sw_if_index_set = 1;
5185       else if (unformat (i, "disable"))
5186         enable = 0;
5187       else if (unformat (i, "dis"))
5188         enable = 0;
5189       else
5190         break;
5191     }
5192
5193   if (sw_if_index_set == 0)
5194     {
5195       errmsg ("missing interface name or sw_if_index");
5196       return -99;
5197     }
5198
5199   /* Construct the API message */
5200   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
5201
5202   mp->sw_if_index = ntohl (sw_if_index);
5203   mp->enable = enable;
5204
5205   /* send it... */
5206   S (mp);
5207
5208   /* Wait for a reply... */
5209   W (ret);
5210   return ret;
5211 }
5212
5213 static int
5214 api_sw_interface_set_table (vat_main_t * vam)
5215 {
5216   unformat_input_t *i = vam->input;
5217   vl_api_sw_interface_set_table_t *mp;
5218   u32 sw_if_index, vrf_id = 0;
5219   u8 sw_if_index_set = 0;
5220   u8 is_ipv6 = 0;
5221   int ret;
5222
5223   /* Parse args required to build the message */
5224   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5225     {
5226       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5227         sw_if_index_set = 1;
5228       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5229         sw_if_index_set = 1;
5230       else if (unformat (i, "vrf %d", &vrf_id))
5231         ;
5232       else if (unformat (i, "ipv6"))
5233         is_ipv6 = 1;
5234       else
5235         break;
5236     }
5237
5238   if (sw_if_index_set == 0)
5239     {
5240       errmsg ("missing interface name or sw_if_index");
5241       return -99;
5242     }
5243
5244   /* Construct the API message */
5245   M (SW_INTERFACE_SET_TABLE, mp);
5246
5247   mp->sw_if_index = ntohl (sw_if_index);
5248   mp->is_ipv6 = is_ipv6;
5249   mp->vrf_id = ntohl (vrf_id);
5250
5251   /* send it... */
5252   S (mp);
5253
5254   /* Wait for a reply... */
5255   W (ret);
5256   return ret;
5257 }
5258
5259 static void vl_api_sw_interface_get_table_reply_t_handler
5260   (vl_api_sw_interface_get_table_reply_t * mp)
5261 {
5262   vat_main_t *vam = &vat_main;
5263
5264   print (vam->ofp, "%d", ntohl (mp->vrf_id));
5265
5266   vam->retval = ntohl (mp->retval);
5267   vam->result_ready = 1;
5268
5269 }
5270
5271 static void vl_api_sw_interface_get_table_reply_t_handler_json
5272   (vl_api_sw_interface_get_table_reply_t * mp)
5273 {
5274   vat_main_t *vam = &vat_main;
5275   vat_json_node_t node;
5276
5277   vat_json_init_object (&node);
5278   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
5279   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
5280
5281   vat_json_print (vam->ofp, &node);
5282   vat_json_free (&node);
5283
5284   vam->retval = ntohl (mp->retval);
5285   vam->result_ready = 1;
5286 }
5287
5288 static int
5289 api_sw_interface_get_table (vat_main_t * vam)
5290 {
5291   unformat_input_t *i = vam->input;
5292   vl_api_sw_interface_get_table_t *mp;
5293   u32 sw_if_index;
5294   u8 sw_if_index_set = 0;
5295   u8 is_ipv6 = 0;
5296   int ret;
5297
5298   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5299     {
5300       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5301         sw_if_index_set = 1;
5302       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5303         sw_if_index_set = 1;
5304       else if (unformat (i, "ipv6"))
5305         is_ipv6 = 1;
5306       else
5307         break;
5308     }
5309
5310   if (sw_if_index_set == 0)
5311     {
5312       errmsg ("missing interface name or sw_if_index");
5313       return -99;
5314     }
5315
5316   M (SW_INTERFACE_GET_TABLE, mp);
5317   mp->sw_if_index = htonl (sw_if_index);
5318   mp->is_ipv6 = is_ipv6;
5319
5320   S (mp);
5321   W (ret);
5322   return ret;
5323 }
5324
5325 static int
5326 api_sw_interface_set_vpath (vat_main_t * vam)
5327 {
5328   unformat_input_t *i = vam->input;
5329   vl_api_sw_interface_set_vpath_t *mp;
5330   u32 sw_if_index = 0;
5331   u8 sw_if_index_set = 0;
5332   u8 is_enable = 0;
5333   int ret;
5334
5335   /* Parse args required to build the message */
5336   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5337     {
5338       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5339         sw_if_index_set = 1;
5340       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5341         sw_if_index_set = 1;
5342       else if (unformat (i, "enable"))
5343         is_enable = 1;
5344       else if (unformat (i, "disable"))
5345         is_enable = 0;
5346       else
5347         break;
5348     }
5349
5350   if (sw_if_index_set == 0)
5351     {
5352       errmsg ("missing interface name or sw_if_index");
5353       return -99;
5354     }
5355
5356   /* Construct the API message */
5357   M (SW_INTERFACE_SET_VPATH, mp);
5358
5359   mp->sw_if_index = ntohl (sw_if_index);
5360   mp->enable = is_enable;
5361
5362   /* send it... */
5363   S (mp);
5364
5365   /* Wait for a reply... */
5366   W (ret);
5367   return ret;
5368 }
5369
5370 static int
5371 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
5372 {
5373   unformat_input_t *i = vam->input;
5374   vl_api_sw_interface_set_vxlan_bypass_t *mp;
5375   u32 sw_if_index = 0;
5376   u8 sw_if_index_set = 0;
5377   u8 is_enable = 1;
5378   u8 is_ipv6 = 0;
5379   int ret;
5380
5381   /* Parse args required to build the message */
5382   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5383     {
5384       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5385         sw_if_index_set = 1;
5386       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5387         sw_if_index_set = 1;
5388       else if (unformat (i, "enable"))
5389         is_enable = 1;
5390       else if (unformat (i, "disable"))
5391         is_enable = 0;
5392       else if (unformat (i, "ip4"))
5393         is_ipv6 = 0;
5394       else if (unformat (i, "ip6"))
5395         is_ipv6 = 1;
5396       else
5397         break;
5398     }
5399
5400   if (sw_if_index_set == 0)
5401     {
5402       errmsg ("missing interface name or sw_if_index");
5403       return -99;
5404     }
5405
5406   /* Construct the API message */
5407   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
5408
5409   mp->sw_if_index = ntohl (sw_if_index);
5410   mp->enable = is_enable;
5411   mp->is_ipv6 = is_ipv6;
5412
5413   /* send it... */
5414   S (mp);
5415
5416   /* Wait for a reply... */
5417   W (ret);
5418   return ret;
5419 }
5420
5421 static int
5422 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
5423 {
5424   unformat_input_t *i = vam->input;
5425   vl_api_sw_interface_set_l2_xconnect_t *mp;
5426   u32 rx_sw_if_index;
5427   u8 rx_sw_if_index_set = 0;
5428   u32 tx_sw_if_index;
5429   u8 tx_sw_if_index_set = 0;
5430   u8 enable = 1;
5431   int ret;
5432
5433   /* Parse args required to build the message */
5434   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5435     {
5436       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
5437         rx_sw_if_index_set = 1;
5438       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
5439         tx_sw_if_index_set = 1;
5440       else if (unformat (i, "rx"))
5441         {
5442           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5443             {
5444               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
5445                             &rx_sw_if_index))
5446                 rx_sw_if_index_set = 1;
5447             }
5448           else
5449             break;
5450         }
5451       else if (unformat (i, "tx"))
5452         {
5453           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5454             {
5455               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
5456                             &tx_sw_if_index))
5457                 tx_sw_if_index_set = 1;
5458             }
5459           else
5460             break;
5461         }
5462       else if (unformat (i, "enable"))
5463         enable = 1;
5464       else if (unformat (i, "disable"))
5465         enable = 0;
5466       else
5467         break;
5468     }
5469
5470   if (rx_sw_if_index_set == 0)
5471     {
5472       errmsg ("missing rx interface name or rx_sw_if_index");
5473       return -99;
5474     }
5475
5476   if (enable && (tx_sw_if_index_set == 0))
5477     {
5478       errmsg ("missing tx interface name or tx_sw_if_index");
5479       return -99;
5480     }
5481
5482   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
5483
5484   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
5485   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
5486   mp->enable = enable;
5487
5488   S (mp);
5489   W (ret);
5490   return ret;
5491 }
5492
5493 static int
5494 api_sw_interface_set_l2_bridge (vat_main_t * vam)
5495 {
5496   unformat_input_t *i = vam->input;
5497   vl_api_sw_interface_set_l2_bridge_t *mp;
5498   u32 rx_sw_if_index;
5499   u8 rx_sw_if_index_set = 0;
5500   u32 bd_id;
5501   u8 bd_id_set = 0;
5502   u8 bvi = 0;
5503   u32 shg = 0;
5504   u8 enable = 1;
5505   int ret;
5506
5507   /* Parse args required to build the message */
5508   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5509     {
5510       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
5511         rx_sw_if_index_set = 1;
5512       else if (unformat (i, "bd_id %d", &bd_id))
5513         bd_id_set = 1;
5514       else
5515         if (unformat
5516             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
5517         rx_sw_if_index_set = 1;
5518       else if (unformat (i, "shg %d", &shg))
5519         ;
5520       else if (unformat (i, "bvi"))
5521         bvi = 1;
5522       else if (unformat (i, "enable"))
5523         enable = 1;
5524       else if (unformat (i, "disable"))
5525         enable = 0;
5526       else
5527         break;
5528     }
5529
5530   if (rx_sw_if_index_set == 0)
5531     {
5532       errmsg ("missing rx interface name or sw_if_index");
5533       return -99;
5534     }
5535
5536   if (enable && (bd_id_set == 0))
5537     {
5538       errmsg ("missing bridge domain");
5539       return -99;
5540     }
5541
5542   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
5543
5544   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
5545   mp->bd_id = ntohl (bd_id);
5546   mp->shg = (u8) shg;
5547   mp->bvi = bvi;
5548   mp->enable = enable;
5549
5550   S (mp);
5551   W (ret);
5552   return ret;
5553 }
5554
5555 static int
5556 api_bridge_domain_dump (vat_main_t * vam)
5557 {
5558   unformat_input_t *i = vam->input;
5559   vl_api_bridge_domain_dump_t *mp;
5560   vl_api_control_ping_t *mp_ping;
5561   u32 bd_id = ~0;
5562   int ret;
5563
5564   /* Parse args required to build the message */
5565   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5566     {
5567       if (unformat (i, "bd_id %d", &bd_id))
5568         ;
5569       else
5570         break;
5571     }
5572
5573   M (BRIDGE_DOMAIN_DUMP, mp);
5574   mp->bd_id = ntohl (bd_id);
5575   S (mp);
5576
5577   /* Use a control ping for synchronization */
5578   M (CONTROL_PING, mp_ping);
5579   S (mp_ping);
5580
5581   W (ret);
5582   return ret;
5583 }
5584
5585 static int
5586 api_bridge_domain_add_del (vat_main_t * vam)
5587 {
5588   unformat_input_t *i = vam->input;
5589   vl_api_bridge_domain_add_del_t *mp;
5590   u32 bd_id = ~0;
5591   u8 is_add = 1;
5592   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
5593   u32 mac_age = 0;
5594   int ret;
5595
5596   /* Parse args required to build the message */
5597   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5598     {
5599       if (unformat (i, "bd_id %d", &bd_id))
5600         ;
5601       else if (unformat (i, "flood %d", &flood))
5602         ;
5603       else if (unformat (i, "uu-flood %d", &uu_flood))
5604         ;
5605       else if (unformat (i, "forward %d", &forward))
5606         ;
5607       else if (unformat (i, "learn %d", &learn))
5608         ;
5609       else if (unformat (i, "arp-term %d", &arp_term))
5610         ;
5611       else if (unformat (i, "mac-age %d", &mac_age))
5612         ;
5613       else if (unformat (i, "del"))
5614         {
5615           is_add = 0;
5616           flood = uu_flood = forward = learn = 0;
5617         }
5618       else
5619         break;
5620     }
5621
5622   if (bd_id == ~0)
5623     {
5624       errmsg ("missing bridge domain");
5625       return -99;
5626     }
5627
5628   if (mac_age > 255)
5629     {
5630       errmsg ("mac age must be less than 256 ");
5631       return -99;
5632     }
5633
5634   M (BRIDGE_DOMAIN_ADD_DEL, mp);
5635
5636   mp->bd_id = ntohl (bd_id);
5637   mp->flood = flood;
5638   mp->uu_flood = uu_flood;
5639   mp->forward = forward;
5640   mp->learn = learn;
5641   mp->arp_term = arp_term;
5642   mp->is_add = is_add;
5643   mp->mac_age = (u8) mac_age;
5644
5645   S (mp);
5646   W (ret);
5647   return ret;
5648 }
5649
5650 static int
5651 api_l2fib_add_del (vat_main_t * vam)
5652 {
5653   unformat_input_t *i = vam->input;
5654   vl_api_l2fib_add_del_t *mp;
5655   f64 timeout;
5656   u64 mac = 0;
5657   u8 mac_set = 0;
5658   u32 bd_id;
5659   u8 bd_id_set = 0;
5660   u32 sw_if_index = ~0;
5661   u8 sw_if_index_set = 0;
5662   u8 is_add = 1;
5663   u8 static_mac = 0;
5664   u8 filter_mac = 0;
5665   u8 bvi_mac = 0;
5666   int count = 1;
5667   f64 before = 0;
5668   int j;
5669
5670   /* Parse args required to build the message */
5671   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5672     {
5673       if (unformat (i, "mac %U", unformat_ethernet_address, &mac))
5674         mac_set = 1;
5675       else if (unformat (i, "bd_id %d", &bd_id))
5676         bd_id_set = 1;
5677       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5678         sw_if_index_set = 1;
5679       else if (unformat (i, "sw_if"))
5680         {
5681           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5682             {
5683               if (unformat
5684                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5685                 sw_if_index_set = 1;
5686             }
5687           else
5688             break;
5689         }
5690       else if (unformat (i, "static"))
5691         static_mac = 1;
5692       else if (unformat (i, "filter"))
5693         {
5694           filter_mac = 1;
5695           static_mac = 1;
5696         }
5697       else if (unformat (i, "bvi"))
5698         {
5699           bvi_mac = 1;
5700           static_mac = 1;
5701         }
5702       else if (unformat (i, "del"))
5703         is_add = 0;
5704       else if (unformat (i, "count %d", &count))
5705         ;
5706       else
5707         break;
5708     }
5709
5710   if (mac_set == 0)
5711     {
5712       errmsg ("missing mac address");
5713       return -99;
5714     }
5715
5716   if (bd_id_set == 0)
5717     {
5718       errmsg ("missing bridge domain");
5719       return -99;
5720     }
5721
5722   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
5723     {
5724       errmsg ("missing interface name or sw_if_index");
5725       return -99;
5726     }
5727
5728   if (count > 1)
5729     {
5730       /* Turn on async mode */
5731       vam->async_mode = 1;
5732       vam->async_errors = 0;
5733       before = vat_time_now (vam);
5734     }
5735
5736   for (j = 0; j < count; j++)
5737     {
5738       M (L2FIB_ADD_DEL, mp);
5739
5740       mp->mac = mac;
5741       mp->bd_id = ntohl (bd_id);
5742       mp->is_add = is_add;
5743
5744       if (is_add)
5745         {
5746           mp->sw_if_index = ntohl (sw_if_index);
5747           mp->static_mac = static_mac;
5748           mp->filter_mac = filter_mac;
5749           mp->bvi_mac = bvi_mac;
5750         }
5751       increment_mac_address (&mac);
5752       /* send it... */
5753       S (mp);
5754     }
5755
5756   if (count > 1)
5757     {
5758       vl_api_control_ping_t *mp_ping;
5759       f64 after;
5760
5761       /* Shut off async mode */
5762       vam->async_mode = 0;
5763
5764       M (CONTROL_PING, mp_ping);
5765       S (mp_ping);
5766
5767       timeout = vat_time_now (vam) + 1.0;
5768       while (vat_time_now (vam) < timeout)
5769         if (vam->result_ready == 1)
5770           goto out;
5771       vam->retval = -99;
5772
5773     out:
5774       if (vam->retval == -99)
5775         errmsg ("timeout");
5776
5777       if (vam->async_errors > 0)
5778         {
5779           errmsg ("%d asynchronous errors", vam->async_errors);
5780           vam->retval = -98;
5781         }
5782       vam->async_errors = 0;
5783       after = vat_time_now (vam);
5784
5785       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
5786              count, after - before, count / (after - before));
5787     }
5788   else
5789     {
5790       int ret;
5791
5792       /* Wait for a reply... */
5793       W (ret);
5794       return ret;
5795     }
5796   /* Return the good/bad news */
5797   return (vam->retval);
5798 }
5799
5800 static int
5801 api_l2_flags (vat_main_t * vam)
5802 {
5803   unformat_input_t *i = vam->input;
5804   vl_api_l2_flags_t *mp;
5805   u32 sw_if_index;
5806   u32 feature_bitmap = 0;
5807   u8 sw_if_index_set = 0;
5808   int ret;
5809
5810   /* Parse args required to build the message */
5811   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5812     {
5813       if (unformat (i, "sw_if_index %d", &sw_if_index))
5814         sw_if_index_set = 1;
5815       else if (unformat (i, "sw_if"))
5816         {
5817           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5818             {
5819               if (unformat
5820                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5821                 sw_if_index_set = 1;
5822             }
5823           else
5824             break;
5825         }
5826       else if (unformat (i, "learn"))
5827         feature_bitmap |= L2INPUT_FEAT_LEARN;
5828       else if (unformat (i, "forward"))
5829         feature_bitmap |= L2INPUT_FEAT_FWD;
5830       else if (unformat (i, "flood"))
5831         feature_bitmap |= L2INPUT_FEAT_FLOOD;
5832       else if (unformat (i, "uu-flood"))
5833         feature_bitmap |= L2INPUT_FEAT_UU_FLOOD;
5834       else
5835         break;
5836     }
5837
5838   if (sw_if_index_set == 0)
5839     {
5840       errmsg ("missing interface name or sw_if_index");
5841       return -99;
5842     }
5843
5844   M (L2_FLAGS, mp);
5845
5846   mp->sw_if_index = ntohl (sw_if_index);
5847   mp->feature_bitmap = ntohl (feature_bitmap);
5848
5849   S (mp);
5850   W (ret);
5851   return ret;
5852 }
5853
5854 static int
5855 api_bridge_flags (vat_main_t * vam)
5856 {
5857   unformat_input_t *i = vam->input;
5858   vl_api_bridge_flags_t *mp;
5859   u32 bd_id;
5860   u8 bd_id_set = 0;
5861   u8 is_set = 1;
5862   u32 flags = 0;
5863   int ret;
5864
5865   /* Parse args required to build the message */
5866   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5867     {
5868       if (unformat (i, "bd_id %d", &bd_id))
5869         bd_id_set = 1;
5870       else if (unformat (i, "learn"))
5871         flags |= L2_LEARN;
5872       else if (unformat (i, "forward"))
5873         flags |= L2_FWD;
5874       else if (unformat (i, "flood"))
5875         flags |= L2_FLOOD;
5876       else if (unformat (i, "uu-flood"))
5877         flags |= L2_UU_FLOOD;
5878       else if (unformat (i, "arp-term"))
5879         flags |= L2_ARP_TERM;
5880       else if (unformat (i, "off"))
5881         is_set = 0;
5882       else if (unformat (i, "disable"))
5883         is_set = 0;
5884       else
5885         break;
5886     }
5887
5888   if (bd_id_set == 0)
5889     {
5890       errmsg ("missing bridge domain");
5891       return -99;
5892     }
5893
5894   M (BRIDGE_FLAGS, mp);
5895
5896   mp->bd_id = ntohl (bd_id);
5897   mp->feature_bitmap = ntohl (flags);
5898   mp->is_set = is_set;
5899
5900   S (mp);
5901   W (ret);
5902   return ret;
5903 }
5904
5905 static int
5906 api_bd_ip_mac_add_del (vat_main_t * vam)
5907 {
5908   unformat_input_t *i = vam->input;
5909   vl_api_bd_ip_mac_add_del_t *mp;
5910   u32 bd_id;
5911   u8 is_ipv6 = 0;
5912   u8 is_add = 1;
5913   u8 bd_id_set = 0;
5914   u8 ip_set = 0;
5915   u8 mac_set = 0;
5916   ip4_address_t v4addr;
5917   ip6_address_t v6addr;
5918   u8 macaddr[6];
5919   int ret;
5920
5921
5922   /* Parse args required to build the message */
5923   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5924     {
5925       if (unformat (i, "bd_id %d", &bd_id))
5926         {
5927           bd_id_set++;
5928         }
5929       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
5930         {
5931           ip_set++;
5932         }
5933       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
5934         {
5935           ip_set++;
5936           is_ipv6++;
5937         }
5938       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
5939         {
5940           mac_set++;
5941         }
5942       else if (unformat (i, "del"))
5943         is_add = 0;
5944       else
5945         break;
5946     }
5947
5948   if (bd_id_set == 0)
5949     {
5950       errmsg ("missing bridge domain");
5951       return -99;
5952     }
5953   else if (ip_set == 0)
5954     {
5955       errmsg ("missing IP address");
5956       return -99;
5957     }
5958   else if (mac_set == 0)
5959     {
5960       errmsg ("missing MAC address");
5961       return -99;
5962     }
5963
5964   M (BD_IP_MAC_ADD_DEL, mp);
5965
5966   mp->bd_id = ntohl (bd_id);
5967   mp->is_ipv6 = is_ipv6;
5968   mp->is_add = is_add;
5969   if (is_ipv6)
5970     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
5971   else
5972     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
5973   clib_memcpy (mp->mac_address, macaddr, 6);
5974   S (mp);
5975   W (ret);
5976   return ret;
5977 }
5978
5979 static int
5980 api_tap_connect (vat_main_t * vam)
5981 {
5982   unformat_input_t *i = vam->input;
5983   vl_api_tap_connect_t *mp;
5984   u8 mac_address[6];
5985   u8 random_mac = 1;
5986   u8 name_set = 0;
5987   u8 *tap_name;
5988   u8 *tag = 0;
5989   ip4_address_t ip4_address;
5990   u32 ip4_mask_width;
5991   int ip4_address_set = 0;
5992   ip6_address_t ip6_address;
5993   u32 ip6_mask_width;
5994   int ip6_address_set = 0;
5995   int ret;
5996
5997   memset (mac_address, 0, sizeof (mac_address));
5998
5999   /* Parse args required to build the message */
6000   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6001     {
6002       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6003         {
6004           random_mac = 0;
6005         }
6006       else if (unformat (i, "random-mac"))
6007         random_mac = 1;
6008       else if (unformat (i, "tapname %s", &tap_name))
6009         name_set = 1;
6010       else if (unformat (i, "tag %s", &tag))
6011         ;
6012       else if (unformat (i, "address %U/%d",
6013                          unformat_ip4_address, &ip4_address, &ip4_mask_width))
6014         ip4_address_set = 1;
6015       else if (unformat (i, "address %U/%d",
6016                          unformat_ip6_address, &ip6_address, &ip6_mask_width))
6017         ip6_address_set = 1;
6018       else
6019         break;
6020     }
6021
6022   if (name_set == 0)
6023     {
6024       errmsg ("missing tap name");
6025       return -99;
6026     }
6027   if (vec_len (tap_name) > 63)
6028     {
6029       errmsg ("tap name too long");
6030       return -99;
6031     }
6032   vec_add1 (tap_name, 0);
6033
6034   if (vec_len (tag) > 63)
6035     {
6036       errmsg ("tag too long");
6037       return -99;
6038     }
6039
6040   /* Construct the API message */
6041   M (TAP_CONNECT, mp);
6042
6043   mp->use_random_mac = random_mac;
6044   clib_memcpy (mp->mac_address, mac_address, 6);
6045   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
6046   if (tag)
6047     clib_memcpy (mp->tag, tag, vec_len (tag));
6048
6049   if (ip4_address_set)
6050     {
6051       mp->ip4_address_set = 1;
6052       clib_memcpy (mp->ip4_address, &ip4_address, sizeof (mp->ip4_address));
6053       mp->ip4_mask_width = ip4_mask_width;
6054     }
6055   if (ip6_address_set)
6056     {
6057       mp->ip6_address_set = 1;
6058       clib_memcpy (mp->ip6_address, &ip6_address, sizeof (mp->ip6_address));
6059       mp->ip6_mask_width = ip6_mask_width;
6060     }
6061
6062   vec_free (tap_name);
6063   vec_free (tag);
6064
6065   /* send it... */
6066   S (mp);
6067
6068   /* Wait for a reply... */
6069   W (ret);
6070   return ret;
6071 }
6072
6073 static int
6074 api_tap_modify (vat_main_t * vam)
6075 {
6076   unformat_input_t *i = vam->input;
6077   vl_api_tap_modify_t *mp;
6078   u8 mac_address[6];
6079   u8 random_mac = 1;
6080   u8 name_set = 0;
6081   u8 *tap_name;
6082   u32 sw_if_index = ~0;
6083   u8 sw_if_index_set = 0;
6084   int ret;
6085
6086   memset (mac_address, 0, sizeof (mac_address));
6087
6088   /* Parse args required to build the message */
6089   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6090     {
6091       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6092         sw_if_index_set = 1;
6093       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6094         sw_if_index_set = 1;
6095       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6096         {
6097           random_mac = 0;
6098         }
6099       else if (unformat (i, "random-mac"))
6100         random_mac = 1;
6101       else if (unformat (i, "tapname %s", &tap_name))
6102         name_set = 1;
6103       else
6104         break;
6105     }
6106
6107   if (sw_if_index_set == 0)
6108     {
6109       errmsg ("missing vpp interface name");
6110       return -99;
6111     }
6112   if (name_set == 0)
6113     {
6114       errmsg ("missing tap name");
6115       return -99;
6116     }
6117   if (vec_len (tap_name) > 63)
6118     {
6119       errmsg ("tap name too long");
6120     }
6121   vec_add1 (tap_name, 0);
6122
6123   /* Construct the API message */
6124   M (TAP_MODIFY, mp);
6125
6126   mp->use_random_mac = random_mac;
6127   mp->sw_if_index = ntohl (sw_if_index);
6128   clib_memcpy (mp->mac_address, mac_address, 6);
6129   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
6130   vec_free (tap_name);
6131
6132   /* send it... */
6133   S (mp);
6134
6135   /* Wait for a reply... */
6136   W (ret);
6137   return ret;
6138 }
6139
6140 static int
6141 api_tap_delete (vat_main_t * vam)
6142 {
6143   unformat_input_t *i = vam->input;
6144   vl_api_tap_delete_t *mp;
6145   u32 sw_if_index = ~0;
6146   u8 sw_if_index_set = 0;
6147   int ret;
6148
6149   /* Parse args required to build the message */
6150   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6151     {
6152       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6153         sw_if_index_set = 1;
6154       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6155         sw_if_index_set = 1;
6156       else
6157         break;
6158     }
6159
6160   if (sw_if_index_set == 0)
6161     {
6162       errmsg ("missing vpp interface name");
6163       return -99;
6164     }
6165
6166   /* Construct the API message */
6167   M (TAP_DELETE, mp);
6168
6169   mp->sw_if_index = ntohl (sw_if_index);
6170
6171   /* send it... */
6172   S (mp);
6173
6174   /* Wait for a reply... */
6175   W (ret);
6176   return ret;
6177 }
6178
6179 static int
6180 api_ip_add_del_route (vat_main_t * vam)
6181 {
6182   unformat_input_t *i = vam->input;
6183   vl_api_ip_add_del_route_t *mp;
6184   u32 sw_if_index = ~0, vrf_id = 0;
6185   u8 is_ipv6 = 0;
6186   u8 is_local = 0, is_drop = 0;
6187   u8 is_unreach = 0, is_prohibit = 0;
6188   u8 create_vrf_if_needed = 0;
6189   u8 is_add = 1;
6190   u32 next_hop_weight = 1;
6191   u8 not_last = 0;
6192   u8 is_multipath = 0;
6193   u8 address_set = 0;
6194   u8 address_length_set = 0;
6195   u32 next_hop_table_id = 0;
6196   u32 resolve_attempts = 0;
6197   u32 dst_address_length = 0;
6198   u8 next_hop_set = 0;
6199   ip4_address_t v4_dst_address, v4_next_hop_address;
6200   ip6_address_t v6_dst_address, v6_next_hop_address;
6201   int count = 1;
6202   int j;
6203   f64 before = 0;
6204   u32 random_add_del = 0;
6205   u32 *random_vector = 0;
6206   uword *random_hash;
6207   u32 random_seed = 0xdeaddabe;
6208   u32 classify_table_index = ~0;
6209   u8 is_classify = 0;
6210   u8 resolve_host = 0, resolve_attached = 0;
6211   mpls_label_t *next_hop_out_label_stack = NULL;
6212   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
6213   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
6214
6215   /* Parse args required to build the message */
6216   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6217     {
6218       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6219         ;
6220       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6221         ;
6222       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
6223         {
6224           address_set = 1;
6225           is_ipv6 = 0;
6226         }
6227       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
6228         {
6229           address_set = 1;
6230           is_ipv6 = 1;
6231         }
6232       else if (unformat (i, "/%d", &dst_address_length))
6233         {
6234           address_length_set = 1;
6235         }
6236
6237       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
6238                                          &v4_next_hop_address))
6239         {
6240           next_hop_set = 1;
6241         }
6242       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
6243                                          &v6_next_hop_address))
6244         {
6245           next_hop_set = 1;
6246         }
6247       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
6248         ;
6249       else if (unformat (i, "weight %d", &next_hop_weight))
6250         ;
6251       else if (unformat (i, "drop"))
6252         {
6253           is_drop = 1;
6254         }
6255       else if (unformat (i, "null-send-unreach"))
6256         {
6257           is_unreach = 1;
6258         }
6259       else if (unformat (i, "null-send-prohibit"))
6260         {
6261           is_prohibit = 1;
6262         }
6263       else if (unformat (i, "local"))
6264         {
6265           is_local = 1;
6266         }
6267       else if (unformat (i, "classify %d", &classify_table_index))
6268         {
6269           is_classify = 1;
6270         }
6271       else if (unformat (i, "del"))
6272         is_add = 0;
6273       else if (unformat (i, "add"))
6274         is_add = 1;
6275       else if (unformat (i, "not-last"))
6276         not_last = 1;
6277       else if (unformat (i, "resolve-via-host"))
6278         resolve_host = 1;
6279       else if (unformat (i, "resolve-via-attached"))
6280         resolve_attached = 1;
6281       else if (unformat (i, "multipath"))
6282         is_multipath = 1;
6283       else if (unformat (i, "vrf %d", &vrf_id))
6284         ;
6285       else if (unformat (i, "create-vrf"))
6286         create_vrf_if_needed = 1;
6287       else if (unformat (i, "count %d", &count))
6288         ;
6289       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
6290         ;
6291       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
6292         ;
6293       else if (unformat (i, "out-label %d", &next_hop_out_label))
6294         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
6295       else if (unformat (i, "via-label %d", &next_hop_via_label))
6296         ;
6297       else if (unformat (i, "random"))
6298         random_add_del = 1;
6299       else if (unformat (i, "seed %d", &random_seed))
6300         ;
6301       else
6302         {
6303           clib_warning ("parse error '%U'", format_unformat_error, i);
6304           return -99;
6305         }
6306     }
6307
6308   if (!next_hop_set && !is_drop && !is_local &&
6309       !is_classify && !is_unreach && !is_prohibit &&
6310       MPLS_LABEL_INVALID == next_hop_via_label)
6311     {
6312       errmsg
6313         ("next hop / local / drop / unreach / prohibit / classify not set");
6314       return -99;
6315     }
6316
6317   if (next_hop_set && MPLS_LABEL_INVALID != next_hop_via_label)
6318     {
6319       errmsg ("next hop and next-hop via label set");
6320       return -99;
6321     }
6322   if (address_set == 0)
6323     {
6324       errmsg ("missing addresses");
6325       return -99;
6326     }
6327
6328   if (address_length_set == 0)
6329     {
6330       errmsg ("missing address length");
6331       return -99;
6332     }
6333
6334   /* Generate a pile of unique, random routes */
6335   if (random_add_del)
6336     {
6337       u32 this_random_address;
6338       random_hash = hash_create (count, sizeof (uword));
6339
6340       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
6341       for (j = 0; j <= count; j++)
6342         {
6343           do
6344             {
6345               this_random_address = random_u32 (&random_seed);
6346               this_random_address =
6347                 clib_host_to_net_u32 (this_random_address);
6348             }
6349           while (hash_get (random_hash, this_random_address));
6350           vec_add1 (random_vector, this_random_address);
6351           hash_set (random_hash, this_random_address, 1);
6352         }
6353       hash_free (random_hash);
6354       v4_dst_address.as_u32 = random_vector[0];
6355     }
6356
6357   if (count > 1)
6358     {
6359       /* Turn on async mode */
6360       vam->async_mode = 1;
6361       vam->async_errors = 0;
6362       before = vat_time_now (vam);
6363     }
6364
6365   for (j = 0; j < count; j++)
6366     {
6367       /* Construct the API message */
6368       M2 (IP_ADD_DEL_ROUTE, mp,
6369           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
6370
6371       mp->next_hop_sw_if_index = ntohl (sw_if_index);
6372       mp->table_id = ntohl (vrf_id);
6373       mp->create_vrf_if_needed = create_vrf_if_needed;
6374
6375       mp->is_add = is_add;
6376       mp->is_drop = is_drop;
6377       mp->is_unreach = is_unreach;
6378       mp->is_prohibit = is_prohibit;
6379       mp->is_ipv6 = is_ipv6;
6380       mp->is_local = is_local;
6381       mp->is_classify = is_classify;
6382       mp->is_multipath = is_multipath;
6383       mp->is_resolve_host = resolve_host;
6384       mp->is_resolve_attached = resolve_attached;
6385       mp->not_last = not_last;
6386       mp->next_hop_weight = next_hop_weight;
6387       mp->dst_address_length = dst_address_length;
6388       mp->next_hop_table_id = ntohl (next_hop_table_id);
6389       mp->classify_table_index = ntohl (classify_table_index);
6390       mp->next_hop_via_label = ntohl (next_hop_via_label);
6391       mp->next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
6392       if (0 != mp->next_hop_n_out_labels)
6393         {
6394           memcpy (mp->next_hop_out_label_stack,
6395                   next_hop_out_label_stack,
6396                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
6397           vec_free (next_hop_out_label_stack);
6398         }
6399
6400       if (is_ipv6)
6401         {
6402           clib_memcpy (mp->dst_address, &v6_dst_address,
6403                        sizeof (v6_dst_address));
6404           if (next_hop_set)
6405             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
6406                          sizeof (v6_next_hop_address));
6407           increment_v6_address (&v6_dst_address);
6408         }
6409       else
6410         {
6411           clib_memcpy (mp->dst_address, &v4_dst_address,
6412                        sizeof (v4_dst_address));
6413           if (next_hop_set)
6414             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
6415                          sizeof (v4_next_hop_address));
6416           if (random_add_del)
6417             v4_dst_address.as_u32 = random_vector[j + 1];
6418           else
6419             increment_v4_address (&v4_dst_address);
6420         }
6421       /* send it... */
6422       S (mp);
6423       /* If we receive SIGTERM, stop now... */
6424       if (vam->do_exit)
6425         break;
6426     }
6427
6428   /* When testing multiple add/del ops, use a control-ping to sync */
6429   if (count > 1)
6430     {
6431       vl_api_control_ping_t *mp_ping;
6432       f64 after;
6433       f64 timeout;
6434
6435       /* Shut off async mode */
6436       vam->async_mode = 0;
6437
6438       M (CONTROL_PING, mp_ping);
6439       S (mp_ping);
6440
6441       timeout = vat_time_now (vam) + 1.0;
6442       while (vat_time_now (vam) < timeout)
6443         if (vam->result_ready == 1)
6444           goto out;
6445       vam->retval = -99;
6446
6447     out:
6448       if (vam->retval == -99)
6449         errmsg ("timeout");
6450
6451       if (vam->async_errors > 0)
6452         {
6453           errmsg ("%d asynchronous errors", vam->async_errors);
6454           vam->retval = -98;
6455         }
6456       vam->async_errors = 0;
6457       after = vat_time_now (vam);
6458
6459       /* slim chance, but we might have eaten SIGTERM on the first iteration */
6460       if (j > 0)
6461         count = j;
6462
6463       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6464              count, after - before, count / (after - before));
6465     }
6466   else
6467     {
6468       int ret;
6469
6470       /* Wait for a reply... */
6471       W (ret);
6472       return ret;
6473     }
6474
6475   /* Return the good/bad news */
6476   return (vam->retval);
6477 }
6478
6479 static int
6480 api_ip_mroute_add_del (vat_main_t * vam)
6481 {
6482   unformat_input_t *i = vam->input;
6483   vl_api_ip_mroute_add_del_t *mp;
6484   u32 sw_if_index = ~0, vrf_id = 0;
6485   u8 is_ipv6 = 0;
6486   u8 is_local = 0;
6487   u8 create_vrf_if_needed = 0;
6488   u8 is_add = 1;
6489   u8 address_set = 0;
6490   u32 grp_address_length = 0;
6491   ip4_address_t v4_grp_address, v4_src_address;
6492   ip6_address_t v6_grp_address, v6_src_address;
6493   mfib_itf_flags_t iflags = 0;
6494   mfib_entry_flags_t eflags = 0;
6495   int ret;
6496
6497   /* Parse args required to build the message */
6498   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6499     {
6500       if (unformat (i, "sw_if_index %d", &sw_if_index))
6501         ;
6502       else if (unformat (i, "%U %U",
6503                          unformat_ip4_address, &v4_src_address,
6504                          unformat_ip4_address, &v4_grp_address))
6505         {
6506           grp_address_length = 64;
6507           address_set = 1;
6508           is_ipv6 = 0;
6509         }
6510       else if (unformat (i, "%U %U",
6511                          unformat_ip6_address, &v6_src_address,
6512                          unformat_ip6_address, &v6_grp_address))
6513         {
6514           grp_address_length = 256;
6515           address_set = 1;
6516           is_ipv6 = 1;
6517         }
6518       else if (unformat (i, "%U", unformat_ip4_address, &v4_grp_address))
6519         {
6520           memset (&v4_src_address, 0, sizeof (v4_src_address));
6521           grp_address_length = 32;
6522           address_set = 1;
6523           is_ipv6 = 0;
6524         }
6525       else if (unformat (i, "%U", unformat_ip6_address, &v6_grp_address))
6526         {
6527           memset (&v6_src_address, 0, sizeof (v6_src_address));
6528           grp_address_length = 128;
6529           address_set = 1;
6530           is_ipv6 = 1;
6531         }
6532       else if (unformat (i, "/%d", &grp_address_length))
6533         ;
6534       else if (unformat (i, "local"))
6535         {
6536           is_local = 1;
6537         }
6538       else if (unformat (i, "del"))
6539         is_add = 0;
6540       else if (unformat (i, "add"))
6541         is_add = 1;
6542       else if (unformat (i, "vrf %d", &vrf_id))
6543         ;
6544       else if (unformat (i, "create-vrf"))
6545         create_vrf_if_needed = 1;
6546       else if (unformat (i, "%U", unformat_mfib_itf_flags, &iflags))
6547         ;
6548       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
6549         ;
6550       else
6551         {
6552           clib_warning ("parse error '%U'", format_unformat_error, i);
6553           return -99;
6554         }
6555     }
6556
6557   if (address_set == 0)
6558     {
6559       errmsg ("missing addresses\n");
6560       return -99;
6561     }
6562
6563   /* Construct the API message */
6564   M (IP_MROUTE_ADD_DEL, mp);
6565
6566   mp->next_hop_sw_if_index = ntohl (sw_if_index);
6567   mp->table_id = ntohl (vrf_id);
6568   mp->create_vrf_if_needed = create_vrf_if_needed;
6569
6570   mp->is_add = is_add;
6571   mp->is_ipv6 = is_ipv6;
6572   mp->is_local = is_local;
6573   mp->itf_flags = ntohl (iflags);
6574   mp->entry_flags = ntohl (eflags);
6575   mp->grp_address_length = grp_address_length;
6576   mp->grp_address_length = ntohs (mp->grp_address_length);
6577
6578   if (is_ipv6)
6579     {
6580       clib_memcpy (mp->grp_address, &v6_grp_address, sizeof (v6_grp_address));
6581       clib_memcpy (mp->src_address, &v6_src_address, sizeof (v6_src_address));
6582     }
6583   else
6584     {
6585       clib_memcpy (mp->grp_address, &v4_grp_address, sizeof (v4_grp_address));
6586       clib_memcpy (mp->src_address, &v4_src_address, sizeof (v4_src_address));
6587
6588     }
6589
6590   /* send it... */
6591   S (mp);
6592   /* Wait for a reply... */
6593   W (ret);
6594   return ret;
6595 }
6596
6597 static int
6598 api_mpls_route_add_del (vat_main_t * vam)
6599 {
6600   unformat_input_t *i = vam->input;
6601   vl_api_mpls_route_add_del_t *mp;
6602   u32 sw_if_index = ~0, table_id = 0;
6603   u8 create_table_if_needed = 0;
6604   u8 is_add = 1;
6605   u32 next_hop_weight = 1;
6606   u8 is_multipath = 0;
6607   u32 next_hop_table_id = 0;
6608   u8 next_hop_set = 0;
6609   ip4_address_t v4_next_hop_address = {
6610     .as_u32 = 0,
6611   };
6612   ip6_address_t v6_next_hop_address = { {0} };
6613   int count = 1;
6614   int j;
6615   f64 before = 0;
6616   u32 classify_table_index = ~0;
6617   u8 is_classify = 0;
6618   u8 resolve_host = 0, resolve_attached = 0;
6619   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
6620   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
6621   mpls_label_t *next_hop_out_label_stack = NULL;
6622   mpls_label_t local_label = MPLS_LABEL_INVALID;
6623   u8 is_eos = 0;
6624   u8 next_hop_proto_is_ip4 = 1;
6625
6626   /* Parse args required to build the message */
6627   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6628     {
6629       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6630         ;
6631       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6632         ;
6633       else if (unformat (i, "%d", &local_label))
6634         ;
6635       else if (unformat (i, "eos"))
6636         is_eos = 1;
6637       else if (unformat (i, "non-eos"))
6638         is_eos = 0;
6639       else if (unformat (i, "via %U", unformat_ip4_address,
6640                          &v4_next_hop_address))
6641         {
6642           next_hop_set = 1;
6643           next_hop_proto_is_ip4 = 1;
6644         }
6645       else if (unformat (i, "via %U", unformat_ip6_address,
6646                          &v6_next_hop_address))
6647         {
6648           next_hop_set = 1;
6649           next_hop_proto_is_ip4 = 0;
6650         }
6651       else if (unformat (i, "weight %d", &next_hop_weight))
6652         ;
6653       else if (unformat (i, "create-table"))
6654         create_table_if_needed = 1;
6655       else if (unformat (i, "classify %d", &classify_table_index))
6656         {
6657           is_classify = 1;
6658         }
6659       else if (unformat (i, "del"))
6660         is_add = 0;
6661       else if (unformat (i, "add"))
6662         is_add = 1;
6663       else if (unformat (i, "resolve-via-host"))
6664         resolve_host = 1;
6665       else if (unformat (i, "resolve-via-attached"))
6666         resolve_attached = 1;
6667       else if (unformat (i, "multipath"))
6668         is_multipath = 1;
6669       else if (unformat (i, "count %d", &count))
6670         ;
6671       else if (unformat (i, "lookup-in-ip4-table %d", &next_hop_table_id))
6672         {
6673           next_hop_set = 1;
6674           next_hop_proto_is_ip4 = 1;
6675         }
6676       else if (unformat (i, "lookup-in-ip6-table %d", &next_hop_table_id))
6677         {
6678           next_hop_set = 1;
6679           next_hop_proto_is_ip4 = 0;
6680         }
6681       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
6682         ;
6683       else if (unformat (i, "via-label %d", &next_hop_via_label))
6684         ;
6685       else if (unformat (i, "out-label %d", &next_hop_out_label))
6686         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
6687       else
6688         {
6689           clib_warning ("parse error '%U'", format_unformat_error, i);
6690           return -99;
6691         }
6692     }
6693
6694   if (!next_hop_set && !is_classify)
6695     {
6696       errmsg ("next hop / classify not set");
6697       return -99;
6698     }
6699
6700   if (MPLS_LABEL_INVALID == local_label)
6701     {
6702       errmsg ("missing label");
6703       return -99;
6704     }
6705
6706   if (count > 1)
6707     {
6708       /* Turn on async mode */
6709       vam->async_mode = 1;
6710       vam->async_errors = 0;
6711       before = vat_time_now (vam);
6712     }
6713
6714   for (j = 0; j < count; j++)
6715     {
6716       /* Construct the API message */
6717       M2 (MPLS_ROUTE_ADD_DEL, mp,
6718           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
6719
6720       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
6721       mp->mr_table_id = ntohl (table_id);
6722       mp->mr_create_table_if_needed = create_table_if_needed;
6723
6724       mp->mr_is_add = is_add;
6725       mp->mr_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
6726       mp->mr_is_classify = is_classify;
6727       mp->mr_is_multipath = is_multipath;
6728       mp->mr_is_resolve_host = resolve_host;
6729       mp->mr_is_resolve_attached = resolve_attached;
6730       mp->mr_next_hop_weight = next_hop_weight;
6731       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
6732       mp->mr_classify_table_index = ntohl (classify_table_index);
6733       mp->mr_next_hop_via_label = ntohl (next_hop_via_label);
6734       mp->mr_label = ntohl (local_label);
6735       mp->mr_eos = is_eos;
6736
6737       mp->mr_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
6738       if (0 != mp->mr_next_hop_n_out_labels)
6739         {
6740           memcpy (mp->mr_next_hop_out_label_stack,
6741                   next_hop_out_label_stack,
6742                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
6743           vec_free (next_hop_out_label_stack);
6744         }
6745
6746       if (next_hop_set)
6747         {
6748           if (next_hop_proto_is_ip4)
6749             {
6750               clib_memcpy (mp->mr_next_hop,
6751                            &v4_next_hop_address,
6752                            sizeof (v4_next_hop_address));
6753             }
6754           else
6755             {
6756               clib_memcpy (mp->mr_next_hop,
6757                            &v6_next_hop_address,
6758                            sizeof (v6_next_hop_address));
6759             }
6760         }
6761       local_label++;
6762
6763       /* send it... */
6764       S (mp);
6765       /* If we receive SIGTERM, stop now... */
6766       if (vam->do_exit)
6767         break;
6768     }
6769
6770   /* When testing multiple add/del ops, use a control-ping to sync */
6771   if (count > 1)
6772     {
6773       vl_api_control_ping_t *mp_ping;
6774       f64 after;
6775       f64 timeout;
6776
6777       /* Shut off async mode */
6778       vam->async_mode = 0;
6779
6780       M (CONTROL_PING, mp_ping);
6781       S (mp_ping);
6782
6783       timeout = vat_time_now (vam) + 1.0;
6784       while (vat_time_now (vam) < timeout)
6785         if (vam->result_ready == 1)
6786           goto out;
6787       vam->retval = -99;
6788
6789     out:
6790       if (vam->retval == -99)
6791         errmsg ("timeout");
6792
6793       if (vam->async_errors > 0)
6794         {
6795           errmsg ("%d asynchronous errors", vam->async_errors);
6796           vam->retval = -98;
6797         }
6798       vam->async_errors = 0;
6799       after = vat_time_now (vam);
6800
6801       /* slim chance, but we might have eaten SIGTERM on the first iteration */
6802       if (j > 0)
6803         count = j;
6804
6805       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6806              count, after - before, count / (after - before));
6807     }
6808   else
6809     {
6810       int ret;
6811
6812       /* Wait for a reply... */
6813       W (ret);
6814       return ret;
6815     }
6816
6817   /* Return the good/bad news */
6818   return (vam->retval);
6819 }
6820
6821 static int
6822 api_mpls_ip_bind_unbind (vat_main_t * vam)
6823 {
6824   unformat_input_t *i = vam->input;
6825   vl_api_mpls_ip_bind_unbind_t *mp;
6826   u32 ip_table_id = 0;
6827   u8 create_table_if_needed = 0;
6828   u8 is_bind = 1;
6829   u8 is_ip4 = 1;
6830   ip4_address_t v4_address;
6831   ip6_address_t v6_address;
6832   u32 address_length;
6833   u8 address_set = 0;
6834   mpls_label_t local_label = MPLS_LABEL_INVALID;
6835   int ret;
6836
6837   /* Parse args required to build the message */
6838   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6839     {
6840       if (unformat (i, "%U/%d", unformat_ip4_address,
6841                     &v4_address, &address_length))
6842         {
6843           is_ip4 = 1;
6844           address_set = 1;
6845         }
6846       else if (unformat (i, "%U/%d", unformat_ip6_address,
6847                          &v6_address, &address_length))
6848         {
6849           is_ip4 = 0;
6850           address_set = 1;
6851         }
6852       else if (unformat (i, "%d", &local_label))
6853         ;
6854       else if (unformat (i, "create-table"))
6855         create_table_if_needed = 1;
6856       else if (unformat (i, "table-id %d", &ip_table_id))
6857         ;
6858       else if (unformat (i, "unbind"))
6859         is_bind = 0;
6860       else if (unformat (i, "bind"))
6861         is_bind = 1;
6862       else
6863         {
6864           clib_warning ("parse error '%U'", format_unformat_error, i);
6865           return -99;
6866         }
6867     }
6868
6869   if (!address_set)
6870     {
6871       errmsg ("IP addres not set");
6872       return -99;
6873     }
6874
6875   if (MPLS_LABEL_INVALID == local_label)
6876     {
6877       errmsg ("missing label");
6878       return -99;
6879     }
6880
6881   /* Construct the API message */
6882   M (MPLS_IP_BIND_UNBIND, mp);
6883
6884   mp->mb_create_table_if_needed = create_table_if_needed;
6885   mp->mb_is_bind = is_bind;
6886   mp->mb_is_ip4 = is_ip4;
6887   mp->mb_ip_table_id = ntohl (ip_table_id);
6888   mp->mb_mpls_table_id = 0;
6889   mp->mb_label = ntohl (local_label);
6890   mp->mb_address_length = address_length;
6891
6892   if (is_ip4)
6893     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
6894   else
6895     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
6896
6897   /* send it... */
6898   S (mp);
6899
6900   /* Wait for a reply... */
6901   W (ret);
6902   return ret;
6903 }
6904
6905 static int
6906 api_proxy_arp_add_del (vat_main_t * vam)
6907 {
6908   unformat_input_t *i = vam->input;
6909   vl_api_proxy_arp_add_del_t *mp;
6910   u32 vrf_id = 0;
6911   u8 is_add = 1;
6912   ip4_address_t lo, hi;
6913   u8 range_set = 0;
6914   int ret;
6915
6916   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6917     {
6918       if (unformat (i, "vrf %d", &vrf_id))
6919         ;
6920       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
6921                          unformat_ip4_address, &hi))
6922         range_set = 1;
6923       else if (unformat (i, "del"))
6924         is_add = 0;
6925       else
6926         {
6927           clib_warning ("parse error '%U'", format_unformat_error, i);
6928           return -99;
6929         }
6930     }
6931
6932   if (range_set == 0)
6933     {
6934       errmsg ("address range not set");
6935       return -99;
6936     }
6937
6938   M (PROXY_ARP_ADD_DEL, mp);
6939
6940   mp->vrf_id = ntohl (vrf_id);
6941   mp->is_add = is_add;
6942   clib_memcpy (mp->low_address, &lo, sizeof (mp->low_address));
6943   clib_memcpy (mp->hi_address, &hi, sizeof (mp->hi_address));
6944
6945   S (mp);
6946   W (ret);
6947   return ret;
6948 }
6949
6950 static int
6951 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
6952 {
6953   unformat_input_t *i = vam->input;
6954   vl_api_proxy_arp_intfc_enable_disable_t *mp;
6955   u32 sw_if_index;
6956   u8 enable = 1;
6957   u8 sw_if_index_set = 0;
6958   int ret;
6959
6960   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6961     {
6962       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6963         sw_if_index_set = 1;
6964       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6965         sw_if_index_set = 1;
6966       else if (unformat (i, "enable"))
6967         enable = 1;
6968       else if (unformat (i, "disable"))
6969         enable = 0;
6970       else
6971         {
6972           clib_warning ("parse error '%U'", format_unformat_error, i);
6973           return -99;
6974         }
6975     }
6976
6977   if (sw_if_index_set == 0)
6978     {
6979       errmsg ("missing interface name or sw_if_index");
6980       return -99;
6981     }
6982
6983   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
6984
6985   mp->sw_if_index = ntohl (sw_if_index);
6986   mp->enable_disable = enable;
6987
6988   S (mp);
6989   W (ret);
6990   return ret;
6991 }
6992
6993 static int
6994 api_mpls_tunnel_add_del (vat_main_t * vam)
6995 {
6996   unformat_input_t *i = vam->input;
6997   vl_api_mpls_tunnel_add_del_t *mp;
6998
6999   u8 is_add = 1;
7000   u8 l2_only = 0;
7001   u32 sw_if_index = ~0;
7002   u32 next_hop_sw_if_index = ~0;
7003   u32 next_hop_proto_is_ip4 = 1;
7004
7005   u32 next_hop_table_id = 0;
7006   ip4_address_t v4_next_hop_address = {
7007     .as_u32 = 0,
7008   };
7009   ip6_address_t v6_next_hop_address = { {0} };
7010   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID, *labels = NULL;
7011   int ret;
7012
7013   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7014     {
7015       if (unformat (i, "add"))
7016         is_add = 1;
7017       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
7018         is_add = 0;
7019       else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
7020         ;
7021       else if (unformat (i, "via %U",
7022                          unformat_ip4_address, &v4_next_hop_address))
7023         {
7024           next_hop_proto_is_ip4 = 1;
7025         }
7026       else if (unformat (i, "via %U",
7027                          unformat_ip6_address, &v6_next_hop_address))
7028         {
7029           next_hop_proto_is_ip4 = 0;
7030         }
7031       else if (unformat (i, "l2-only"))
7032         l2_only = 1;
7033       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
7034         ;
7035       else if (unformat (i, "out-label %d", &next_hop_out_label))
7036         vec_add1 (labels, ntohl (next_hop_out_label));
7037       else
7038         {
7039           clib_warning ("parse error '%U'", format_unformat_error, i);
7040           return -99;
7041         }
7042     }
7043
7044   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (mpls_label_t) * vec_len (labels));
7045
7046   mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
7047   mp->mt_sw_if_index = ntohl (sw_if_index);
7048   mp->mt_is_add = is_add;
7049   mp->mt_l2_only = l2_only;
7050   mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
7051   mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
7052
7053   mp->mt_next_hop_n_out_labels = vec_len (labels);
7054
7055   if (0 != mp->mt_next_hop_n_out_labels)
7056     {
7057       clib_memcpy (mp->mt_next_hop_out_label_stack, labels,
7058                    sizeof (mpls_label_t) * mp->mt_next_hop_n_out_labels);
7059       vec_free (labels);
7060     }
7061
7062   if (next_hop_proto_is_ip4)
7063     {
7064       clib_memcpy (mp->mt_next_hop,
7065                    &v4_next_hop_address, sizeof (v4_next_hop_address));
7066     }
7067   else
7068     {
7069       clib_memcpy (mp->mt_next_hop,
7070                    &v6_next_hop_address, sizeof (v6_next_hop_address));
7071     }
7072
7073   S (mp);
7074   W (ret);
7075   return ret;
7076 }
7077
7078 static int
7079 api_sw_interface_set_unnumbered (vat_main_t * vam)
7080 {
7081   unformat_input_t *i = vam->input;
7082   vl_api_sw_interface_set_unnumbered_t *mp;
7083   u32 sw_if_index;
7084   u32 unnum_sw_index = ~0;
7085   u8 is_add = 1;
7086   u8 sw_if_index_set = 0;
7087   int ret;
7088
7089   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7090     {
7091       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7092         sw_if_index_set = 1;
7093       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7094         sw_if_index_set = 1;
7095       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
7096         ;
7097       else if (unformat (i, "del"))
7098         is_add = 0;
7099       else
7100         {
7101           clib_warning ("parse error '%U'", format_unformat_error, i);
7102           return -99;
7103         }
7104     }
7105
7106   if (sw_if_index_set == 0)
7107     {
7108       errmsg ("missing interface name or sw_if_index");
7109       return -99;
7110     }
7111
7112   M (SW_INTERFACE_SET_UNNUMBERED, mp);
7113
7114   mp->sw_if_index = ntohl (sw_if_index);
7115   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
7116   mp->is_add = is_add;
7117
7118   S (mp);
7119   W (ret);
7120   return ret;
7121 }
7122
7123 static int
7124 api_ip_neighbor_add_del (vat_main_t * vam)
7125 {
7126   unformat_input_t *i = vam->input;
7127   vl_api_ip_neighbor_add_del_t *mp;
7128   u32 sw_if_index;
7129   u8 sw_if_index_set = 0;
7130   u8 is_add = 1;
7131   u8 is_static = 0;
7132   u8 mac_address[6];
7133   u8 mac_set = 0;
7134   u8 v4_address_set = 0;
7135   u8 v6_address_set = 0;
7136   ip4_address_t v4address;
7137   ip6_address_t v6address;
7138   int ret;
7139
7140   memset (mac_address, 0, sizeof (mac_address));
7141
7142   /* Parse args required to build the message */
7143   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7144     {
7145       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7146         {
7147           mac_set = 1;
7148         }
7149       else if (unformat (i, "del"))
7150         is_add = 0;
7151       else
7152         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7153         sw_if_index_set = 1;
7154       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7155         sw_if_index_set = 1;
7156       else if (unformat (i, "is_static"))
7157         is_static = 1;
7158       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
7159         v4_address_set = 1;
7160       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
7161         v6_address_set = 1;
7162       else
7163         {
7164           clib_warning ("parse error '%U'", format_unformat_error, i);
7165           return -99;
7166         }
7167     }
7168
7169   if (sw_if_index_set == 0)
7170     {
7171       errmsg ("missing interface name or sw_if_index");
7172       return -99;
7173     }
7174   if (v4_address_set && v6_address_set)
7175     {
7176       errmsg ("both v4 and v6 addresses set");
7177       return -99;
7178     }
7179   if (!v4_address_set && !v6_address_set)
7180     {
7181       errmsg ("no address set");
7182       return -99;
7183     }
7184
7185   /* Construct the API message */
7186   M (IP_NEIGHBOR_ADD_DEL, mp);
7187
7188   mp->sw_if_index = ntohl (sw_if_index);
7189   mp->is_add = is_add;
7190   mp->is_static = is_static;
7191   if (mac_set)
7192     clib_memcpy (mp->mac_address, mac_address, 6);
7193   if (v6_address_set)
7194     {
7195       mp->is_ipv6 = 1;
7196       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
7197     }
7198   else
7199     {
7200       /* mp->is_ipv6 = 0; via memset in M macro above */
7201       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
7202     }
7203
7204   /* send it... */
7205   S (mp);
7206
7207   /* Wait for a reply, return good/bad news  */
7208   W (ret);
7209   return ret;
7210 }
7211
7212 static int
7213 api_reset_vrf (vat_main_t * vam)
7214 {
7215   unformat_input_t *i = vam->input;
7216   vl_api_reset_vrf_t *mp;
7217   u32 vrf_id = 0;
7218   u8 is_ipv6 = 0;
7219   u8 vrf_id_set = 0;
7220   int ret;
7221
7222   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7223     {
7224       if (unformat (i, "vrf %d", &vrf_id))
7225         vrf_id_set = 1;
7226       else if (unformat (i, "ipv6"))
7227         is_ipv6 = 1;
7228       else
7229         {
7230           clib_warning ("parse error '%U'", format_unformat_error, i);
7231           return -99;
7232         }
7233     }
7234
7235   if (vrf_id_set == 0)
7236     {
7237       errmsg ("missing vrf id");
7238       return -99;
7239     }
7240
7241   M (RESET_VRF, mp);
7242
7243   mp->vrf_id = ntohl (vrf_id);
7244   mp->is_ipv6 = is_ipv6;
7245
7246   S (mp);
7247   W (ret);
7248   return ret;
7249 }
7250
7251 static int
7252 api_create_vlan_subif (vat_main_t * vam)
7253 {
7254   unformat_input_t *i = vam->input;
7255   vl_api_create_vlan_subif_t *mp;
7256   u32 sw_if_index;
7257   u8 sw_if_index_set = 0;
7258   u32 vlan_id;
7259   u8 vlan_id_set = 0;
7260   int ret;
7261
7262   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7263     {
7264       if (unformat (i, "sw_if_index %d", &sw_if_index))
7265         sw_if_index_set = 1;
7266       else
7267         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7268         sw_if_index_set = 1;
7269       else if (unformat (i, "vlan %d", &vlan_id))
7270         vlan_id_set = 1;
7271       else
7272         {
7273           clib_warning ("parse error '%U'", format_unformat_error, i);
7274           return -99;
7275         }
7276     }
7277
7278   if (sw_if_index_set == 0)
7279     {
7280       errmsg ("missing interface name or sw_if_index");
7281       return -99;
7282     }
7283
7284   if (vlan_id_set == 0)
7285     {
7286       errmsg ("missing vlan_id");
7287       return -99;
7288     }
7289   M (CREATE_VLAN_SUBIF, mp);
7290
7291   mp->sw_if_index = ntohl (sw_if_index);
7292   mp->vlan_id = ntohl (vlan_id);
7293
7294   S (mp);
7295   W (ret);
7296   return ret;
7297 }
7298
7299 #define foreach_create_subif_bit                \
7300 _(no_tags)                                      \
7301 _(one_tag)                                      \
7302 _(two_tags)                                     \
7303 _(dot1ad)                                       \
7304 _(exact_match)                                  \
7305 _(default_sub)                                  \
7306 _(outer_vlan_id_any)                            \
7307 _(inner_vlan_id_any)
7308
7309 static int
7310 api_create_subif (vat_main_t * vam)
7311 {
7312   unformat_input_t *i = vam->input;
7313   vl_api_create_subif_t *mp;
7314   u32 sw_if_index;
7315   u8 sw_if_index_set = 0;
7316   u32 sub_id;
7317   u8 sub_id_set = 0;
7318   u32 no_tags = 0;
7319   u32 one_tag = 0;
7320   u32 two_tags = 0;
7321   u32 dot1ad = 0;
7322   u32 exact_match = 0;
7323   u32 default_sub = 0;
7324   u32 outer_vlan_id_any = 0;
7325   u32 inner_vlan_id_any = 0;
7326   u32 tmp;
7327   u16 outer_vlan_id = 0;
7328   u16 inner_vlan_id = 0;
7329   int ret;
7330
7331   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7332     {
7333       if (unformat (i, "sw_if_index %d", &sw_if_index))
7334         sw_if_index_set = 1;
7335       else
7336         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7337         sw_if_index_set = 1;
7338       else if (unformat (i, "sub_id %d", &sub_id))
7339         sub_id_set = 1;
7340       else if (unformat (i, "outer_vlan_id %d", &tmp))
7341         outer_vlan_id = tmp;
7342       else if (unformat (i, "inner_vlan_id %d", &tmp))
7343         inner_vlan_id = tmp;
7344
7345 #define _(a) else if (unformat (i, #a)) a = 1 ;
7346       foreach_create_subif_bit
7347 #undef _
7348         else
7349         {
7350           clib_warning ("parse error '%U'", format_unformat_error, i);
7351           return -99;
7352         }
7353     }
7354
7355   if (sw_if_index_set == 0)
7356     {
7357       errmsg ("missing interface name or sw_if_index");
7358       return -99;
7359     }
7360
7361   if (sub_id_set == 0)
7362     {
7363       errmsg ("missing sub_id");
7364       return -99;
7365     }
7366   M (CREATE_SUBIF, mp);
7367
7368   mp->sw_if_index = ntohl (sw_if_index);
7369   mp->sub_id = ntohl (sub_id);
7370
7371 #define _(a) mp->a = a;
7372   foreach_create_subif_bit;
7373 #undef _
7374
7375   mp->outer_vlan_id = ntohs (outer_vlan_id);
7376   mp->inner_vlan_id = ntohs (inner_vlan_id);
7377
7378   S (mp);
7379   W (ret);
7380   return ret;
7381 }
7382
7383 static int
7384 api_oam_add_del (vat_main_t * vam)
7385 {
7386   unformat_input_t *i = vam->input;
7387   vl_api_oam_add_del_t *mp;
7388   u32 vrf_id = 0;
7389   u8 is_add = 1;
7390   ip4_address_t src, dst;
7391   u8 src_set = 0;
7392   u8 dst_set = 0;
7393   int ret;
7394
7395   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7396     {
7397       if (unformat (i, "vrf %d", &vrf_id))
7398         ;
7399       else if (unformat (i, "src %U", unformat_ip4_address, &src))
7400         src_set = 1;
7401       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
7402         dst_set = 1;
7403       else if (unformat (i, "del"))
7404         is_add = 0;
7405       else
7406         {
7407           clib_warning ("parse error '%U'", format_unformat_error, i);
7408           return -99;
7409         }
7410     }
7411
7412   if (src_set == 0)
7413     {
7414       errmsg ("missing src addr");
7415       return -99;
7416     }
7417
7418   if (dst_set == 0)
7419     {
7420       errmsg ("missing dst addr");
7421       return -99;
7422     }
7423
7424   M (OAM_ADD_DEL, mp);
7425
7426   mp->vrf_id = ntohl (vrf_id);
7427   mp->is_add = is_add;
7428   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
7429   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
7430
7431   S (mp);
7432   W (ret);
7433   return ret;
7434 }
7435
7436 static int
7437 api_reset_fib (vat_main_t * vam)
7438 {
7439   unformat_input_t *i = vam->input;
7440   vl_api_reset_fib_t *mp;
7441   u32 vrf_id = 0;
7442   u8 is_ipv6 = 0;
7443   u8 vrf_id_set = 0;
7444
7445   int ret;
7446   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7447     {
7448       if (unformat (i, "vrf %d", &vrf_id))
7449         vrf_id_set = 1;
7450       else if (unformat (i, "ipv6"))
7451         is_ipv6 = 1;
7452       else
7453         {
7454           clib_warning ("parse error '%U'", format_unformat_error, i);
7455           return -99;
7456         }
7457     }
7458
7459   if (vrf_id_set == 0)
7460     {
7461       errmsg ("missing vrf id");
7462       return -99;
7463     }
7464
7465   M (RESET_FIB, mp);
7466
7467   mp->vrf_id = ntohl (vrf_id);
7468   mp->is_ipv6 = is_ipv6;
7469
7470   S (mp);
7471   W (ret);
7472   return ret;
7473 }
7474
7475 static int
7476 api_dhcp_proxy_config (vat_main_t * vam)
7477 {
7478   unformat_input_t *i = vam->input;
7479   vl_api_dhcp_proxy_config_t *mp;
7480   u32 rx_vrf_id = 0;
7481   u32 server_vrf_id = 0;
7482   u8 is_add = 1;
7483   u8 v4_address_set = 0;
7484   u8 v6_address_set = 0;
7485   ip4_address_t v4address;
7486   ip6_address_t v6address;
7487   u8 v4_src_address_set = 0;
7488   u8 v6_src_address_set = 0;
7489   ip4_address_t v4srcaddress;
7490   ip6_address_t v6srcaddress;
7491   int ret;
7492
7493   /* Parse args required to build the message */
7494   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7495     {
7496       if (unformat (i, "del"))
7497         is_add = 0;
7498       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
7499         ;
7500       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
7501         ;
7502       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
7503         v4_address_set = 1;
7504       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
7505         v6_address_set = 1;
7506       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
7507         v4_src_address_set = 1;
7508       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
7509         v6_src_address_set = 1;
7510       else
7511         break;
7512     }
7513
7514   if (v4_address_set && v6_address_set)
7515     {
7516       errmsg ("both v4 and v6 server addresses set");
7517       return -99;
7518     }
7519   if (!v4_address_set && !v6_address_set)
7520     {
7521       errmsg ("no server addresses set");
7522       return -99;
7523     }
7524
7525   if (v4_src_address_set && v6_src_address_set)
7526     {
7527       errmsg ("both v4 and v6  src addresses set");
7528       return -99;
7529     }
7530   if (!v4_src_address_set && !v6_src_address_set)
7531     {
7532       errmsg ("no src addresses set");
7533       return -99;
7534     }
7535
7536   if (!(v4_src_address_set && v4_address_set) &&
7537       !(v6_src_address_set && v6_address_set))
7538     {
7539       errmsg ("no matching server and src addresses set");
7540       return -99;
7541     }
7542
7543   /* Construct the API message */
7544   M (DHCP_PROXY_CONFIG, mp);
7545
7546   mp->is_add = is_add;
7547   mp->rx_vrf_id = ntohl (rx_vrf_id);
7548   mp->server_vrf_id = ntohl (server_vrf_id);
7549   if (v6_address_set)
7550     {
7551       mp->is_ipv6 = 1;
7552       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
7553       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
7554     }
7555   else
7556     {
7557       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
7558       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
7559     }
7560
7561   /* send it... */
7562   S (mp);
7563
7564   /* Wait for a reply, return good/bad news  */
7565   W (ret);
7566   return ret;
7567 }
7568
7569 #define vl_api_dhcp_proxy_details_t_endian vl_noop_handler
7570 #define vl_api_dhcp_proxy_details_t_print vl_noop_handler
7571
7572 static void
7573 vl_api_dhcp_proxy_details_t_handler (vl_api_dhcp_proxy_details_t * mp)
7574 {
7575   vat_main_t *vam = &vat_main;
7576
7577   if (mp->is_ipv6)
7578     print (vam->ofp,
7579            "RX Table-ID %d, Server Table-ID %d, Server Address %U, Source Address %U, VSS FIB-ID %d, VSS OUI %d",
7580            ntohl (mp->rx_vrf_id),
7581            ntohl (mp->server_vrf_id),
7582            format_ip6_address, mp->dhcp_server,
7583            format_ip6_address, mp->dhcp_src_address,
7584            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
7585   else
7586     print (vam->ofp,
7587            "RX Table-ID %d, Server Table-ID %d, Server Address %U, Source Address %U, VSS FIB-ID %d, VSS OUI %d",
7588            ntohl (mp->rx_vrf_id),
7589            ntohl (mp->server_vrf_id),
7590            format_ip4_address, mp->dhcp_server,
7591            format_ip4_address, mp->dhcp_src_address,
7592            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
7593 }
7594
7595 static void vl_api_dhcp_proxy_details_t_handler_json
7596   (vl_api_dhcp_proxy_details_t * mp)
7597 {
7598   vat_main_t *vam = &vat_main;
7599   vat_json_node_t *node = NULL;
7600   struct in_addr ip4;
7601   struct in6_addr ip6;
7602
7603   if (VAT_JSON_ARRAY != vam->json_tree.type)
7604     {
7605       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
7606       vat_json_init_array (&vam->json_tree);
7607     }
7608   node = vat_json_array_add (&vam->json_tree);
7609
7610   vat_json_init_object (node);
7611   vat_json_object_add_uint (node, "rx-table-id", ntohl (mp->rx_vrf_id));
7612   vat_json_object_add_uint (node, "server-table-id",
7613                             ntohl (mp->server_vrf_id));
7614   if (mp->is_ipv6)
7615     {
7616       clib_memcpy (&ip6, &mp->dhcp_server, sizeof (ip6));
7617       vat_json_object_add_ip6 (node, "server_address", ip6);
7618       clib_memcpy (&ip6, &mp->dhcp_src_address, sizeof (ip6));
7619       vat_json_object_add_ip6 (node, "src_address", ip6);
7620     }
7621   else
7622     {
7623       clib_memcpy (&ip4, &mp->dhcp_server, sizeof (ip4));
7624       vat_json_object_add_ip4 (node, "server_address", ip4);
7625       clib_memcpy (&ip4, &mp->dhcp_src_address, sizeof (ip4));
7626       vat_json_object_add_ip4 (node, "src_address", ip4);
7627     }
7628   vat_json_object_add_uint (node, "vss-fib-id", ntohl (mp->vss_fib_id));
7629   vat_json_object_add_uint (node, "vss-oui", ntohl (mp->vss_oui));
7630 }
7631
7632 static int
7633 api_dhcp_proxy_dump (vat_main_t * vam)
7634 {
7635   unformat_input_t *i = vam->input;
7636   vl_api_control_ping_t *mp_ping;
7637   vl_api_dhcp_proxy_dump_t *mp;
7638   u8 is_ipv6 = 0;
7639   int ret;
7640
7641   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7642     {
7643       if (unformat (i, "ipv6"))
7644         is_ipv6 = 1;
7645       else
7646         {
7647           clib_warning ("parse error '%U'", format_unformat_error, i);
7648           return -99;
7649         }
7650     }
7651
7652   M (DHCP_PROXY_DUMP, mp);
7653
7654   mp->is_ip6 = is_ipv6;
7655   S (mp);
7656
7657   /* Use a control ping for synchronization */
7658   M (CONTROL_PING, mp_ping);
7659   S (mp_ping);
7660
7661   W (ret);
7662   return ret;
7663 }
7664
7665 static int
7666 api_dhcp_proxy_set_vss (vat_main_t * vam)
7667 {
7668   unformat_input_t *i = vam->input;
7669   vl_api_dhcp_proxy_set_vss_t *mp;
7670   u8 is_ipv6 = 0;
7671   u8 is_add = 1;
7672   u32 tbl_id;
7673   u8 tbl_id_set = 0;
7674   u32 oui;
7675   u8 oui_set = 0;
7676   u32 fib_id;
7677   u8 fib_id_set = 0;
7678   int ret;
7679
7680   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7681     {
7682       if (unformat (i, "tbl_id %d", &tbl_id))
7683         tbl_id_set = 1;
7684       if (unformat (i, "fib_id %d", &fib_id))
7685         fib_id_set = 1;
7686       if (unformat (i, "oui %d", &oui))
7687         oui_set = 1;
7688       else if (unformat (i, "ipv6"))
7689         is_ipv6 = 1;
7690       else if (unformat (i, "del"))
7691         is_add = 0;
7692       else
7693         {
7694           clib_warning ("parse error '%U'", format_unformat_error, i);
7695           return -99;
7696         }
7697     }
7698
7699   if (tbl_id_set == 0)
7700     {
7701       errmsg ("missing tbl id");
7702       return -99;
7703     }
7704
7705   if (fib_id_set == 0)
7706     {
7707       errmsg ("missing fib id");
7708       return -99;
7709     }
7710   if (oui_set == 0)
7711     {
7712       errmsg ("missing oui");
7713       return -99;
7714     }
7715
7716   M (DHCP_PROXY_SET_VSS, mp);
7717   mp->tbl_id = ntohl (tbl_id);
7718   mp->fib_id = ntohl (fib_id);
7719   mp->oui = ntohl (oui);
7720   mp->is_ipv6 = is_ipv6;
7721   mp->is_add = is_add;
7722
7723   S (mp);
7724   W (ret);
7725   return ret;
7726 }
7727
7728 static int
7729 api_dhcp_client_config (vat_main_t * vam)
7730 {
7731   unformat_input_t *i = vam->input;
7732   vl_api_dhcp_client_config_t *mp;
7733   u32 sw_if_index;
7734   u8 sw_if_index_set = 0;
7735   u8 is_add = 1;
7736   u8 *hostname = 0;
7737   u8 disable_event = 0;
7738   int ret;
7739
7740   /* Parse args required to build the message */
7741   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7742     {
7743       if (unformat (i, "del"))
7744         is_add = 0;
7745       else
7746         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7747         sw_if_index_set = 1;
7748       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7749         sw_if_index_set = 1;
7750       else if (unformat (i, "hostname %s", &hostname))
7751         ;
7752       else if (unformat (i, "disable_event"))
7753         disable_event = 1;
7754       else
7755         break;
7756     }
7757
7758   if (sw_if_index_set == 0)
7759     {
7760       errmsg ("missing interface name or sw_if_index");
7761       return -99;
7762     }
7763
7764   if (vec_len (hostname) > 63)
7765     {
7766       errmsg ("hostname too long");
7767     }
7768   vec_add1 (hostname, 0);
7769
7770   /* Construct the API message */
7771   M (DHCP_CLIENT_CONFIG, mp);
7772
7773   mp->sw_if_index = ntohl (sw_if_index);
7774   clib_memcpy (mp->hostname, hostname, vec_len (hostname));
7775   vec_free (hostname);
7776   mp->is_add = is_add;
7777   mp->want_dhcp_event = disable_event ? 0 : 1;
7778   mp->pid = getpid ();
7779
7780   /* send it... */
7781   S (mp);
7782
7783   /* Wait for a reply, return good/bad news  */
7784   W (ret);
7785   return ret;
7786 }
7787
7788 static int
7789 api_set_ip_flow_hash (vat_main_t * vam)
7790 {
7791   unformat_input_t *i = vam->input;
7792   vl_api_set_ip_flow_hash_t *mp;
7793   u32 vrf_id = 0;
7794   u8 is_ipv6 = 0;
7795   u8 vrf_id_set = 0;
7796   u8 src = 0;
7797   u8 dst = 0;
7798   u8 sport = 0;
7799   u8 dport = 0;
7800   u8 proto = 0;
7801   u8 reverse = 0;
7802   int ret;
7803
7804   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7805     {
7806       if (unformat (i, "vrf %d", &vrf_id))
7807         vrf_id_set = 1;
7808       else if (unformat (i, "ipv6"))
7809         is_ipv6 = 1;
7810       else if (unformat (i, "src"))
7811         src = 1;
7812       else if (unformat (i, "dst"))
7813         dst = 1;
7814       else if (unformat (i, "sport"))
7815         sport = 1;
7816       else if (unformat (i, "dport"))
7817         dport = 1;
7818       else if (unformat (i, "proto"))
7819         proto = 1;
7820       else if (unformat (i, "reverse"))
7821         reverse = 1;
7822
7823       else
7824         {
7825           clib_warning ("parse error '%U'", format_unformat_error, i);
7826           return -99;
7827         }
7828     }
7829
7830   if (vrf_id_set == 0)
7831     {
7832       errmsg ("missing vrf id");
7833       return -99;
7834     }
7835
7836   M (SET_IP_FLOW_HASH, mp);
7837   mp->src = src;
7838   mp->dst = dst;
7839   mp->sport = sport;
7840   mp->dport = dport;
7841   mp->proto = proto;
7842   mp->reverse = reverse;
7843   mp->vrf_id = ntohl (vrf_id);
7844   mp->is_ipv6 = is_ipv6;
7845
7846   S (mp);
7847   W (ret);
7848   return ret;
7849 }
7850
7851 static int
7852 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
7853 {
7854   unformat_input_t *i = vam->input;
7855   vl_api_sw_interface_ip6_enable_disable_t *mp;
7856   u32 sw_if_index;
7857   u8 sw_if_index_set = 0;
7858   u8 enable = 0;
7859   int ret;
7860
7861   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7862     {
7863       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7864         sw_if_index_set = 1;
7865       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7866         sw_if_index_set = 1;
7867       else if (unformat (i, "enable"))
7868         enable = 1;
7869       else if (unformat (i, "disable"))
7870         enable = 0;
7871       else
7872         {
7873           clib_warning ("parse error '%U'", format_unformat_error, i);
7874           return -99;
7875         }
7876     }
7877
7878   if (sw_if_index_set == 0)
7879     {
7880       errmsg ("missing interface name or sw_if_index");
7881       return -99;
7882     }
7883
7884   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
7885
7886   mp->sw_if_index = ntohl (sw_if_index);
7887   mp->enable = enable;
7888
7889   S (mp);
7890   W (ret);
7891   return ret;
7892 }
7893
7894 static int
7895 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
7896 {
7897   unformat_input_t *i = vam->input;
7898   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
7899   u32 sw_if_index;
7900   u8 sw_if_index_set = 0;
7901   u8 v6_address_set = 0;
7902   ip6_address_t v6address;
7903   int ret;
7904
7905   /* Parse args required to build the message */
7906   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7907     {
7908       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7909         sw_if_index_set = 1;
7910       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7911         sw_if_index_set = 1;
7912       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
7913         v6_address_set = 1;
7914       else
7915         break;
7916     }
7917
7918   if (sw_if_index_set == 0)
7919     {
7920       errmsg ("missing interface name or sw_if_index");
7921       return -99;
7922     }
7923   if (!v6_address_set)
7924     {
7925       errmsg ("no address set");
7926       return -99;
7927     }
7928
7929   /* Construct the API message */
7930   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS, mp);
7931
7932   mp->sw_if_index = ntohl (sw_if_index);
7933   clib_memcpy (mp->address, &v6address, sizeof (v6address));
7934
7935   /* send it... */
7936   S (mp);
7937
7938   /* Wait for a reply, return good/bad news  */
7939   W (ret);
7940   return ret;
7941 }
7942
7943
7944 static int
7945 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
7946 {
7947   unformat_input_t *i = vam->input;
7948   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
7949   u32 sw_if_index;
7950   u8 sw_if_index_set = 0;
7951   u32 address_length = 0;
7952   u8 v6_address_set = 0;
7953   ip6_address_t v6address;
7954   u8 use_default = 0;
7955   u8 no_advertise = 0;
7956   u8 off_link = 0;
7957   u8 no_autoconfig = 0;
7958   u8 no_onlink = 0;
7959   u8 is_no = 0;
7960   u32 val_lifetime = 0;
7961   u32 pref_lifetime = 0;
7962   int ret;
7963
7964   /* Parse args required to build the message */
7965   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7966     {
7967       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7968         sw_if_index_set = 1;
7969       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7970         sw_if_index_set = 1;
7971       else if (unformat (i, "%U/%d",
7972                          unformat_ip6_address, &v6address, &address_length))
7973         v6_address_set = 1;
7974       else if (unformat (i, "val_life %d", &val_lifetime))
7975         ;
7976       else if (unformat (i, "pref_life %d", &pref_lifetime))
7977         ;
7978       else if (unformat (i, "def"))
7979         use_default = 1;
7980       else if (unformat (i, "noadv"))
7981         no_advertise = 1;
7982       else if (unformat (i, "offl"))
7983         off_link = 1;
7984       else if (unformat (i, "noauto"))
7985         no_autoconfig = 1;
7986       else if (unformat (i, "nolink"))
7987         no_onlink = 1;
7988       else if (unformat (i, "isno"))
7989         is_no = 1;
7990       else
7991         {
7992           clib_warning ("parse error '%U'", format_unformat_error, i);
7993           return -99;
7994         }
7995     }
7996
7997   if (sw_if_index_set == 0)
7998     {
7999       errmsg ("missing interface name or sw_if_index");
8000       return -99;
8001     }
8002   if (!v6_address_set)
8003     {
8004       errmsg ("no address set");
8005       return -99;
8006     }
8007
8008   /* Construct the API message */
8009   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
8010
8011   mp->sw_if_index = ntohl (sw_if_index);
8012   clib_memcpy (mp->address, &v6address, sizeof (v6address));
8013   mp->address_length = address_length;
8014   mp->use_default = use_default;
8015   mp->no_advertise = no_advertise;
8016   mp->off_link = off_link;
8017   mp->no_autoconfig = no_autoconfig;
8018   mp->no_onlink = no_onlink;
8019   mp->is_no = is_no;
8020   mp->val_lifetime = ntohl (val_lifetime);
8021   mp->pref_lifetime = ntohl (pref_lifetime);
8022
8023   /* send it... */
8024   S (mp);
8025
8026   /* Wait for a reply, return good/bad news  */
8027   W (ret);
8028   return ret;
8029 }
8030
8031 static int
8032 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
8033 {
8034   unformat_input_t *i = vam->input;
8035   vl_api_sw_interface_ip6nd_ra_config_t *mp;
8036   u32 sw_if_index;
8037   u8 sw_if_index_set = 0;
8038   u8 suppress = 0;
8039   u8 managed = 0;
8040   u8 other = 0;
8041   u8 ll_option = 0;
8042   u8 send_unicast = 0;
8043   u8 cease = 0;
8044   u8 is_no = 0;
8045   u8 default_router = 0;
8046   u32 max_interval = 0;
8047   u32 min_interval = 0;
8048   u32 lifetime = 0;
8049   u32 initial_count = 0;
8050   u32 initial_interval = 0;
8051   int ret;
8052
8053
8054   /* Parse args required to build the message */
8055   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8056     {
8057       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8058         sw_if_index_set = 1;
8059       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8060         sw_if_index_set = 1;
8061       else if (unformat (i, "maxint %d", &max_interval))
8062         ;
8063       else if (unformat (i, "minint %d", &min_interval))
8064         ;
8065       else if (unformat (i, "life %d", &lifetime))
8066         ;
8067       else if (unformat (i, "count %d", &initial_count))
8068         ;
8069       else if (unformat (i, "interval %d", &initial_interval))
8070         ;
8071       else if (unformat (i, "suppress") || unformat (i, "surpress"))
8072         suppress = 1;
8073       else if (unformat (i, "managed"))
8074         managed = 1;
8075       else if (unformat (i, "other"))
8076         other = 1;
8077       else if (unformat (i, "ll"))
8078         ll_option = 1;
8079       else if (unformat (i, "send"))
8080         send_unicast = 1;
8081       else if (unformat (i, "cease"))
8082         cease = 1;
8083       else if (unformat (i, "isno"))
8084         is_no = 1;
8085       else if (unformat (i, "def"))
8086         default_router = 1;
8087       else
8088         {
8089           clib_warning ("parse error '%U'", format_unformat_error, i);
8090           return -99;
8091         }
8092     }
8093
8094   if (sw_if_index_set == 0)
8095     {
8096       errmsg ("missing interface name or sw_if_index");
8097       return -99;
8098     }
8099
8100   /* Construct the API message */
8101   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
8102
8103   mp->sw_if_index = ntohl (sw_if_index);
8104   mp->max_interval = ntohl (max_interval);
8105   mp->min_interval = ntohl (min_interval);
8106   mp->lifetime = ntohl (lifetime);
8107   mp->initial_count = ntohl (initial_count);
8108   mp->initial_interval = ntohl (initial_interval);
8109   mp->suppress = suppress;
8110   mp->managed = managed;
8111   mp->other = other;
8112   mp->ll_option = ll_option;
8113   mp->send_unicast = send_unicast;
8114   mp->cease = cease;
8115   mp->is_no = is_no;
8116   mp->default_router = default_router;
8117
8118   /* send it... */
8119   S (mp);
8120
8121   /* Wait for a reply, return good/bad news  */
8122   W (ret);
8123   return ret;
8124 }
8125
8126 static int
8127 api_set_arp_neighbor_limit (vat_main_t * vam)
8128 {
8129   unformat_input_t *i = vam->input;
8130   vl_api_set_arp_neighbor_limit_t *mp;
8131   u32 arp_nbr_limit;
8132   u8 limit_set = 0;
8133   u8 is_ipv6 = 0;
8134   int ret;
8135
8136   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8137     {
8138       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
8139         limit_set = 1;
8140       else if (unformat (i, "ipv6"))
8141         is_ipv6 = 1;
8142       else
8143         {
8144           clib_warning ("parse error '%U'", format_unformat_error, i);
8145           return -99;
8146         }
8147     }
8148
8149   if (limit_set == 0)
8150     {
8151       errmsg ("missing limit value");
8152       return -99;
8153     }
8154
8155   M (SET_ARP_NEIGHBOR_LIMIT, mp);
8156
8157   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
8158   mp->is_ipv6 = is_ipv6;
8159
8160   S (mp);
8161   W (ret);
8162   return ret;
8163 }
8164
8165 static int
8166 api_l2_patch_add_del (vat_main_t * vam)
8167 {
8168   unformat_input_t *i = vam->input;
8169   vl_api_l2_patch_add_del_t *mp;
8170   u32 rx_sw_if_index;
8171   u8 rx_sw_if_index_set = 0;
8172   u32 tx_sw_if_index;
8173   u8 tx_sw_if_index_set = 0;
8174   u8 is_add = 1;
8175   int ret;
8176
8177   /* Parse args required to build the message */
8178   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8179     {
8180       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
8181         rx_sw_if_index_set = 1;
8182       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
8183         tx_sw_if_index_set = 1;
8184       else if (unformat (i, "rx"))
8185         {
8186           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8187             {
8188               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
8189                             &rx_sw_if_index))
8190                 rx_sw_if_index_set = 1;
8191             }
8192           else
8193             break;
8194         }
8195       else if (unformat (i, "tx"))
8196         {
8197           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8198             {
8199               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
8200                             &tx_sw_if_index))
8201                 tx_sw_if_index_set = 1;
8202             }
8203           else
8204             break;
8205         }
8206       else if (unformat (i, "del"))
8207         is_add = 0;
8208       else
8209         break;
8210     }
8211
8212   if (rx_sw_if_index_set == 0)
8213     {
8214       errmsg ("missing rx interface name or rx_sw_if_index");
8215       return -99;
8216     }
8217
8218   if (tx_sw_if_index_set == 0)
8219     {
8220       errmsg ("missing tx interface name or tx_sw_if_index");
8221       return -99;
8222     }
8223
8224   M (L2_PATCH_ADD_DEL, mp);
8225
8226   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
8227   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
8228   mp->is_add = is_add;
8229
8230   S (mp);
8231   W (ret);
8232   return ret;
8233 }
8234
8235 u8 is_del;
8236 u8 localsid_addr[16];
8237 u8 end_psp;
8238 u8 behavior;
8239 u32 sw_if_index;
8240 u32 vlan_index;
8241 u32 fib_table;
8242 u8 nh_addr[16];
8243
8244 static int
8245 api_sr_localsid_add_del (vat_main_t * vam)
8246 {
8247   unformat_input_t *i = vam->input;
8248   vl_api_sr_localsid_add_del_t *mp;
8249
8250   u8 is_del;
8251   ip6_address_t localsid;
8252   u8 end_psp = 0;
8253   u8 behavior = ~0;
8254   u32 sw_if_index;
8255   u32 fib_table = ~(u32) 0;
8256   ip6_address_t next_hop;
8257
8258   bool nexthop_set = 0;
8259
8260   int ret;
8261
8262   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8263     {
8264       if (unformat (i, "del"))
8265         is_del = 1;
8266       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
8267       else if (unformat (i, "next-hop %U", unformat_ip6_address, &next_hop))
8268         nexthop_set = 1;
8269       else if (unformat (i, "behavior %u", &behavior));
8270       else if (unformat (i, "sw_if_index %u", &sw_if_index));
8271       else if (unformat (i, "fib-table %u", &fib_table));
8272       else if (unformat (i, "end.psp %u", &behavior));
8273       else
8274         break;
8275     }
8276
8277   M (SR_LOCALSID_ADD_DEL, mp);
8278
8279   clib_memcpy (mp->localsid_addr, &localsid, sizeof (mp->localsid_addr));
8280   if (nexthop_set)
8281     clib_memcpy (mp->nh_addr, &next_hop, sizeof (mp->nh_addr));
8282   mp->behavior = behavior;
8283   mp->sw_if_index = ntohl (sw_if_index);
8284   mp->fib_table = ntohl (fib_table);
8285   mp->end_psp = end_psp;
8286   mp->is_del = is_del;
8287
8288   S (mp);
8289   W (ret);
8290   return ret;
8291 }
8292
8293 static int
8294 api_ioam_enable (vat_main_t * vam)
8295 {
8296   unformat_input_t *input = vam->input;
8297   vl_api_ioam_enable_t *mp;
8298   u32 id = 0;
8299   int has_trace_option = 0;
8300   int has_pot_option = 0;
8301   int has_seqno_option = 0;
8302   int has_analyse_option = 0;
8303   int ret;
8304
8305   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8306     {
8307       if (unformat (input, "trace"))
8308         has_trace_option = 1;
8309       else if (unformat (input, "pot"))
8310         has_pot_option = 1;
8311       else if (unformat (input, "seqno"))
8312         has_seqno_option = 1;
8313       else if (unformat (input, "analyse"))
8314         has_analyse_option = 1;
8315       else
8316         break;
8317     }
8318   M (IOAM_ENABLE, mp);
8319   mp->id = htons (id);
8320   mp->seqno = has_seqno_option;
8321   mp->analyse = has_analyse_option;
8322   mp->pot_enable = has_pot_option;
8323   mp->trace_enable = has_trace_option;
8324
8325   S (mp);
8326   W (ret);
8327   return ret;
8328 }
8329
8330
8331 static int
8332 api_ioam_disable (vat_main_t * vam)
8333 {
8334   vl_api_ioam_disable_t *mp;
8335   int ret;
8336
8337   M (IOAM_DISABLE, mp);
8338   S (mp);
8339   W (ret);
8340   return ret;
8341 }
8342
8343 #define foreach_tcp_proto_field                 \
8344 _(src_port)                                     \
8345 _(dst_port)
8346
8347 #define foreach_udp_proto_field                 \
8348 _(src_port)                                     \
8349 _(dst_port)
8350
8351 #define foreach_ip4_proto_field                 \
8352 _(src_address)                                  \
8353 _(dst_address)                                  \
8354 _(tos)                                          \
8355 _(length)                                       \
8356 _(fragment_id)                                  \
8357 _(ttl)                                          \
8358 _(protocol)                                     \
8359 _(checksum)
8360
8361 typedef struct
8362 {
8363   u16 src_port, dst_port;
8364 } tcpudp_header_t;
8365
8366 #if VPP_API_TEST_BUILTIN == 0
8367 uword
8368 unformat_tcp_mask (unformat_input_t * input, va_list * args)
8369 {
8370   u8 **maskp = va_arg (*args, u8 **);
8371   u8 *mask = 0;
8372   u8 found_something = 0;
8373   tcp_header_t *tcp;
8374
8375 #define _(a) u8 a=0;
8376   foreach_tcp_proto_field;
8377 #undef _
8378
8379   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8380     {
8381       if (0);
8382 #define _(a) else if (unformat (input, #a)) a=1;
8383       foreach_tcp_proto_field
8384 #undef _
8385         else
8386         break;
8387     }
8388
8389 #define _(a) found_something += a;
8390   foreach_tcp_proto_field;
8391 #undef _
8392
8393   if (found_something == 0)
8394     return 0;
8395
8396   vec_validate (mask, sizeof (*tcp) - 1);
8397
8398   tcp = (tcp_header_t *) mask;
8399
8400 #define _(a) if (a) memset (&tcp->a, 0xff, sizeof (tcp->a));
8401   foreach_tcp_proto_field;
8402 #undef _
8403
8404   *maskp = mask;
8405   return 1;
8406 }
8407
8408 uword
8409 unformat_udp_mask (unformat_input_t * input, va_list * args)
8410 {
8411   u8 **maskp = va_arg (*args, u8 **);
8412   u8 *mask = 0;
8413   u8 found_something = 0;
8414   udp_header_t *udp;
8415
8416 #define _(a) u8 a=0;
8417   foreach_udp_proto_field;
8418 #undef _
8419
8420   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8421     {
8422       if (0);
8423 #define _(a) else if (unformat (input, #a)) a=1;
8424       foreach_udp_proto_field
8425 #undef _
8426         else
8427         break;
8428     }
8429
8430 #define _(a) found_something += a;
8431   foreach_udp_proto_field;
8432 #undef _
8433
8434   if (found_something == 0)
8435     return 0;
8436
8437   vec_validate (mask, sizeof (*udp) - 1);
8438
8439   udp = (udp_header_t *) mask;
8440
8441 #define _(a) if (a) memset (&udp->a, 0xff, sizeof (udp->a));
8442   foreach_udp_proto_field;
8443 #undef _
8444
8445   *maskp = mask;
8446   return 1;
8447 }
8448
8449 uword
8450 unformat_l4_mask (unformat_input_t * input, va_list * args)
8451 {
8452   u8 **maskp = va_arg (*args, u8 **);
8453   u16 src_port = 0, dst_port = 0;
8454   tcpudp_header_t *tcpudp;
8455
8456   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8457     {
8458       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
8459         return 1;
8460       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
8461         return 1;
8462       else if (unformat (input, "src_port"))
8463         src_port = 0xFFFF;
8464       else if (unformat (input, "dst_port"))
8465         dst_port = 0xFFFF;
8466       else
8467         return 0;
8468     }
8469
8470   if (!src_port && !dst_port)
8471     return 0;
8472
8473   u8 *mask = 0;
8474   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
8475
8476   tcpudp = (tcpudp_header_t *) mask;
8477   tcpudp->src_port = src_port;
8478   tcpudp->dst_port = dst_port;
8479
8480   *maskp = mask;
8481
8482   return 1;
8483 }
8484
8485 uword
8486 unformat_ip4_mask (unformat_input_t * input, va_list * args)
8487 {
8488   u8 **maskp = va_arg (*args, u8 **);
8489   u8 *mask = 0;
8490   u8 found_something = 0;
8491   ip4_header_t *ip;
8492
8493 #define _(a) u8 a=0;
8494   foreach_ip4_proto_field;
8495 #undef _
8496   u8 version = 0;
8497   u8 hdr_length = 0;
8498
8499
8500   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8501     {
8502       if (unformat (input, "version"))
8503         version = 1;
8504       else if (unformat (input, "hdr_length"))
8505         hdr_length = 1;
8506       else if (unformat (input, "src"))
8507         src_address = 1;
8508       else if (unformat (input, "dst"))
8509         dst_address = 1;
8510       else if (unformat (input, "proto"))
8511         protocol = 1;
8512
8513 #define _(a) else if (unformat (input, #a)) a=1;
8514       foreach_ip4_proto_field
8515 #undef _
8516         else
8517         break;
8518     }
8519
8520 #define _(a) found_something += a;
8521   foreach_ip4_proto_field;
8522 #undef _
8523
8524   if (found_something == 0)
8525     return 0;
8526
8527   vec_validate (mask, sizeof (*ip) - 1);
8528
8529   ip = (ip4_header_t *) mask;
8530
8531 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
8532   foreach_ip4_proto_field;
8533 #undef _
8534
8535   ip->ip_version_and_header_length = 0;
8536
8537   if (version)
8538     ip->ip_version_and_header_length |= 0xF0;
8539
8540   if (hdr_length)
8541     ip->ip_version_and_header_length |= 0x0F;
8542
8543   *maskp = mask;
8544   return 1;
8545 }
8546
8547 #define foreach_ip6_proto_field                 \
8548 _(src_address)                                  \
8549 _(dst_address)                                  \
8550 _(payload_length)                               \
8551 _(hop_limit)                                    \
8552 _(protocol)
8553
8554 uword
8555 unformat_ip6_mask (unformat_input_t * input, va_list * args)
8556 {
8557   u8 **maskp = va_arg (*args, u8 **);
8558   u8 *mask = 0;
8559   u8 found_something = 0;
8560   ip6_header_t *ip;
8561   u32 ip_version_traffic_class_and_flow_label;
8562
8563 #define _(a) u8 a=0;
8564   foreach_ip6_proto_field;
8565 #undef _
8566   u8 version = 0;
8567   u8 traffic_class = 0;
8568   u8 flow_label = 0;
8569
8570   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8571     {
8572       if (unformat (input, "version"))
8573         version = 1;
8574       else if (unformat (input, "traffic-class"))
8575         traffic_class = 1;
8576       else if (unformat (input, "flow-label"))
8577         flow_label = 1;
8578       else if (unformat (input, "src"))
8579         src_address = 1;
8580       else if (unformat (input, "dst"))
8581         dst_address = 1;
8582       else if (unformat (input, "proto"))
8583         protocol = 1;
8584
8585 #define _(a) else if (unformat (input, #a)) a=1;
8586       foreach_ip6_proto_field
8587 #undef _
8588         else
8589         break;
8590     }
8591
8592 #define _(a) found_something += a;
8593   foreach_ip6_proto_field;
8594 #undef _
8595
8596   if (found_something == 0)
8597     return 0;
8598
8599   vec_validate (mask, sizeof (*ip) - 1);
8600
8601   ip = (ip6_header_t *) mask;
8602
8603 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
8604   foreach_ip6_proto_field;
8605 #undef _
8606
8607   ip_version_traffic_class_and_flow_label = 0;
8608
8609   if (version)
8610     ip_version_traffic_class_and_flow_label |= 0xF0000000;
8611
8612   if (traffic_class)
8613     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
8614
8615   if (flow_label)
8616     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
8617
8618   ip->ip_version_traffic_class_and_flow_label =
8619     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
8620
8621   *maskp = mask;
8622   return 1;
8623 }
8624
8625 uword
8626 unformat_l3_mask (unformat_input_t * input, va_list * args)
8627 {
8628   u8 **maskp = va_arg (*args, u8 **);
8629
8630   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8631     {
8632       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
8633         return 1;
8634       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
8635         return 1;
8636       else
8637         break;
8638     }
8639   return 0;
8640 }
8641
8642 uword
8643 unformat_l2_mask (unformat_input_t * input, va_list * args)
8644 {
8645   u8 **maskp = va_arg (*args, u8 **);
8646   u8 *mask = 0;
8647   u8 src = 0;
8648   u8 dst = 0;
8649   u8 proto = 0;
8650   u8 tag1 = 0;
8651   u8 tag2 = 0;
8652   u8 ignore_tag1 = 0;
8653   u8 ignore_tag2 = 0;
8654   u8 cos1 = 0;
8655   u8 cos2 = 0;
8656   u8 dot1q = 0;
8657   u8 dot1ad = 0;
8658   int len = 14;
8659
8660   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8661     {
8662       if (unformat (input, "src"))
8663         src = 1;
8664       else if (unformat (input, "dst"))
8665         dst = 1;
8666       else if (unformat (input, "proto"))
8667         proto = 1;
8668       else if (unformat (input, "tag1"))
8669         tag1 = 1;
8670       else if (unformat (input, "tag2"))
8671         tag2 = 1;
8672       else if (unformat (input, "ignore-tag1"))
8673         ignore_tag1 = 1;
8674       else if (unformat (input, "ignore-tag2"))
8675         ignore_tag2 = 1;
8676       else if (unformat (input, "cos1"))
8677         cos1 = 1;
8678       else if (unformat (input, "cos2"))
8679         cos2 = 1;
8680       else if (unformat (input, "dot1q"))
8681         dot1q = 1;
8682       else if (unformat (input, "dot1ad"))
8683         dot1ad = 1;
8684       else
8685         break;
8686     }
8687   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
8688        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
8689     return 0;
8690
8691   if (tag1 || ignore_tag1 || cos1 || dot1q)
8692     len = 18;
8693   if (tag2 || ignore_tag2 || cos2 || dot1ad)
8694     len = 22;
8695
8696   vec_validate (mask, len - 1);
8697
8698   if (dst)
8699     memset (mask, 0xff, 6);
8700
8701   if (src)
8702     memset (mask + 6, 0xff, 6);
8703
8704   if (tag2 || dot1ad)
8705     {
8706       /* inner vlan tag */
8707       if (tag2)
8708         {
8709           mask[19] = 0xff;
8710           mask[18] = 0x0f;
8711         }
8712       if (cos2)
8713         mask[18] |= 0xe0;
8714       if (proto)
8715         mask[21] = mask[20] = 0xff;
8716       if (tag1)
8717         {
8718           mask[15] = 0xff;
8719           mask[14] = 0x0f;
8720         }
8721       if (cos1)
8722         mask[14] |= 0xe0;
8723       *maskp = mask;
8724       return 1;
8725     }
8726   if (tag1 | dot1q)
8727     {
8728       if (tag1)
8729         {
8730           mask[15] = 0xff;
8731           mask[14] = 0x0f;
8732         }
8733       if (cos1)
8734         mask[14] |= 0xe0;
8735       if (proto)
8736         mask[16] = mask[17] = 0xff;
8737
8738       *maskp = mask;
8739       return 1;
8740     }
8741   if (cos2)
8742     mask[18] |= 0xe0;
8743   if (cos1)
8744     mask[14] |= 0xe0;
8745   if (proto)
8746     mask[12] = mask[13] = 0xff;
8747
8748   *maskp = mask;
8749   return 1;
8750 }
8751
8752 uword
8753 unformat_classify_mask (unformat_input_t * input, va_list * args)
8754 {
8755   u8 **maskp = va_arg (*args, u8 **);
8756   u32 *skipp = va_arg (*args, u32 *);
8757   u32 *matchp = va_arg (*args, u32 *);
8758   u32 match;
8759   u8 *mask = 0;
8760   u8 *l2 = 0;
8761   u8 *l3 = 0;
8762   u8 *l4 = 0;
8763   int i;
8764
8765   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8766     {
8767       if (unformat (input, "hex %U", unformat_hex_string, &mask))
8768         ;
8769       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
8770         ;
8771       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
8772         ;
8773       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
8774         ;
8775       else
8776         break;
8777     }
8778
8779   if (l4 && !l3)
8780     {
8781       vec_free (mask);
8782       vec_free (l2);
8783       vec_free (l4);
8784       return 0;
8785     }
8786
8787   if (mask || l2 || l3 || l4)
8788     {
8789       if (l2 || l3 || l4)
8790         {
8791           /* "With a free Ethernet header in every package" */
8792           if (l2 == 0)
8793             vec_validate (l2, 13);
8794           mask = l2;
8795           if (vec_len (l3))
8796             {
8797               vec_append (mask, l3);
8798               vec_free (l3);
8799             }
8800           if (vec_len (l4))
8801             {
8802               vec_append (mask, l4);
8803               vec_free (l4);
8804             }
8805         }
8806
8807       /* Scan forward looking for the first significant mask octet */
8808       for (i = 0; i < vec_len (mask); i++)
8809         if (mask[i])
8810           break;
8811
8812       /* compute (skip, match) params */
8813       *skipp = i / sizeof (u32x4);
8814       vec_delete (mask, *skipp * sizeof (u32x4), 0);
8815
8816       /* Pad mask to an even multiple of the vector size */
8817       while (vec_len (mask) % sizeof (u32x4))
8818         vec_add1 (mask, 0);
8819
8820       match = vec_len (mask) / sizeof (u32x4);
8821
8822       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
8823         {
8824           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
8825           if (*tmp || *(tmp + 1))
8826             break;
8827           match--;
8828         }
8829       if (match == 0)
8830         clib_warning ("BUG: match 0");
8831
8832       _vec_len (mask) = match * sizeof (u32x4);
8833
8834       *matchp = match;
8835       *maskp = mask;
8836
8837       return 1;
8838     }
8839
8840   return 0;
8841 }
8842 #endif /* VPP_API_TEST_BUILTIN */
8843
8844 #define foreach_l2_next                         \
8845 _(drop, DROP)                                   \
8846 _(ethernet, ETHERNET_INPUT)                     \
8847 _(ip4, IP4_INPUT)                               \
8848 _(ip6, IP6_INPUT)
8849
8850 uword
8851 unformat_l2_next_index (unformat_input_t * input, va_list * args)
8852 {
8853   u32 *miss_next_indexp = va_arg (*args, u32 *);
8854   u32 next_index = 0;
8855   u32 tmp;
8856
8857 #define _(n,N) \
8858   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
8859   foreach_l2_next;
8860 #undef _
8861
8862   if (unformat (input, "%d", &tmp))
8863     {
8864       next_index = tmp;
8865       goto out;
8866     }
8867
8868   return 0;
8869
8870 out:
8871   *miss_next_indexp = next_index;
8872   return 1;
8873 }
8874
8875 #define foreach_ip_next                         \
8876 _(drop, DROP)                                   \
8877 _(local, LOCAL)                                 \
8878 _(rewrite, REWRITE)
8879
8880 uword
8881 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
8882 {
8883   u32 *miss_next_indexp = va_arg (*args, u32 *);
8884   u32 next_index = 0;
8885   u32 tmp;
8886
8887 #define _(n,N) \
8888   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
8889   foreach_ip_next;
8890 #undef _
8891
8892   if (unformat (input, "%d", &tmp))
8893     {
8894       next_index = tmp;
8895       goto out;
8896     }
8897
8898   return 0;
8899
8900 out:
8901   *miss_next_indexp = next_index;
8902   return 1;
8903 }
8904
8905 #define foreach_acl_next                        \
8906 _(deny, DENY)
8907
8908 uword
8909 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
8910 {
8911   u32 *miss_next_indexp = va_arg (*args, u32 *);
8912   u32 next_index = 0;
8913   u32 tmp;
8914
8915 #define _(n,N) \
8916   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
8917   foreach_acl_next;
8918 #undef _
8919
8920   if (unformat (input, "permit"))
8921     {
8922       next_index = ~0;
8923       goto out;
8924     }
8925   else if (unformat (input, "%d", &tmp))
8926     {
8927       next_index = tmp;
8928       goto out;
8929     }
8930
8931   return 0;
8932
8933 out:
8934   *miss_next_indexp = next_index;
8935   return 1;
8936 }
8937
8938 uword
8939 unformat_policer_precolor (unformat_input_t * input, va_list * args)
8940 {
8941   u32 *r = va_arg (*args, u32 *);
8942
8943   if (unformat (input, "conform-color"))
8944     *r = POLICE_CONFORM;
8945   else if (unformat (input, "exceed-color"))
8946     *r = POLICE_EXCEED;
8947   else
8948     return 0;
8949
8950   return 1;
8951 }
8952
8953 static int
8954 api_classify_add_del_table (vat_main_t * vam)
8955 {
8956   unformat_input_t *i = vam->input;
8957   vl_api_classify_add_del_table_t *mp;
8958
8959   u32 nbuckets = 2;
8960   u32 skip = ~0;
8961   u32 match = ~0;
8962   int is_add = 1;
8963   int del_chain = 0;
8964   u32 table_index = ~0;
8965   u32 next_table_index = ~0;
8966   u32 miss_next_index = ~0;
8967   u32 memory_size = 32 << 20;
8968   u8 *mask = 0;
8969   u32 current_data_flag = 0;
8970   int current_data_offset = 0;
8971   int ret;
8972
8973   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8974     {
8975       if (unformat (i, "del"))
8976         is_add = 0;
8977       else if (unformat (i, "del-chain"))
8978         {
8979           is_add = 0;
8980           del_chain = 1;
8981         }
8982       else if (unformat (i, "buckets %d", &nbuckets))
8983         ;
8984       else if (unformat (i, "memory_size %d", &memory_size))
8985         ;
8986       else if (unformat (i, "skip %d", &skip))
8987         ;
8988       else if (unformat (i, "match %d", &match))
8989         ;
8990       else if (unformat (i, "table %d", &table_index))
8991         ;
8992       else if (unformat (i, "mask %U", unformat_classify_mask,
8993                          &mask, &skip, &match))
8994         ;
8995       else if (unformat (i, "next-table %d", &next_table_index))
8996         ;
8997       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
8998                          &miss_next_index))
8999         ;
9000       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
9001                          &miss_next_index))
9002         ;
9003       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
9004                          &miss_next_index))
9005         ;
9006       else if (unformat (i, "current-data-flag %d", &current_data_flag))
9007         ;
9008       else if (unformat (i, "current-data-offset %d", &current_data_offset))
9009         ;
9010       else
9011         break;
9012     }
9013
9014   if (is_add && mask == 0)
9015     {
9016       errmsg ("Mask required");
9017       return -99;
9018     }
9019
9020   if (is_add && skip == ~0)
9021     {
9022       errmsg ("skip count required");
9023       return -99;
9024     }
9025
9026   if (is_add && match == ~0)
9027     {
9028       errmsg ("match count required");
9029       return -99;
9030     }
9031
9032   if (!is_add && table_index == ~0)
9033     {
9034       errmsg ("table index required for delete");
9035       return -99;
9036     }
9037
9038   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
9039
9040   mp->is_add = is_add;
9041   mp->del_chain = del_chain;
9042   mp->table_index = ntohl (table_index);
9043   mp->nbuckets = ntohl (nbuckets);
9044   mp->memory_size = ntohl (memory_size);
9045   mp->skip_n_vectors = ntohl (skip);
9046   mp->match_n_vectors = ntohl (match);
9047   mp->next_table_index = ntohl (next_table_index);
9048   mp->miss_next_index = ntohl (miss_next_index);
9049   mp->current_data_flag = ntohl (current_data_flag);
9050   mp->current_data_offset = ntohl (current_data_offset);
9051   clib_memcpy (mp->mask, mask, vec_len (mask));
9052
9053   vec_free (mask);
9054
9055   S (mp);
9056   W (ret);
9057   return ret;
9058 }
9059
9060 #if VPP_API_TEST_BUILTIN == 0
9061 uword
9062 unformat_l4_match (unformat_input_t * input, va_list * args)
9063 {
9064   u8 **matchp = va_arg (*args, u8 **);
9065
9066   u8 *proto_header = 0;
9067   int src_port = 0;
9068   int dst_port = 0;
9069
9070   tcpudp_header_t h;
9071
9072   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9073     {
9074       if (unformat (input, "src_port %d", &src_port))
9075         ;
9076       else if (unformat (input, "dst_port %d", &dst_port))
9077         ;
9078       else
9079         return 0;
9080     }
9081
9082   h.src_port = clib_host_to_net_u16 (src_port);
9083   h.dst_port = clib_host_to_net_u16 (dst_port);
9084   vec_validate (proto_header, sizeof (h) - 1);
9085   memcpy (proto_header, &h, sizeof (h));
9086
9087   *matchp = proto_header;
9088
9089   return 1;
9090 }
9091
9092 uword
9093 unformat_ip4_match (unformat_input_t * input, va_list * args)
9094 {
9095   u8 **matchp = va_arg (*args, u8 **);
9096   u8 *match = 0;
9097   ip4_header_t *ip;
9098   int version = 0;
9099   u32 version_val;
9100   int hdr_length = 0;
9101   u32 hdr_length_val;
9102   int src = 0, dst = 0;
9103   ip4_address_t src_val, dst_val;
9104   int proto = 0;
9105   u32 proto_val;
9106   int tos = 0;
9107   u32 tos_val;
9108   int length = 0;
9109   u32 length_val;
9110   int fragment_id = 0;
9111   u32 fragment_id_val;
9112   int ttl = 0;
9113   int ttl_val;
9114   int checksum = 0;
9115   u32 checksum_val;
9116
9117   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9118     {
9119       if (unformat (input, "version %d", &version_val))
9120         version = 1;
9121       else if (unformat (input, "hdr_length %d", &hdr_length_val))
9122         hdr_length = 1;
9123       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
9124         src = 1;
9125       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
9126         dst = 1;
9127       else if (unformat (input, "proto %d", &proto_val))
9128         proto = 1;
9129       else if (unformat (input, "tos %d", &tos_val))
9130         tos = 1;
9131       else if (unformat (input, "length %d", &length_val))
9132         length = 1;
9133       else if (unformat (input, "fragment_id %d", &fragment_id_val))
9134         fragment_id = 1;
9135       else if (unformat (input, "ttl %d", &ttl_val))
9136         ttl = 1;
9137       else if (unformat (input, "checksum %d", &checksum_val))
9138         checksum = 1;
9139       else
9140         break;
9141     }
9142
9143   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
9144       + ttl + checksum == 0)
9145     return 0;
9146
9147   /*
9148    * Aligned because we use the real comparison functions
9149    */
9150   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
9151
9152   ip = (ip4_header_t *) match;
9153
9154   /* These are realistically matched in practice */
9155   if (src)
9156     ip->src_address.as_u32 = src_val.as_u32;
9157
9158   if (dst)
9159     ip->dst_address.as_u32 = dst_val.as_u32;
9160
9161   if (proto)
9162     ip->protocol = proto_val;
9163
9164
9165   /* These are not, but they're included for completeness */
9166   if (version)
9167     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
9168
9169   if (hdr_length)
9170     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
9171
9172   if (tos)
9173     ip->tos = tos_val;
9174
9175   if (length)
9176     ip->length = clib_host_to_net_u16 (length_val);
9177
9178   if (ttl)
9179     ip->ttl = ttl_val;
9180
9181   if (checksum)
9182     ip->checksum = clib_host_to_net_u16 (checksum_val);
9183
9184   *matchp = match;
9185   return 1;
9186 }
9187
9188 uword
9189 unformat_ip6_match (unformat_input_t * input, va_list * args)
9190 {
9191   u8 **matchp = va_arg (*args, u8 **);
9192   u8 *match = 0;
9193   ip6_header_t *ip;
9194   int version = 0;
9195   u32 version_val;
9196   u8 traffic_class = 0;
9197   u32 traffic_class_val = 0;
9198   u8 flow_label = 0;
9199   u8 flow_label_val;
9200   int src = 0, dst = 0;
9201   ip6_address_t src_val, dst_val;
9202   int proto = 0;
9203   u32 proto_val;
9204   int payload_length = 0;
9205   u32 payload_length_val;
9206   int hop_limit = 0;
9207   int hop_limit_val;
9208   u32 ip_version_traffic_class_and_flow_label;
9209
9210   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9211     {
9212       if (unformat (input, "version %d", &version_val))
9213         version = 1;
9214       else if (unformat (input, "traffic_class %d", &traffic_class_val))
9215         traffic_class = 1;
9216       else if (unformat (input, "flow_label %d", &flow_label_val))
9217         flow_label = 1;
9218       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
9219         src = 1;
9220       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
9221         dst = 1;
9222       else if (unformat (input, "proto %d", &proto_val))
9223         proto = 1;
9224       else if (unformat (input, "payload_length %d", &payload_length_val))
9225         payload_length = 1;
9226       else if (unformat (input, "hop_limit %d", &hop_limit_val))
9227         hop_limit = 1;
9228       else
9229         break;
9230     }
9231
9232   if (version + traffic_class + flow_label + src + dst + proto +
9233       payload_length + hop_limit == 0)
9234     return 0;
9235
9236   /*
9237    * Aligned because we use the real comparison functions
9238    */
9239   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
9240
9241   ip = (ip6_header_t *) match;
9242
9243   if (src)
9244     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
9245
9246   if (dst)
9247     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
9248
9249   if (proto)
9250     ip->protocol = proto_val;
9251
9252   ip_version_traffic_class_and_flow_label = 0;
9253
9254   if (version)
9255     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
9256
9257   if (traffic_class)
9258     ip_version_traffic_class_and_flow_label |=
9259       (traffic_class_val & 0xFF) << 20;
9260
9261   if (flow_label)
9262     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
9263
9264   ip->ip_version_traffic_class_and_flow_label =
9265     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
9266
9267   if (payload_length)
9268     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
9269
9270   if (hop_limit)
9271     ip->hop_limit = hop_limit_val;
9272
9273   *matchp = match;
9274   return 1;
9275 }
9276
9277 uword
9278 unformat_l3_match (unformat_input_t * input, va_list * args)
9279 {
9280   u8 **matchp = va_arg (*args, u8 **);
9281
9282   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9283     {
9284       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
9285         return 1;
9286       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
9287         return 1;
9288       else
9289         break;
9290     }
9291   return 0;
9292 }
9293
9294 uword
9295 unformat_vlan_tag (unformat_input_t * input, va_list * args)
9296 {
9297   u8 *tagp = va_arg (*args, u8 *);
9298   u32 tag;
9299
9300   if (unformat (input, "%d", &tag))
9301     {
9302       tagp[0] = (tag >> 8) & 0x0F;
9303       tagp[1] = tag & 0xFF;
9304       return 1;
9305     }
9306
9307   return 0;
9308 }
9309
9310 uword
9311 unformat_l2_match (unformat_input_t * input, va_list * args)
9312 {
9313   u8 **matchp = va_arg (*args, u8 **);
9314   u8 *match = 0;
9315   u8 src = 0;
9316   u8 src_val[6];
9317   u8 dst = 0;
9318   u8 dst_val[6];
9319   u8 proto = 0;
9320   u16 proto_val;
9321   u8 tag1 = 0;
9322   u8 tag1_val[2];
9323   u8 tag2 = 0;
9324   u8 tag2_val[2];
9325   int len = 14;
9326   u8 ignore_tag1 = 0;
9327   u8 ignore_tag2 = 0;
9328   u8 cos1 = 0;
9329   u8 cos2 = 0;
9330   u32 cos1_val = 0;
9331   u32 cos2_val = 0;
9332
9333   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9334     {
9335       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
9336         src = 1;
9337       else
9338         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
9339         dst = 1;
9340       else if (unformat (input, "proto %U",
9341                          unformat_ethernet_type_host_byte_order, &proto_val))
9342         proto = 1;
9343       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
9344         tag1 = 1;
9345       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
9346         tag2 = 1;
9347       else if (unformat (input, "ignore-tag1"))
9348         ignore_tag1 = 1;
9349       else if (unformat (input, "ignore-tag2"))
9350         ignore_tag2 = 1;
9351       else if (unformat (input, "cos1 %d", &cos1_val))
9352         cos1 = 1;
9353       else if (unformat (input, "cos2 %d", &cos2_val))
9354         cos2 = 1;
9355       else
9356         break;
9357     }
9358   if ((src + dst + proto + tag1 + tag2 +
9359        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
9360     return 0;
9361
9362   if (tag1 || ignore_tag1 || cos1)
9363     len = 18;
9364   if (tag2 || ignore_tag2 || cos2)
9365     len = 22;
9366
9367   vec_validate_aligned (match, len - 1, sizeof (u32x4));
9368
9369   if (dst)
9370     clib_memcpy (match, dst_val, 6);
9371
9372   if (src)
9373     clib_memcpy (match + 6, src_val, 6);
9374
9375   if (tag2)
9376     {
9377       /* inner vlan tag */
9378       match[19] = tag2_val[1];
9379       match[18] = tag2_val[0];
9380       if (cos2)
9381         match[18] |= (cos2_val & 0x7) << 5;
9382       if (proto)
9383         {
9384           match[21] = proto_val & 0xff;
9385           match[20] = proto_val >> 8;
9386         }
9387       if (tag1)
9388         {
9389           match[15] = tag1_val[1];
9390           match[14] = tag1_val[0];
9391         }
9392       if (cos1)
9393         match[14] |= (cos1_val & 0x7) << 5;
9394       *matchp = match;
9395       return 1;
9396     }
9397   if (tag1)
9398     {
9399       match[15] = tag1_val[1];
9400       match[14] = tag1_val[0];
9401       if (proto)
9402         {
9403           match[17] = proto_val & 0xff;
9404           match[16] = proto_val >> 8;
9405         }
9406       if (cos1)
9407         match[14] |= (cos1_val & 0x7) << 5;
9408
9409       *matchp = match;
9410       return 1;
9411     }
9412   if (cos2)
9413     match[18] |= (cos2_val & 0x7) << 5;
9414   if (cos1)
9415     match[14] |= (cos1_val & 0x7) << 5;
9416   if (proto)
9417     {
9418       match[13] = proto_val & 0xff;
9419       match[12] = proto_val >> 8;
9420     }
9421
9422   *matchp = match;
9423   return 1;
9424 }
9425 #endif
9426
9427 uword
9428 api_unformat_classify_match (unformat_input_t * input, va_list * args)
9429 {
9430   u8 **matchp = va_arg (*args, u8 **);
9431   u32 skip_n_vectors = va_arg (*args, u32);
9432   u32 match_n_vectors = va_arg (*args, u32);
9433
9434   u8 *match = 0;
9435   u8 *l2 = 0;
9436   u8 *l3 = 0;
9437   u8 *l4 = 0;
9438
9439   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9440     {
9441       if (unformat (input, "hex %U", unformat_hex_string, &match))
9442         ;
9443       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
9444         ;
9445       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
9446         ;
9447       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
9448         ;
9449       else
9450         break;
9451     }
9452
9453   if (l4 && !l3)
9454     {
9455       vec_free (match);
9456       vec_free (l2);
9457       vec_free (l4);
9458       return 0;
9459     }
9460
9461   if (match || l2 || l3 || l4)
9462     {
9463       if (l2 || l3 || l4)
9464         {
9465           /* "Win a free Ethernet header in every packet" */
9466           if (l2 == 0)
9467             vec_validate_aligned (l2, 13, sizeof (u32x4));
9468           match = l2;
9469           if (vec_len (l3))
9470             {
9471               vec_append_aligned (match, l3, sizeof (u32x4));
9472               vec_free (l3);
9473             }
9474           if (vec_len (l4))
9475             {
9476               vec_append_aligned (match, l4, sizeof (u32x4));
9477               vec_free (l4);
9478             }
9479         }
9480
9481       /* Make sure the vector is big enough even if key is all 0's */
9482       vec_validate_aligned
9483         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
9484          sizeof (u32x4));
9485
9486       /* Set size, include skipped vectors */
9487       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
9488
9489       *matchp = match;
9490
9491       return 1;
9492     }
9493
9494   return 0;
9495 }
9496
9497 static int
9498 api_classify_add_del_session (vat_main_t * vam)
9499 {
9500   unformat_input_t *i = vam->input;
9501   vl_api_classify_add_del_session_t *mp;
9502   int is_add = 1;
9503   u32 table_index = ~0;
9504   u32 hit_next_index = ~0;
9505   u32 opaque_index = ~0;
9506   u8 *match = 0;
9507   i32 advance = 0;
9508   u32 skip_n_vectors = 0;
9509   u32 match_n_vectors = 0;
9510   u32 action = 0;
9511   u32 metadata = 0;
9512   int ret;
9513
9514   /*
9515    * Warning: you have to supply skip_n and match_n
9516    * because the API client cant simply look at the classify
9517    * table object.
9518    */
9519
9520   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9521     {
9522       if (unformat (i, "del"))
9523         is_add = 0;
9524       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
9525                          &hit_next_index))
9526         ;
9527       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
9528                          &hit_next_index))
9529         ;
9530       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
9531                          &hit_next_index))
9532         ;
9533       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
9534         ;
9535       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
9536         ;
9537       else if (unformat (i, "opaque-index %d", &opaque_index))
9538         ;
9539       else if (unformat (i, "skip_n %d", &skip_n_vectors))
9540         ;
9541       else if (unformat (i, "match_n %d", &match_n_vectors))
9542         ;
9543       else if (unformat (i, "match %U", api_unformat_classify_match,
9544                          &match, skip_n_vectors, match_n_vectors))
9545         ;
9546       else if (unformat (i, "advance %d", &advance))
9547         ;
9548       else if (unformat (i, "table-index %d", &table_index))
9549         ;
9550       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
9551         action = 1;
9552       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
9553         action = 2;
9554       else if (unformat (i, "action %d", &action))
9555         ;
9556       else if (unformat (i, "metadata %d", &metadata))
9557         ;
9558       else
9559         break;
9560     }
9561
9562   if (table_index == ~0)
9563     {
9564       errmsg ("Table index required");
9565       return -99;
9566     }
9567
9568   if (is_add && match == 0)
9569     {
9570       errmsg ("Match value required");
9571       return -99;
9572     }
9573
9574   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
9575
9576   mp->is_add = is_add;
9577   mp->table_index = ntohl (table_index);
9578   mp->hit_next_index = ntohl (hit_next_index);
9579   mp->opaque_index = ntohl (opaque_index);
9580   mp->advance = ntohl (advance);
9581   mp->action = action;
9582   mp->metadata = ntohl (metadata);
9583   clib_memcpy (mp->match, match, vec_len (match));
9584   vec_free (match);
9585
9586   S (mp);
9587   W (ret);
9588   return ret;
9589 }
9590
9591 static int
9592 api_classify_set_interface_ip_table (vat_main_t * vam)
9593 {
9594   unformat_input_t *i = vam->input;
9595   vl_api_classify_set_interface_ip_table_t *mp;
9596   u32 sw_if_index;
9597   int sw_if_index_set;
9598   u32 table_index = ~0;
9599   u8 is_ipv6 = 0;
9600   int ret;
9601
9602   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9603     {
9604       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9605         sw_if_index_set = 1;
9606       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9607         sw_if_index_set = 1;
9608       else if (unformat (i, "table %d", &table_index))
9609         ;
9610       else
9611         {
9612           clib_warning ("parse error '%U'", format_unformat_error, i);
9613           return -99;
9614         }
9615     }
9616
9617   if (sw_if_index_set == 0)
9618     {
9619       errmsg ("missing interface name or sw_if_index");
9620       return -99;
9621     }
9622
9623
9624   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
9625
9626   mp->sw_if_index = ntohl (sw_if_index);
9627   mp->table_index = ntohl (table_index);
9628   mp->is_ipv6 = is_ipv6;
9629
9630   S (mp);
9631   W (ret);
9632   return ret;
9633 }
9634
9635 static int
9636 api_classify_set_interface_l2_tables (vat_main_t * vam)
9637 {
9638   unformat_input_t *i = vam->input;
9639   vl_api_classify_set_interface_l2_tables_t *mp;
9640   u32 sw_if_index;
9641   int sw_if_index_set;
9642   u32 ip4_table_index = ~0;
9643   u32 ip6_table_index = ~0;
9644   u32 other_table_index = ~0;
9645   u32 is_input = 1;
9646   int ret;
9647
9648   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9649     {
9650       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9651         sw_if_index_set = 1;
9652       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9653         sw_if_index_set = 1;
9654       else if (unformat (i, "ip4-table %d", &ip4_table_index))
9655         ;
9656       else if (unformat (i, "ip6-table %d", &ip6_table_index))
9657         ;
9658       else if (unformat (i, "other-table %d", &other_table_index))
9659         ;
9660       else if (unformat (i, "is-input %d", &is_input))
9661         ;
9662       else
9663         {
9664           clib_warning ("parse error '%U'", format_unformat_error, i);
9665           return -99;
9666         }
9667     }
9668
9669   if (sw_if_index_set == 0)
9670     {
9671       errmsg ("missing interface name or sw_if_index");
9672       return -99;
9673     }
9674
9675
9676   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
9677
9678   mp->sw_if_index = ntohl (sw_if_index);
9679   mp->ip4_table_index = ntohl (ip4_table_index);
9680   mp->ip6_table_index = ntohl (ip6_table_index);
9681   mp->other_table_index = ntohl (other_table_index);
9682   mp->is_input = (u8) is_input;
9683
9684   S (mp);
9685   W (ret);
9686   return ret;
9687 }
9688
9689 static int
9690 api_set_ipfix_exporter (vat_main_t * vam)
9691 {
9692   unformat_input_t *i = vam->input;
9693   vl_api_set_ipfix_exporter_t *mp;
9694   ip4_address_t collector_address;
9695   u8 collector_address_set = 0;
9696   u32 collector_port = ~0;
9697   ip4_address_t src_address;
9698   u8 src_address_set = 0;
9699   u32 vrf_id = ~0;
9700   u32 path_mtu = ~0;
9701   u32 template_interval = ~0;
9702   u8 udp_checksum = 0;
9703   int ret;
9704
9705   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9706     {
9707       if (unformat (i, "collector_address %U", unformat_ip4_address,
9708                     &collector_address))
9709         collector_address_set = 1;
9710       else if (unformat (i, "collector_port %d", &collector_port))
9711         ;
9712       else if (unformat (i, "src_address %U", unformat_ip4_address,
9713                          &src_address))
9714         src_address_set = 1;
9715       else if (unformat (i, "vrf_id %d", &vrf_id))
9716         ;
9717       else if (unformat (i, "path_mtu %d", &path_mtu))
9718         ;
9719       else if (unformat (i, "template_interval %d", &template_interval))
9720         ;
9721       else if (unformat (i, "udp_checksum"))
9722         udp_checksum = 1;
9723       else
9724         break;
9725     }
9726
9727   if (collector_address_set == 0)
9728     {
9729       errmsg ("collector_address required");
9730       return -99;
9731     }
9732
9733   if (src_address_set == 0)
9734     {
9735       errmsg ("src_address required");
9736       return -99;
9737     }
9738
9739   M (SET_IPFIX_EXPORTER, mp);
9740
9741   memcpy (mp->collector_address, collector_address.data,
9742           sizeof (collector_address.data));
9743   mp->collector_port = htons ((u16) collector_port);
9744   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
9745   mp->vrf_id = htonl (vrf_id);
9746   mp->path_mtu = htonl (path_mtu);
9747   mp->template_interval = htonl (template_interval);
9748   mp->udp_checksum = udp_checksum;
9749
9750   S (mp);
9751   W (ret);
9752   return ret;
9753 }
9754
9755 static int
9756 api_set_ipfix_classify_stream (vat_main_t * vam)
9757 {
9758   unformat_input_t *i = vam->input;
9759   vl_api_set_ipfix_classify_stream_t *mp;
9760   u32 domain_id = 0;
9761   u32 src_port = UDP_DST_PORT_ipfix;
9762   int ret;
9763
9764   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9765     {
9766       if (unformat (i, "domain %d", &domain_id))
9767         ;
9768       else if (unformat (i, "src_port %d", &src_port))
9769         ;
9770       else
9771         {
9772           errmsg ("unknown input `%U'", format_unformat_error, i);
9773           return -99;
9774         }
9775     }
9776
9777   M (SET_IPFIX_CLASSIFY_STREAM, mp);
9778
9779   mp->domain_id = htonl (domain_id);
9780   mp->src_port = htons ((u16) src_port);
9781
9782   S (mp);
9783   W (ret);
9784   return ret;
9785 }
9786
9787 static int
9788 api_ipfix_classify_table_add_del (vat_main_t * vam)
9789 {
9790   unformat_input_t *i = vam->input;
9791   vl_api_ipfix_classify_table_add_del_t *mp;
9792   int is_add = -1;
9793   u32 classify_table_index = ~0;
9794   u8 ip_version = 0;
9795   u8 transport_protocol = 255;
9796   int ret;
9797
9798   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9799     {
9800       if (unformat (i, "add"))
9801         is_add = 1;
9802       else if (unformat (i, "del"))
9803         is_add = 0;
9804       else if (unformat (i, "table %d", &classify_table_index))
9805         ;
9806       else if (unformat (i, "ip4"))
9807         ip_version = 4;
9808       else if (unformat (i, "ip6"))
9809         ip_version = 6;
9810       else if (unformat (i, "tcp"))
9811         transport_protocol = 6;
9812       else if (unformat (i, "udp"))
9813         transport_protocol = 17;
9814       else
9815         {
9816           errmsg ("unknown input `%U'", format_unformat_error, i);
9817           return -99;
9818         }
9819     }
9820
9821   if (is_add == -1)
9822     {
9823       errmsg ("expecting: add|del");
9824       return -99;
9825     }
9826   if (classify_table_index == ~0)
9827     {
9828       errmsg ("classifier table not specified");
9829       return -99;
9830     }
9831   if (ip_version == 0)
9832     {
9833       errmsg ("IP version not specified");
9834       return -99;
9835     }
9836
9837   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
9838
9839   mp->is_add = is_add;
9840   mp->table_id = htonl (classify_table_index);
9841   mp->ip_version = ip_version;
9842   mp->transport_protocol = transport_protocol;
9843
9844   S (mp);
9845   W (ret);
9846   return ret;
9847 }
9848
9849 static int
9850 api_get_node_index (vat_main_t * vam)
9851 {
9852   unformat_input_t *i = vam->input;
9853   vl_api_get_node_index_t *mp;
9854   u8 *name = 0;
9855   int ret;
9856
9857   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9858     {
9859       if (unformat (i, "node %s", &name))
9860         ;
9861       else
9862         break;
9863     }
9864   if (name == 0)
9865     {
9866       errmsg ("node name required");
9867       return -99;
9868     }
9869   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
9870     {
9871       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
9872       return -99;
9873     }
9874
9875   M (GET_NODE_INDEX, mp);
9876   clib_memcpy (mp->node_name, name, vec_len (name));
9877   vec_free (name);
9878
9879   S (mp);
9880   W (ret);
9881   return ret;
9882 }
9883
9884 static int
9885 api_get_next_index (vat_main_t * vam)
9886 {
9887   unformat_input_t *i = vam->input;
9888   vl_api_get_next_index_t *mp;
9889   u8 *node_name = 0, *next_node_name = 0;
9890   int ret;
9891
9892   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9893     {
9894       if (unformat (i, "node-name %s", &node_name))
9895         ;
9896       else if (unformat (i, "next-node-name %s", &next_node_name))
9897         break;
9898     }
9899
9900   if (node_name == 0)
9901     {
9902       errmsg ("node name required");
9903       return -99;
9904     }
9905   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
9906     {
9907       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
9908       return -99;
9909     }
9910
9911   if (next_node_name == 0)
9912     {
9913       errmsg ("next node name required");
9914       return -99;
9915     }
9916   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
9917     {
9918       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
9919       return -99;
9920     }
9921
9922   M (GET_NEXT_INDEX, mp);
9923   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
9924   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
9925   vec_free (node_name);
9926   vec_free (next_node_name);
9927
9928   S (mp);
9929   W (ret);
9930   return ret;
9931 }
9932
9933 static int
9934 api_add_node_next (vat_main_t * vam)
9935 {
9936   unformat_input_t *i = vam->input;
9937   vl_api_add_node_next_t *mp;
9938   u8 *name = 0;
9939   u8 *next = 0;
9940   int ret;
9941
9942   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9943     {
9944       if (unformat (i, "node %s", &name))
9945         ;
9946       else if (unformat (i, "next %s", &next))
9947         ;
9948       else
9949         break;
9950     }
9951   if (name == 0)
9952     {
9953       errmsg ("node name required");
9954       return -99;
9955     }
9956   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
9957     {
9958       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
9959       return -99;
9960     }
9961   if (next == 0)
9962     {
9963       errmsg ("next node required");
9964       return -99;
9965     }
9966   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
9967     {
9968       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
9969       return -99;
9970     }
9971
9972   M (ADD_NODE_NEXT, mp);
9973   clib_memcpy (mp->node_name, name, vec_len (name));
9974   clib_memcpy (mp->next_name, next, vec_len (next));
9975   vec_free (name);
9976   vec_free (next);
9977
9978   S (mp);
9979   W (ret);
9980   return ret;
9981 }
9982
9983 static int
9984 api_l2tpv3_create_tunnel (vat_main_t * vam)
9985 {
9986   unformat_input_t *i = vam->input;
9987   ip6_address_t client_address, our_address;
9988   int client_address_set = 0;
9989   int our_address_set = 0;
9990   u32 local_session_id = 0;
9991   u32 remote_session_id = 0;
9992   u64 local_cookie = 0;
9993   u64 remote_cookie = 0;
9994   u8 l2_sublayer_present = 0;
9995   vl_api_l2tpv3_create_tunnel_t *mp;
9996   int ret;
9997
9998   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9999     {
10000       if (unformat (i, "client_address %U", unformat_ip6_address,
10001                     &client_address))
10002         client_address_set = 1;
10003       else if (unformat (i, "our_address %U", unformat_ip6_address,
10004                          &our_address))
10005         our_address_set = 1;
10006       else if (unformat (i, "local_session_id %d", &local_session_id))
10007         ;
10008       else if (unformat (i, "remote_session_id %d", &remote_session_id))
10009         ;
10010       else if (unformat (i, "local_cookie %lld", &local_cookie))
10011         ;
10012       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
10013         ;
10014       else if (unformat (i, "l2-sublayer-present"))
10015         l2_sublayer_present = 1;
10016       else
10017         break;
10018     }
10019
10020   if (client_address_set == 0)
10021     {
10022       errmsg ("client_address required");
10023       return -99;
10024     }
10025
10026   if (our_address_set == 0)
10027     {
10028       errmsg ("our_address required");
10029       return -99;
10030     }
10031
10032   M (L2TPV3_CREATE_TUNNEL, mp);
10033
10034   clib_memcpy (mp->client_address, client_address.as_u8,
10035                sizeof (mp->client_address));
10036
10037   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
10038
10039   mp->local_session_id = ntohl (local_session_id);
10040   mp->remote_session_id = ntohl (remote_session_id);
10041   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
10042   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
10043   mp->l2_sublayer_present = l2_sublayer_present;
10044   mp->is_ipv6 = 1;
10045
10046   S (mp);
10047   W (ret);
10048   return ret;
10049 }
10050
10051 static int
10052 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
10053 {
10054   unformat_input_t *i = vam->input;
10055   u32 sw_if_index;
10056   u8 sw_if_index_set = 0;
10057   u64 new_local_cookie = 0;
10058   u64 new_remote_cookie = 0;
10059   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
10060   int ret;
10061
10062   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10063     {
10064       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10065         sw_if_index_set = 1;
10066       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10067         sw_if_index_set = 1;
10068       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
10069         ;
10070       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
10071         ;
10072       else
10073         break;
10074     }
10075
10076   if (sw_if_index_set == 0)
10077     {
10078       errmsg ("missing interface name or sw_if_index");
10079       return -99;
10080     }
10081
10082   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
10083
10084   mp->sw_if_index = ntohl (sw_if_index);
10085   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
10086   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
10087
10088   S (mp);
10089   W (ret);
10090   return ret;
10091 }
10092
10093 static int
10094 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
10095 {
10096   unformat_input_t *i = vam->input;
10097   vl_api_l2tpv3_interface_enable_disable_t *mp;
10098   u32 sw_if_index;
10099   u8 sw_if_index_set = 0;
10100   u8 enable_disable = 1;
10101   int ret;
10102
10103   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10104     {
10105       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10106         sw_if_index_set = 1;
10107       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10108         sw_if_index_set = 1;
10109       else if (unformat (i, "enable"))
10110         enable_disable = 1;
10111       else if (unformat (i, "disable"))
10112         enable_disable = 0;
10113       else
10114         break;
10115     }
10116
10117   if (sw_if_index_set == 0)
10118     {
10119       errmsg ("missing interface name or sw_if_index");
10120       return -99;
10121     }
10122
10123   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
10124
10125   mp->sw_if_index = ntohl (sw_if_index);
10126   mp->enable_disable = enable_disable;
10127
10128   S (mp);
10129   W (ret);
10130   return ret;
10131 }
10132
10133 static int
10134 api_l2tpv3_set_lookup_key (vat_main_t * vam)
10135 {
10136   unformat_input_t *i = vam->input;
10137   vl_api_l2tpv3_set_lookup_key_t *mp;
10138   u8 key = ~0;
10139   int ret;
10140
10141   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10142     {
10143       if (unformat (i, "lookup_v6_src"))
10144         key = L2T_LOOKUP_SRC_ADDRESS;
10145       else if (unformat (i, "lookup_v6_dst"))
10146         key = L2T_LOOKUP_DST_ADDRESS;
10147       else if (unformat (i, "lookup_session_id"))
10148         key = L2T_LOOKUP_SESSION_ID;
10149       else
10150         break;
10151     }
10152
10153   if (key == (u8) ~ 0)
10154     {
10155       errmsg ("l2tp session lookup key unset");
10156       return -99;
10157     }
10158
10159   M (L2TPV3_SET_LOOKUP_KEY, mp);
10160
10161   mp->key = key;
10162
10163   S (mp);
10164   W (ret);
10165   return ret;
10166 }
10167
10168 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
10169   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
10170 {
10171   vat_main_t *vam = &vat_main;
10172
10173   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
10174          format_ip6_address, mp->our_address,
10175          format_ip6_address, mp->client_address,
10176          clib_net_to_host_u32 (mp->sw_if_index));
10177
10178   print (vam->ofp,
10179          "   local cookies %016llx %016llx remote cookie %016llx",
10180          clib_net_to_host_u64 (mp->local_cookie[0]),
10181          clib_net_to_host_u64 (mp->local_cookie[1]),
10182          clib_net_to_host_u64 (mp->remote_cookie));
10183
10184   print (vam->ofp, "   local session-id %d remote session-id %d",
10185          clib_net_to_host_u32 (mp->local_session_id),
10186          clib_net_to_host_u32 (mp->remote_session_id));
10187
10188   print (vam->ofp, "   l2 specific sublayer %s\n",
10189          mp->l2_sublayer_present ? "preset" : "absent");
10190
10191 }
10192
10193 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
10194   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
10195 {
10196   vat_main_t *vam = &vat_main;
10197   vat_json_node_t *node = NULL;
10198   struct in6_addr addr;
10199
10200   if (VAT_JSON_ARRAY != vam->json_tree.type)
10201     {
10202       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10203       vat_json_init_array (&vam->json_tree);
10204     }
10205   node = vat_json_array_add (&vam->json_tree);
10206
10207   vat_json_init_object (node);
10208
10209   clib_memcpy (&addr, mp->our_address, sizeof (addr));
10210   vat_json_object_add_ip6 (node, "our_address", addr);
10211   clib_memcpy (&addr, mp->client_address, sizeof (addr));
10212   vat_json_object_add_ip6 (node, "client_address", addr);
10213
10214   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
10215   vat_json_init_array (lc);
10216   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
10217   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
10218   vat_json_object_add_uint (node, "remote_cookie",
10219                             clib_net_to_host_u64 (mp->remote_cookie));
10220
10221   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
10222   vat_json_object_add_uint (node, "local_session_id",
10223                             clib_net_to_host_u32 (mp->local_session_id));
10224   vat_json_object_add_uint (node, "remote_session_id",
10225                             clib_net_to_host_u32 (mp->remote_session_id));
10226   vat_json_object_add_string_copy (node, "l2_sublayer",
10227                                    mp->l2_sublayer_present ? (u8 *) "present"
10228                                    : (u8 *) "absent");
10229 }
10230
10231 static int
10232 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
10233 {
10234   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
10235   vl_api_control_ping_t *mp_ping;
10236   int ret;
10237
10238   /* Get list of l2tpv3-tunnel interfaces */
10239   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
10240   S (mp);
10241
10242   /* Use a control ping for synchronization */
10243   M (CONTROL_PING, mp_ping);
10244   S (mp_ping);
10245
10246   W (ret);
10247   return ret;
10248 }
10249
10250
10251 static void vl_api_sw_interface_tap_details_t_handler
10252   (vl_api_sw_interface_tap_details_t * mp)
10253 {
10254   vat_main_t *vam = &vat_main;
10255
10256   print (vam->ofp, "%-16s %d",
10257          mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
10258 }
10259
10260 static void vl_api_sw_interface_tap_details_t_handler_json
10261   (vl_api_sw_interface_tap_details_t * mp)
10262 {
10263   vat_main_t *vam = &vat_main;
10264   vat_json_node_t *node = NULL;
10265
10266   if (VAT_JSON_ARRAY != vam->json_tree.type)
10267     {
10268       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10269       vat_json_init_array (&vam->json_tree);
10270     }
10271   node = vat_json_array_add (&vam->json_tree);
10272
10273   vat_json_init_object (node);
10274   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10275   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
10276 }
10277
10278 static int
10279 api_sw_interface_tap_dump (vat_main_t * vam)
10280 {
10281   vl_api_sw_interface_tap_dump_t *mp;
10282   vl_api_control_ping_t *mp_ping;
10283   int ret;
10284
10285   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
10286   /* Get list of tap interfaces */
10287   M (SW_INTERFACE_TAP_DUMP, mp);
10288   S (mp);
10289
10290   /* Use a control ping for synchronization */
10291   M (CONTROL_PING, mp_ping);
10292   S (mp_ping);
10293
10294   W (ret);
10295   return ret;
10296 }
10297
10298 static uword unformat_vxlan_decap_next
10299   (unformat_input_t * input, va_list * args)
10300 {
10301   u32 *result = va_arg (*args, u32 *);
10302   u32 tmp;
10303
10304   if (unformat (input, "l2"))
10305     *result = VXLAN_INPUT_NEXT_L2_INPUT;
10306   else if (unformat (input, "%d", &tmp))
10307     *result = tmp;
10308   else
10309     return 0;
10310   return 1;
10311 }
10312
10313 static int
10314 api_vxlan_add_del_tunnel (vat_main_t * vam)
10315 {
10316   unformat_input_t *line_input = vam->input;
10317   vl_api_vxlan_add_del_tunnel_t *mp;
10318   ip46_address_t src, dst;
10319   u8 is_add = 1;
10320   u8 ipv4_set = 0, ipv6_set = 0;
10321   u8 src_set = 0;
10322   u8 dst_set = 0;
10323   u8 grp_set = 0;
10324   u32 mcast_sw_if_index = ~0;
10325   u32 encap_vrf_id = 0;
10326   u32 decap_next_index = ~0;
10327   u32 vni = 0;
10328   int ret;
10329
10330   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
10331   memset (&src, 0, sizeof src);
10332   memset (&dst, 0, sizeof dst);
10333
10334   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10335     {
10336       if (unformat (line_input, "del"))
10337         is_add = 0;
10338       else
10339         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
10340         {
10341           ipv4_set = 1;
10342           src_set = 1;
10343         }
10344       else
10345         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
10346         {
10347           ipv4_set = 1;
10348           dst_set = 1;
10349         }
10350       else
10351         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
10352         {
10353           ipv6_set = 1;
10354           src_set = 1;
10355         }
10356       else
10357         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
10358         {
10359           ipv6_set = 1;
10360           dst_set = 1;
10361         }
10362       else if (unformat (line_input, "group %U %U",
10363                          unformat_ip4_address, &dst.ip4,
10364                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
10365         {
10366           grp_set = dst_set = 1;
10367           ipv4_set = 1;
10368         }
10369       else if (unformat (line_input, "group %U",
10370                          unformat_ip4_address, &dst.ip4))
10371         {
10372           grp_set = dst_set = 1;
10373           ipv4_set = 1;
10374         }
10375       else if (unformat (line_input, "group %U %U",
10376                          unformat_ip6_address, &dst.ip6,
10377                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
10378         {
10379           grp_set = dst_set = 1;
10380           ipv6_set = 1;
10381         }
10382       else if (unformat (line_input, "group %U",
10383                          unformat_ip6_address, &dst.ip6))
10384         {
10385           grp_set = dst_set = 1;
10386           ipv6_set = 1;
10387         }
10388       else
10389         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
10390         ;
10391       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
10392         ;
10393       else if (unformat (line_input, "decap-next %U",
10394                          unformat_vxlan_decap_next, &decap_next_index))
10395         ;
10396       else if (unformat (line_input, "vni %d", &vni))
10397         ;
10398       else
10399         {
10400           errmsg ("parse error '%U'", format_unformat_error, line_input);
10401           return -99;
10402         }
10403     }
10404
10405   if (src_set == 0)
10406     {
10407       errmsg ("tunnel src address not specified");
10408       return -99;
10409     }
10410   if (dst_set == 0)
10411     {
10412       errmsg ("tunnel dst address not specified");
10413       return -99;
10414     }
10415
10416   if (grp_set && !ip46_address_is_multicast (&dst))
10417     {
10418       errmsg ("tunnel group address not multicast");
10419       return -99;
10420     }
10421   if (grp_set && mcast_sw_if_index == ~0)
10422     {
10423       errmsg ("tunnel nonexistent multicast device");
10424       return -99;
10425     }
10426   if (grp_set == 0 && ip46_address_is_multicast (&dst))
10427     {
10428       errmsg ("tunnel dst address must be unicast");
10429       return -99;
10430     }
10431
10432
10433   if (ipv4_set && ipv6_set)
10434     {
10435       errmsg ("both IPv4 and IPv6 addresses specified");
10436       return -99;
10437     }
10438
10439   if ((vni == 0) || (vni >> 24))
10440     {
10441       errmsg ("vni not specified or out of range");
10442       return -99;
10443     }
10444
10445   M (VXLAN_ADD_DEL_TUNNEL, mp);
10446
10447   if (ipv6_set)
10448     {
10449       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
10450       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
10451     }
10452   else
10453     {
10454       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
10455       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
10456     }
10457   mp->encap_vrf_id = ntohl (encap_vrf_id);
10458   mp->decap_next_index = ntohl (decap_next_index);
10459   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
10460   mp->vni = ntohl (vni);
10461   mp->is_add = is_add;
10462   mp->is_ipv6 = ipv6_set;
10463
10464   S (mp);
10465   W (ret);
10466   return ret;
10467 }
10468
10469 static void vl_api_vxlan_tunnel_details_t_handler
10470   (vl_api_vxlan_tunnel_details_t * mp)
10471 {
10472   vat_main_t *vam = &vat_main;
10473   ip46_address_t src, dst;
10474
10475   ip46_from_addr_buf (mp->is_ipv6, mp->src_address, &src);
10476   ip46_from_addr_buf (mp->is_ipv6, mp->dst_address, &dst);
10477
10478   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
10479          ntohl (mp->sw_if_index),
10480          format_ip46_address, &src, IP46_TYPE_ANY,
10481          format_ip46_address, &dst, IP46_TYPE_ANY,
10482          ntohl (mp->encap_vrf_id),
10483          ntohl (mp->decap_next_index), ntohl (mp->vni),
10484          ntohl (mp->mcast_sw_if_index));
10485 }
10486
10487 static void vl_api_vxlan_tunnel_details_t_handler_json
10488   (vl_api_vxlan_tunnel_details_t * mp)
10489 {
10490   vat_main_t *vam = &vat_main;
10491   vat_json_node_t *node = NULL;
10492
10493   if (VAT_JSON_ARRAY != vam->json_tree.type)
10494     {
10495       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10496       vat_json_init_array (&vam->json_tree);
10497     }
10498   node = vat_json_array_add (&vam->json_tree);
10499
10500   vat_json_init_object (node);
10501   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10502   if (mp->is_ipv6)
10503     {
10504       struct in6_addr ip6;
10505
10506       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
10507       vat_json_object_add_ip6 (node, "src_address", ip6);
10508       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
10509       vat_json_object_add_ip6 (node, "dst_address", ip6);
10510     }
10511   else
10512     {
10513       struct in_addr ip4;
10514
10515       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
10516       vat_json_object_add_ip4 (node, "src_address", ip4);
10517       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
10518       vat_json_object_add_ip4 (node, "dst_address", ip4);
10519     }
10520   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
10521   vat_json_object_add_uint (node, "decap_next_index",
10522                             ntohl (mp->decap_next_index));
10523   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
10524   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
10525   vat_json_object_add_uint (node, "mcast_sw_if_index",
10526                             ntohl (mp->mcast_sw_if_index));
10527 }
10528
10529 static int
10530 api_vxlan_tunnel_dump (vat_main_t * vam)
10531 {
10532   unformat_input_t *i = vam->input;
10533   vl_api_vxlan_tunnel_dump_t *mp;
10534   vl_api_control_ping_t *mp_ping;
10535   u32 sw_if_index;
10536   u8 sw_if_index_set = 0;
10537   int ret;
10538
10539   /* Parse args required to build the message */
10540   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10541     {
10542       if (unformat (i, "sw_if_index %d", &sw_if_index))
10543         sw_if_index_set = 1;
10544       else
10545         break;
10546     }
10547
10548   if (sw_if_index_set == 0)
10549     {
10550       sw_if_index = ~0;
10551     }
10552
10553   if (!vam->json_output)
10554     {
10555       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
10556              "sw_if_index", "src_address", "dst_address",
10557              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
10558     }
10559
10560   /* Get list of vxlan-tunnel interfaces */
10561   M (VXLAN_TUNNEL_DUMP, mp);
10562
10563   mp->sw_if_index = htonl (sw_if_index);
10564
10565   S (mp);
10566
10567   /* Use a control ping for synchronization */
10568   M (CONTROL_PING, mp_ping);
10569   S (mp_ping);
10570
10571   W (ret);
10572   return ret;
10573 }
10574
10575 static int
10576 api_gre_add_del_tunnel (vat_main_t * vam)
10577 {
10578   unformat_input_t *line_input = vam->input;
10579   vl_api_gre_add_del_tunnel_t *mp;
10580   ip4_address_t src4, dst4;
10581   u8 is_add = 1;
10582   u8 teb = 0;
10583   u8 src_set = 0;
10584   u8 dst_set = 0;
10585   u32 outer_fib_id = 0;
10586   int ret;
10587
10588   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10589     {
10590       if (unformat (line_input, "del"))
10591         is_add = 0;
10592       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
10593         src_set = 1;
10594       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
10595         dst_set = 1;
10596       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
10597         ;
10598       else if (unformat (line_input, "teb"))
10599         teb = 1;
10600       else
10601         {
10602           errmsg ("parse error '%U'", format_unformat_error, line_input);
10603           return -99;
10604         }
10605     }
10606
10607   if (src_set == 0)
10608     {
10609       errmsg ("tunnel src address not specified");
10610       return -99;
10611     }
10612   if (dst_set == 0)
10613     {
10614       errmsg ("tunnel dst address not specified");
10615       return -99;
10616     }
10617
10618
10619   M (GRE_ADD_DEL_TUNNEL, mp);
10620
10621   clib_memcpy (&mp->src_address, &src4, sizeof (src4));
10622   clib_memcpy (&mp->dst_address, &dst4, sizeof (dst4));
10623   mp->outer_fib_id = ntohl (outer_fib_id);
10624   mp->is_add = is_add;
10625   mp->teb = teb;
10626
10627   S (mp);
10628   W (ret);
10629   return ret;
10630 }
10631
10632 static void vl_api_gre_tunnel_details_t_handler
10633   (vl_api_gre_tunnel_details_t * mp)
10634 {
10635   vat_main_t *vam = &vat_main;
10636
10637   print (vam->ofp, "%11d%15U%15U%6d%14d",
10638          ntohl (mp->sw_if_index),
10639          format_ip4_address, &mp->src_address,
10640          format_ip4_address, &mp->dst_address,
10641          mp->teb, ntohl (mp->outer_fib_id));
10642 }
10643
10644 static void vl_api_gre_tunnel_details_t_handler_json
10645   (vl_api_gre_tunnel_details_t * mp)
10646 {
10647   vat_main_t *vam = &vat_main;
10648   vat_json_node_t *node = NULL;
10649   struct in_addr ip4;
10650
10651   if (VAT_JSON_ARRAY != vam->json_tree.type)
10652     {
10653       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10654       vat_json_init_array (&vam->json_tree);
10655     }
10656   node = vat_json_array_add (&vam->json_tree);
10657
10658   vat_json_init_object (node);
10659   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10660   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
10661   vat_json_object_add_ip4 (node, "src_address", ip4);
10662   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
10663   vat_json_object_add_ip4 (node, "dst_address", ip4);
10664   vat_json_object_add_uint (node, "teb", mp->teb);
10665   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
10666 }
10667
10668 static int
10669 api_gre_tunnel_dump (vat_main_t * vam)
10670 {
10671   unformat_input_t *i = vam->input;
10672   vl_api_gre_tunnel_dump_t *mp;
10673   vl_api_control_ping_t *mp_ping;
10674   u32 sw_if_index;
10675   u8 sw_if_index_set = 0;
10676   int ret;
10677
10678   /* Parse args required to build the message */
10679   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10680     {
10681       if (unformat (i, "sw_if_index %d", &sw_if_index))
10682         sw_if_index_set = 1;
10683       else
10684         break;
10685     }
10686
10687   if (sw_if_index_set == 0)
10688     {
10689       sw_if_index = ~0;
10690     }
10691
10692   if (!vam->json_output)
10693     {
10694       print (vam->ofp, "%11s%15s%15s%6s%14s",
10695              "sw_if_index", "src_address", "dst_address", "teb",
10696              "outer_fib_id");
10697     }
10698
10699   /* Get list of gre-tunnel interfaces */
10700   M (GRE_TUNNEL_DUMP, mp);
10701
10702   mp->sw_if_index = htonl (sw_if_index);
10703
10704   S (mp);
10705
10706   /* Use a control ping for synchronization */
10707   M (CONTROL_PING, mp_ping);
10708   S (mp_ping);
10709
10710   W (ret);
10711   return ret;
10712 }
10713
10714 static int
10715 api_l2_fib_clear_table (vat_main_t * vam)
10716 {
10717 //  unformat_input_t * i = vam->input;
10718   vl_api_l2_fib_clear_table_t *mp;
10719   int ret;
10720
10721   M (L2_FIB_CLEAR_TABLE, mp);
10722
10723   S (mp);
10724   W (ret);
10725   return ret;
10726 }
10727
10728 static int
10729 api_l2_interface_efp_filter (vat_main_t * vam)
10730 {
10731   unformat_input_t *i = vam->input;
10732   vl_api_l2_interface_efp_filter_t *mp;
10733   u32 sw_if_index;
10734   u8 enable = 1;
10735   u8 sw_if_index_set = 0;
10736   int ret;
10737
10738   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10739     {
10740       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10741         sw_if_index_set = 1;
10742       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10743         sw_if_index_set = 1;
10744       else if (unformat (i, "enable"))
10745         enable = 1;
10746       else if (unformat (i, "disable"))
10747         enable = 0;
10748       else
10749         {
10750           clib_warning ("parse error '%U'", format_unformat_error, i);
10751           return -99;
10752         }
10753     }
10754
10755   if (sw_if_index_set == 0)
10756     {
10757       errmsg ("missing sw_if_index");
10758       return -99;
10759     }
10760
10761   M (L2_INTERFACE_EFP_FILTER, mp);
10762
10763   mp->sw_if_index = ntohl (sw_if_index);
10764   mp->enable_disable = enable;
10765
10766   S (mp);
10767   W (ret);
10768   return ret;
10769 }
10770
10771 #define foreach_vtr_op                          \
10772 _("disable",  L2_VTR_DISABLED)                  \
10773 _("push-1",  L2_VTR_PUSH_1)                     \
10774 _("push-2",  L2_VTR_PUSH_2)                     \
10775 _("pop-1",  L2_VTR_POP_1)                       \
10776 _("pop-2",  L2_VTR_POP_2)                       \
10777 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
10778 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
10779 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
10780 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
10781
10782 static int
10783 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
10784 {
10785   unformat_input_t *i = vam->input;
10786   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
10787   u32 sw_if_index;
10788   u8 sw_if_index_set = 0;
10789   u8 vtr_op_set = 0;
10790   u32 vtr_op = 0;
10791   u32 push_dot1q = 1;
10792   u32 tag1 = ~0;
10793   u32 tag2 = ~0;
10794   int ret;
10795
10796   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10797     {
10798       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10799         sw_if_index_set = 1;
10800       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10801         sw_if_index_set = 1;
10802       else if (unformat (i, "vtr_op %d", &vtr_op))
10803         vtr_op_set = 1;
10804 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
10805       foreach_vtr_op
10806 #undef _
10807         else if (unformat (i, "push_dot1q %d", &push_dot1q))
10808         ;
10809       else if (unformat (i, "tag1 %d", &tag1))
10810         ;
10811       else if (unformat (i, "tag2 %d", &tag2))
10812         ;
10813       else
10814         {
10815           clib_warning ("parse error '%U'", format_unformat_error, i);
10816           return -99;
10817         }
10818     }
10819
10820   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
10821     {
10822       errmsg ("missing vtr operation or sw_if_index");
10823       return -99;
10824     }
10825
10826   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
10827   mp->sw_if_index = ntohl (sw_if_index);
10828   mp->vtr_op = ntohl (vtr_op);
10829   mp->push_dot1q = ntohl (push_dot1q);
10830   mp->tag1 = ntohl (tag1);
10831   mp->tag2 = ntohl (tag2);
10832
10833   S (mp);
10834   W (ret);
10835   return ret;
10836 }
10837
10838 static int
10839 api_create_vhost_user_if (vat_main_t * vam)
10840 {
10841   unformat_input_t *i = vam->input;
10842   vl_api_create_vhost_user_if_t *mp;
10843   u8 *file_name;
10844   u8 is_server = 0;
10845   u8 file_name_set = 0;
10846   u32 custom_dev_instance = ~0;
10847   u8 hwaddr[6];
10848   u8 use_custom_mac = 0;
10849   u8 *tag = 0;
10850   int ret;
10851
10852   /* Shut up coverity */
10853   memset (hwaddr, 0, sizeof (hwaddr));
10854
10855   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10856     {
10857       if (unformat (i, "socket %s", &file_name))
10858         {
10859           file_name_set = 1;
10860         }
10861       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
10862         ;
10863       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
10864         use_custom_mac = 1;
10865       else if (unformat (i, "server"))
10866         is_server = 1;
10867       else if (unformat (i, "tag %s", &tag))
10868         ;
10869       else
10870         break;
10871     }
10872
10873   if (file_name_set == 0)
10874     {
10875       errmsg ("missing socket file name");
10876       return -99;
10877     }
10878
10879   if (vec_len (file_name) > 255)
10880     {
10881       errmsg ("socket file name too long");
10882       return -99;
10883     }
10884   vec_add1 (file_name, 0);
10885
10886   M (CREATE_VHOST_USER_IF, mp);
10887
10888   mp->is_server = is_server;
10889   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
10890   vec_free (file_name);
10891   if (custom_dev_instance != ~0)
10892     {
10893       mp->renumber = 1;
10894       mp->custom_dev_instance = ntohl (custom_dev_instance);
10895     }
10896   mp->use_custom_mac = use_custom_mac;
10897   clib_memcpy (mp->mac_address, hwaddr, 6);
10898   if (tag)
10899     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
10900   vec_free (tag);
10901
10902   S (mp);
10903   W (ret);
10904   return ret;
10905 }
10906
10907 static int
10908 api_modify_vhost_user_if (vat_main_t * vam)
10909 {
10910   unformat_input_t *i = vam->input;
10911   vl_api_modify_vhost_user_if_t *mp;
10912   u8 *file_name;
10913   u8 is_server = 0;
10914   u8 file_name_set = 0;
10915   u32 custom_dev_instance = ~0;
10916   u8 sw_if_index_set = 0;
10917   u32 sw_if_index = (u32) ~ 0;
10918   int ret;
10919
10920   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10921     {
10922       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10923         sw_if_index_set = 1;
10924       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10925         sw_if_index_set = 1;
10926       else if (unformat (i, "socket %s", &file_name))
10927         {
10928           file_name_set = 1;
10929         }
10930       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
10931         ;
10932       else if (unformat (i, "server"))
10933         is_server = 1;
10934       else
10935         break;
10936     }
10937
10938   if (sw_if_index_set == 0)
10939     {
10940       errmsg ("missing sw_if_index or interface name");
10941       return -99;
10942     }
10943
10944   if (file_name_set == 0)
10945     {
10946       errmsg ("missing socket file name");
10947       return -99;
10948     }
10949
10950   if (vec_len (file_name) > 255)
10951     {
10952       errmsg ("socket file name too long");
10953       return -99;
10954     }
10955   vec_add1 (file_name, 0);
10956
10957   M (MODIFY_VHOST_USER_IF, mp);
10958
10959   mp->sw_if_index = ntohl (sw_if_index);
10960   mp->is_server = is_server;
10961   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
10962   vec_free (file_name);
10963   if (custom_dev_instance != ~0)
10964     {
10965       mp->renumber = 1;
10966       mp->custom_dev_instance = ntohl (custom_dev_instance);
10967     }
10968
10969   S (mp);
10970   W (ret);
10971   return ret;
10972 }
10973
10974 static int
10975 api_delete_vhost_user_if (vat_main_t * vam)
10976 {
10977   unformat_input_t *i = vam->input;
10978   vl_api_delete_vhost_user_if_t *mp;
10979   u32 sw_if_index = ~0;
10980   u8 sw_if_index_set = 0;
10981   int ret;
10982
10983   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10984     {
10985       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10986         sw_if_index_set = 1;
10987       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10988         sw_if_index_set = 1;
10989       else
10990         break;
10991     }
10992
10993   if (sw_if_index_set == 0)
10994     {
10995       errmsg ("missing sw_if_index or interface name");
10996       return -99;
10997     }
10998
10999
11000   M (DELETE_VHOST_USER_IF, mp);
11001
11002   mp->sw_if_index = ntohl (sw_if_index);
11003
11004   S (mp);
11005   W (ret);
11006   return ret;
11007 }
11008
11009 static void vl_api_sw_interface_vhost_user_details_t_handler
11010   (vl_api_sw_interface_vhost_user_details_t * mp)
11011 {
11012   vat_main_t *vam = &vat_main;
11013
11014   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
11015          (char *) mp->interface_name,
11016          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
11017          clib_net_to_host_u64 (mp->features), mp->is_server,
11018          ntohl (mp->num_regions), (char *) mp->sock_filename);
11019   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
11020 }
11021
11022 static void vl_api_sw_interface_vhost_user_details_t_handler_json
11023   (vl_api_sw_interface_vhost_user_details_t * mp)
11024 {
11025   vat_main_t *vam = &vat_main;
11026   vat_json_node_t *node = NULL;
11027
11028   if (VAT_JSON_ARRAY != vam->json_tree.type)
11029     {
11030       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11031       vat_json_init_array (&vam->json_tree);
11032     }
11033   node = vat_json_array_add (&vam->json_tree);
11034
11035   vat_json_init_object (node);
11036   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11037   vat_json_object_add_string_copy (node, "interface_name",
11038                                    mp->interface_name);
11039   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
11040                             ntohl (mp->virtio_net_hdr_sz));
11041   vat_json_object_add_uint (node, "features",
11042                             clib_net_to_host_u64 (mp->features));
11043   vat_json_object_add_uint (node, "is_server", mp->is_server);
11044   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
11045   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
11046   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
11047 }
11048
11049 static int
11050 api_sw_interface_vhost_user_dump (vat_main_t * vam)
11051 {
11052   vl_api_sw_interface_vhost_user_dump_t *mp;
11053   vl_api_control_ping_t *mp_ping;
11054   int ret;
11055   print (vam->ofp,
11056          "Interface name           idx hdr_sz features server regions filename");
11057
11058   /* Get list of vhost-user interfaces */
11059   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
11060   S (mp);
11061
11062   /* Use a control ping for synchronization */
11063   M (CONTROL_PING, mp_ping);
11064   S (mp_ping);
11065
11066   W (ret);
11067   return ret;
11068 }
11069
11070 static int
11071 api_show_version (vat_main_t * vam)
11072 {
11073   vl_api_show_version_t *mp;
11074   int ret;
11075
11076   M (SHOW_VERSION, mp);
11077
11078   S (mp);
11079   W (ret);
11080   return ret;
11081 }
11082
11083
11084 static int
11085 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
11086 {
11087   unformat_input_t *line_input = vam->input;
11088   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
11089   ip4_address_t local4, remote4;
11090   ip6_address_t local6, remote6;
11091   u8 is_add = 1;
11092   u8 ipv4_set = 0, ipv6_set = 0;
11093   u8 local_set = 0;
11094   u8 remote_set = 0;
11095   u32 encap_vrf_id = 0;
11096   u32 decap_vrf_id = 0;
11097   u8 protocol = ~0;
11098   u32 vni;
11099   u8 vni_set = 0;
11100   int ret;
11101
11102   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11103     {
11104       if (unformat (line_input, "del"))
11105         is_add = 0;
11106       else if (unformat (line_input, "local %U",
11107                          unformat_ip4_address, &local4))
11108         {
11109           local_set = 1;
11110           ipv4_set = 1;
11111         }
11112       else if (unformat (line_input, "remote %U",
11113                          unformat_ip4_address, &remote4))
11114         {
11115           remote_set = 1;
11116           ipv4_set = 1;
11117         }
11118       else if (unformat (line_input, "local %U",
11119                          unformat_ip6_address, &local6))
11120         {
11121           local_set = 1;
11122           ipv6_set = 1;
11123         }
11124       else if (unformat (line_input, "remote %U",
11125                          unformat_ip6_address, &remote6))
11126         {
11127           remote_set = 1;
11128           ipv6_set = 1;
11129         }
11130       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
11131         ;
11132       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
11133         ;
11134       else if (unformat (line_input, "vni %d", &vni))
11135         vni_set = 1;
11136       else if (unformat (line_input, "next-ip4"))
11137         protocol = 1;
11138       else if (unformat (line_input, "next-ip6"))
11139         protocol = 2;
11140       else if (unformat (line_input, "next-ethernet"))
11141         protocol = 3;
11142       else if (unformat (line_input, "next-nsh"))
11143         protocol = 4;
11144       else
11145         {
11146           errmsg ("parse error '%U'", format_unformat_error, line_input);
11147           return -99;
11148         }
11149     }
11150
11151   if (local_set == 0)
11152     {
11153       errmsg ("tunnel local address not specified");
11154       return -99;
11155     }
11156   if (remote_set == 0)
11157     {
11158       errmsg ("tunnel remote address not specified");
11159       return -99;
11160     }
11161   if (ipv4_set && ipv6_set)
11162     {
11163       errmsg ("both IPv4 and IPv6 addresses specified");
11164       return -99;
11165     }
11166
11167   if (vni_set == 0)
11168     {
11169       errmsg ("vni not specified");
11170       return -99;
11171     }
11172
11173   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
11174
11175
11176   if (ipv6_set)
11177     {
11178       clib_memcpy (&mp->local, &local6, sizeof (local6));
11179       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
11180     }
11181   else
11182     {
11183       clib_memcpy (&mp->local, &local4, sizeof (local4));
11184       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
11185     }
11186
11187   mp->encap_vrf_id = ntohl (encap_vrf_id);
11188   mp->decap_vrf_id = ntohl (decap_vrf_id);
11189   mp->protocol = protocol;
11190   mp->vni = ntohl (vni);
11191   mp->is_add = is_add;
11192   mp->is_ipv6 = ipv6_set;
11193
11194   S (mp);
11195   W (ret);
11196   return ret;
11197 }
11198
11199 static void vl_api_vxlan_gpe_tunnel_details_t_handler
11200   (vl_api_vxlan_gpe_tunnel_details_t * mp)
11201 {
11202   vat_main_t *vam = &vat_main;
11203
11204   print (vam->ofp, "%11d%24U%24U%13d%12d%14d%14d",
11205          ntohl (mp->sw_if_index),
11206          format_ip46_address, &(mp->local[0]),
11207          format_ip46_address, &(mp->remote[0]),
11208          ntohl (mp->vni),
11209          ntohl (mp->protocol),
11210          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
11211 }
11212
11213 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
11214   (vl_api_vxlan_gpe_tunnel_details_t * mp)
11215 {
11216   vat_main_t *vam = &vat_main;
11217   vat_json_node_t *node = NULL;
11218   struct in_addr ip4;
11219   struct in6_addr ip6;
11220
11221   if (VAT_JSON_ARRAY != vam->json_tree.type)
11222     {
11223       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11224       vat_json_init_array (&vam->json_tree);
11225     }
11226   node = vat_json_array_add (&vam->json_tree);
11227
11228   vat_json_init_object (node);
11229   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11230   if (mp->is_ipv6)
11231     {
11232       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
11233       vat_json_object_add_ip6 (node, "local", ip6);
11234       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
11235       vat_json_object_add_ip6 (node, "remote", ip6);
11236     }
11237   else
11238     {
11239       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
11240       vat_json_object_add_ip4 (node, "local", ip4);
11241       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
11242       vat_json_object_add_ip4 (node, "remote", ip4);
11243     }
11244   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
11245   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
11246   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
11247   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
11248   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
11249 }
11250
11251 static int
11252 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
11253 {
11254   unformat_input_t *i = vam->input;
11255   vl_api_vxlan_gpe_tunnel_dump_t *mp;
11256   vl_api_control_ping_t *mp_ping;
11257   u32 sw_if_index;
11258   u8 sw_if_index_set = 0;
11259   int ret;
11260
11261   /* Parse args required to build the message */
11262   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11263     {
11264       if (unformat (i, "sw_if_index %d", &sw_if_index))
11265         sw_if_index_set = 1;
11266       else
11267         break;
11268     }
11269
11270   if (sw_if_index_set == 0)
11271     {
11272       sw_if_index = ~0;
11273     }
11274
11275   if (!vam->json_output)
11276     {
11277       print (vam->ofp, "%11s%24s%24s%13s%15s%14s%14s",
11278              "sw_if_index", "local", "remote", "vni",
11279              "protocol", "encap_vrf_id", "decap_vrf_id");
11280     }
11281
11282   /* Get list of vxlan-tunnel interfaces */
11283   M (VXLAN_GPE_TUNNEL_DUMP, mp);
11284
11285   mp->sw_if_index = htonl (sw_if_index);
11286
11287   S (mp);
11288
11289   /* Use a control ping for synchronization */
11290   M (CONTROL_PING, mp_ping);
11291   S (mp_ping);
11292
11293   W (ret);
11294   return ret;
11295 }
11296
11297 u8 *
11298 format_l2_fib_mac_address (u8 * s, va_list * args)
11299 {
11300   u8 *a = va_arg (*args, u8 *);
11301
11302   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
11303                  a[2], a[3], a[4], a[5], a[6], a[7]);
11304 }
11305
11306 static void vl_api_l2_fib_table_entry_t_handler
11307   (vl_api_l2_fib_table_entry_t * mp)
11308 {
11309   vat_main_t *vam = &vat_main;
11310
11311   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
11312          "       %d       %d     %d",
11313          ntohl (mp->bd_id), format_l2_fib_mac_address, &mp->mac,
11314          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
11315          mp->bvi_mac);
11316 }
11317
11318 static void vl_api_l2_fib_table_entry_t_handler_json
11319   (vl_api_l2_fib_table_entry_t * mp)
11320 {
11321   vat_main_t *vam = &vat_main;
11322   vat_json_node_t *node = NULL;
11323
11324   if (VAT_JSON_ARRAY != vam->json_tree.type)
11325     {
11326       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11327       vat_json_init_array (&vam->json_tree);
11328     }
11329   node = vat_json_array_add (&vam->json_tree);
11330
11331   vat_json_init_object (node);
11332   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
11333   vat_json_object_add_uint (node, "mac", clib_net_to_host_u64 (mp->mac));
11334   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11335   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
11336   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
11337   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
11338 }
11339
11340 static int
11341 api_l2_fib_table_dump (vat_main_t * vam)
11342 {
11343   unformat_input_t *i = vam->input;
11344   vl_api_l2_fib_table_dump_t *mp;
11345   vl_api_control_ping_t *mp_ping;
11346   u32 bd_id;
11347   u8 bd_id_set = 0;
11348   int ret;
11349
11350   /* Parse args required to build the message */
11351   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11352     {
11353       if (unformat (i, "bd_id %d", &bd_id))
11354         bd_id_set = 1;
11355       else
11356         break;
11357     }
11358
11359   if (bd_id_set == 0)
11360     {
11361       errmsg ("missing bridge domain");
11362       return -99;
11363     }
11364
11365   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
11366
11367   /* Get list of l2 fib entries */
11368   M (L2_FIB_TABLE_DUMP, mp);
11369
11370   mp->bd_id = ntohl (bd_id);
11371   S (mp);
11372
11373   /* Use a control ping for synchronization */
11374   M (CONTROL_PING, mp_ping);
11375   S (mp_ping);
11376
11377   W (ret);
11378   return ret;
11379 }
11380
11381
11382 static int
11383 api_interface_name_renumber (vat_main_t * vam)
11384 {
11385   unformat_input_t *line_input = vam->input;
11386   vl_api_interface_name_renumber_t *mp;
11387   u32 sw_if_index = ~0;
11388   u32 new_show_dev_instance = ~0;
11389   int ret;
11390
11391   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11392     {
11393       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
11394                     &sw_if_index))
11395         ;
11396       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
11397         ;
11398       else if (unformat (line_input, "new_show_dev_instance %d",
11399                          &new_show_dev_instance))
11400         ;
11401       else
11402         break;
11403     }
11404
11405   if (sw_if_index == ~0)
11406     {
11407       errmsg ("missing interface name or sw_if_index");
11408       return -99;
11409     }
11410
11411   if (new_show_dev_instance == ~0)
11412     {
11413       errmsg ("missing new_show_dev_instance");
11414       return -99;
11415     }
11416
11417   M (INTERFACE_NAME_RENUMBER, mp);
11418
11419   mp->sw_if_index = ntohl (sw_if_index);
11420   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
11421
11422   S (mp);
11423   W (ret);
11424   return ret;
11425 }
11426
11427 static int
11428 api_want_ip4_arp_events (vat_main_t * vam)
11429 {
11430   unformat_input_t *line_input = vam->input;
11431   vl_api_want_ip4_arp_events_t *mp;
11432   ip4_address_t address;
11433   int address_set = 0;
11434   u32 enable_disable = 1;
11435   int ret;
11436
11437   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11438     {
11439       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
11440         address_set = 1;
11441       else if (unformat (line_input, "del"))
11442         enable_disable = 0;
11443       else
11444         break;
11445     }
11446
11447   if (address_set == 0)
11448     {
11449       errmsg ("missing addresses");
11450       return -99;
11451     }
11452
11453   M (WANT_IP4_ARP_EVENTS, mp);
11454   mp->enable_disable = enable_disable;
11455   mp->pid = getpid ();
11456   mp->address = address.as_u32;
11457
11458   S (mp);
11459   W (ret);
11460   return ret;
11461 }
11462
11463 static int
11464 api_want_ip6_nd_events (vat_main_t * vam)
11465 {
11466   unformat_input_t *line_input = vam->input;
11467   vl_api_want_ip6_nd_events_t *mp;
11468   ip6_address_t address;
11469   int address_set = 0;
11470   u32 enable_disable = 1;
11471   int ret;
11472
11473   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11474     {
11475       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
11476         address_set = 1;
11477       else if (unformat (line_input, "del"))
11478         enable_disable = 0;
11479       else
11480         break;
11481     }
11482
11483   if (address_set == 0)
11484     {
11485       errmsg ("missing addresses");
11486       return -99;
11487     }
11488
11489   M (WANT_IP6_ND_EVENTS, mp);
11490   mp->enable_disable = enable_disable;
11491   mp->pid = getpid ();
11492   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
11493
11494   S (mp);
11495   W (ret);
11496   return ret;
11497 }
11498
11499 static int
11500 api_input_acl_set_interface (vat_main_t * vam)
11501 {
11502   unformat_input_t *i = vam->input;
11503   vl_api_input_acl_set_interface_t *mp;
11504   u32 sw_if_index;
11505   int sw_if_index_set;
11506   u32 ip4_table_index = ~0;
11507   u32 ip6_table_index = ~0;
11508   u32 l2_table_index = ~0;
11509   u8 is_add = 1;
11510   int ret;
11511
11512   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11513     {
11514       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11515         sw_if_index_set = 1;
11516       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11517         sw_if_index_set = 1;
11518       else if (unformat (i, "del"))
11519         is_add = 0;
11520       else if (unformat (i, "ip4-table %d", &ip4_table_index))
11521         ;
11522       else if (unformat (i, "ip6-table %d", &ip6_table_index))
11523         ;
11524       else if (unformat (i, "l2-table %d", &l2_table_index))
11525         ;
11526       else
11527         {
11528           clib_warning ("parse error '%U'", format_unformat_error, i);
11529           return -99;
11530         }
11531     }
11532
11533   if (sw_if_index_set == 0)
11534     {
11535       errmsg ("missing interface name or sw_if_index");
11536       return -99;
11537     }
11538
11539   M (INPUT_ACL_SET_INTERFACE, mp);
11540
11541   mp->sw_if_index = ntohl (sw_if_index);
11542   mp->ip4_table_index = ntohl (ip4_table_index);
11543   mp->ip6_table_index = ntohl (ip6_table_index);
11544   mp->l2_table_index = ntohl (l2_table_index);
11545   mp->is_add = is_add;
11546
11547   S (mp);
11548   W (ret);
11549   return ret;
11550 }
11551
11552 static int
11553 api_ip_address_dump (vat_main_t * vam)
11554 {
11555   unformat_input_t *i = vam->input;
11556   vl_api_ip_address_dump_t *mp;
11557   vl_api_control_ping_t *mp_ping;
11558   u32 sw_if_index = ~0;
11559   u8 sw_if_index_set = 0;
11560   u8 ipv4_set = 0;
11561   u8 ipv6_set = 0;
11562   int ret;
11563
11564   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11565     {
11566       if (unformat (i, "sw_if_index %d", &sw_if_index))
11567         sw_if_index_set = 1;
11568       else
11569         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11570         sw_if_index_set = 1;
11571       else if (unformat (i, "ipv4"))
11572         ipv4_set = 1;
11573       else if (unformat (i, "ipv6"))
11574         ipv6_set = 1;
11575       else
11576         break;
11577     }
11578
11579   if (ipv4_set && ipv6_set)
11580     {
11581       errmsg ("ipv4 and ipv6 flags cannot be both set");
11582       return -99;
11583     }
11584
11585   if ((!ipv4_set) && (!ipv6_set))
11586     {
11587       errmsg ("no ipv4 nor ipv6 flag set");
11588       return -99;
11589     }
11590
11591   if (sw_if_index_set == 0)
11592     {
11593       errmsg ("missing interface name or sw_if_index");
11594       return -99;
11595     }
11596
11597   vam->current_sw_if_index = sw_if_index;
11598   vam->is_ipv6 = ipv6_set;
11599
11600   M (IP_ADDRESS_DUMP, mp);
11601   mp->sw_if_index = ntohl (sw_if_index);
11602   mp->is_ipv6 = ipv6_set;
11603   S (mp);
11604
11605   /* Use a control ping for synchronization */
11606   M (CONTROL_PING, mp_ping);
11607   S (mp_ping);
11608
11609   W (ret);
11610   return ret;
11611 }
11612
11613 static int
11614 api_ip_dump (vat_main_t * vam)
11615 {
11616   vl_api_ip_dump_t *mp;
11617   vl_api_control_ping_t *mp_ping;
11618   unformat_input_t *in = vam->input;
11619   int ipv4_set = 0;
11620   int ipv6_set = 0;
11621   int is_ipv6;
11622   int i;
11623   int ret;
11624
11625   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
11626     {
11627       if (unformat (in, "ipv4"))
11628         ipv4_set = 1;
11629       else if (unformat (in, "ipv6"))
11630         ipv6_set = 1;
11631       else
11632         break;
11633     }
11634
11635   if (ipv4_set && ipv6_set)
11636     {
11637       errmsg ("ipv4 and ipv6 flags cannot be both set");
11638       return -99;
11639     }
11640
11641   if ((!ipv4_set) && (!ipv6_set))
11642     {
11643       errmsg ("no ipv4 nor ipv6 flag set");
11644       return -99;
11645     }
11646
11647   is_ipv6 = ipv6_set;
11648   vam->is_ipv6 = is_ipv6;
11649
11650   /* free old data */
11651   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
11652     {
11653       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
11654     }
11655   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
11656
11657   M (IP_DUMP, mp);
11658   mp->is_ipv6 = ipv6_set;
11659   S (mp);
11660
11661   /* Use a control ping for synchronization */
11662   M (CONTROL_PING, mp_ping);
11663   S (mp_ping);
11664
11665   W (ret);
11666   return ret;
11667 }
11668
11669 static int
11670 api_ipsec_spd_add_del (vat_main_t * vam)
11671 {
11672   unformat_input_t *i = vam->input;
11673   vl_api_ipsec_spd_add_del_t *mp;
11674   u32 spd_id = ~0;
11675   u8 is_add = 1;
11676   int ret;
11677
11678   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11679     {
11680       if (unformat (i, "spd_id %d", &spd_id))
11681         ;
11682       else if (unformat (i, "del"))
11683         is_add = 0;
11684       else
11685         {
11686           clib_warning ("parse error '%U'", format_unformat_error, i);
11687           return -99;
11688         }
11689     }
11690   if (spd_id == ~0)
11691     {
11692       errmsg ("spd_id must be set");
11693       return -99;
11694     }
11695
11696   M (IPSEC_SPD_ADD_DEL, mp);
11697
11698   mp->spd_id = ntohl (spd_id);
11699   mp->is_add = is_add;
11700
11701   S (mp);
11702   W (ret);
11703   return ret;
11704 }
11705
11706 static int
11707 api_ipsec_interface_add_del_spd (vat_main_t * vam)
11708 {
11709   unformat_input_t *i = vam->input;
11710   vl_api_ipsec_interface_add_del_spd_t *mp;
11711   u32 sw_if_index;
11712   u8 sw_if_index_set = 0;
11713   u32 spd_id = (u32) ~ 0;
11714   u8 is_add = 1;
11715   int ret;
11716
11717   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11718     {
11719       if (unformat (i, "del"))
11720         is_add = 0;
11721       else if (unformat (i, "spd_id %d", &spd_id))
11722         ;
11723       else
11724         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11725         sw_if_index_set = 1;
11726       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11727         sw_if_index_set = 1;
11728       else
11729         {
11730           clib_warning ("parse error '%U'", format_unformat_error, i);
11731           return -99;
11732         }
11733
11734     }
11735
11736   if (spd_id == (u32) ~ 0)
11737     {
11738       errmsg ("spd_id must be set");
11739       return -99;
11740     }
11741
11742   if (sw_if_index_set == 0)
11743     {
11744       errmsg ("missing interface name or sw_if_index");
11745       return -99;
11746     }
11747
11748   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
11749
11750   mp->spd_id = ntohl (spd_id);
11751   mp->sw_if_index = ntohl (sw_if_index);
11752   mp->is_add = is_add;
11753
11754   S (mp);
11755   W (ret);
11756   return ret;
11757 }
11758
11759 static int
11760 api_ipsec_spd_add_del_entry (vat_main_t * vam)
11761 {
11762   unformat_input_t *i = vam->input;
11763   vl_api_ipsec_spd_add_del_entry_t *mp;
11764   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
11765   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
11766   i32 priority = 0;
11767   u32 rport_start = 0, rport_stop = (u32) ~ 0;
11768   u32 lport_start = 0, lport_stop = (u32) ~ 0;
11769   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
11770   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
11771   int ret;
11772
11773   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
11774   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
11775   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
11776   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
11777   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
11778   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
11779
11780   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11781     {
11782       if (unformat (i, "del"))
11783         is_add = 0;
11784       if (unformat (i, "outbound"))
11785         is_outbound = 1;
11786       if (unformat (i, "inbound"))
11787         is_outbound = 0;
11788       else if (unformat (i, "spd_id %d", &spd_id))
11789         ;
11790       else if (unformat (i, "sa_id %d", &sa_id))
11791         ;
11792       else if (unformat (i, "priority %d", &priority))
11793         ;
11794       else if (unformat (i, "protocol %d", &protocol))
11795         ;
11796       else if (unformat (i, "lport_start %d", &lport_start))
11797         ;
11798       else if (unformat (i, "lport_stop %d", &lport_stop))
11799         ;
11800       else if (unformat (i, "rport_start %d", &rport_start))
11801         ;
11802       else if (unformat (i, "rport_stop %d", &rport_stop))
11803         ;
11804       else
11805         if (unformat
11806             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
11807         {
11808           is_ipv6 = 0;
11809           is_ip_any = 0;
11810         }
11811       else
11812         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
11813         {
11814           is_ipv6 = 0;
11815           is_ip_any = 0;
11816         }
11817       else
11818         if (unformat
11819             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
11820         {
11821           is_ipv6 = 0;
11822           is_ip_any = 0;
11823         }
11824       else
11825         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
11826         {
11827           is_ipv6 = 0;
11828           is_ip_any = 0;
11829         }
11830       else
11831         if (unformat
11832             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
11833         {
11834           is_ipv6 = 1;
11835           is_ip_any = 0;
11836         }
11837       else
11838         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
11839         {
11840           is_ipv6 = 1;
11841           is_ip_any = 0;
11842         }
11843       else
11844         if (unformat
11845             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
11846         {
11847           is_ipv6 = 1;
11848           is_ip_any = 0;
11849         }
11850       else
11851         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
11852         {
11853           is_ipv6 = 1;
11854           is_ip_any = 0;
11855         }
11856       else
11857         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
11858         {
11859           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
11860             {
11861               clib_warning ("unsupported action: 'resolve'");
11862               return -99;
11863             }
11864         }
11865       else
11866         {
11867           clib_warning ("parse error '%U'", format_unformat_error, i);
11868           return -99;
11869         }
11870
11871     }
11872
11873   M (IPSEC_SPD_ADD_DEL_ENTRY, mp);
11874
11875   mp->spd_id = ntohl (spd_id);
11876   mp->priority = ntohl (priority);
11877   mp->is_outbound = is_outbound;
11878
11879   mp->is_ipv6 = is_ipv6;
11880   if (is_ipv6 || is_ip_any)
11881     {
11882       clib_memcpy (mp->remote_address_start, &raddr6_start,
11883                    sizeof (ip6_address_t));
11884       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
11885                    sizeof (ip6_address_t));
11886       clib_memcpy (mp->local_address_start, &laddr6_start,
11887                    sizeof (ip6_address_t));
11888       clib_memcpy (mp->local_address_stop, &laddr6_stop,
11889                    sizeof (ip6_address_t));
11890     }
11891   else
11892     {
11893       clib_memcpy (mp->remote_address_start, &raddr4_start,
11894                    sizeof (ip4_address_t));
11895       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
11896                    sizeof (ip4_address_t));
11897       clib_memcpy (mp->local_address_start, &laddr4_start,
11898                    sizeof (ip4_address_t));
11899       clib_memcpy (mp->local_address_stop, &laddr4_stop,
11900                    sizeof (ip4_address_t));
11901     }
11902   mp->protocol = (u8) protocol;
11903   mp->local_port_start = ntohs ((u16) lport_start);
11904   mp->local_port_stop = ntohs ((u16) lport_stop);
11905   mp->remote_port_start = ntohs ((u16) rport_start);
11906   mp->remote_port_stop = ntohs ((u16) rport_stop);
11907   mp->policy = (u8) policy;
11908   mp->sa_id = ntohl (sa_id);
11909   mp->is_add = is_add;
11910   mp->is_ip_any = is_ip_any;
11911   S (mp);
11912   W (ret);
11913   return ret;
11914 }
11915
11916 static int
11917 api_ipsec_sad_add_del_entry (vat_main_t * vam)
11918 {
11919   unformat_input_t *i = vam->input;
11920   vl_api_ipsec_sad_add_del_entry_t *mp;
11921   u32 sad_id = 0, spi = 0;
11922   u8 *ck = 0, *ik = 0;
11923   u8 is_add = 1;
11924
11925   u8 protocol = IPSEC_PROTOCOL_AH;
11926   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
11927   u32 crypto_alg = 0, integ_alg = 0;
11928   ip4_address_t tun_src4;
11929   ip4_address_t tun_dst4;
11930   ip6_address_t tun_src6;
11931   ip6_address_t tun_dst6;
11932   int ret;
11933
11934   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11935     {
11936       if (unformat (i, "del"))
11937         is_add = 0;
11938       else if (unformat (i, "sad_id %d", &sad_id))
11939         ;
11940       else if (unformat (i, "spi %d", &spi))
11941         ;
11942       else if (unformat (i, "esp"))
11943         protocol = IPSEC_PROTOCOL_ESP;
11944       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
11945         {
11946           is_tunnel = 1;
11947           is_tunnel_ipv6 = 0;
11948         }
11949       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
11950         {
11951           is_tunnel = 1;
11952           is_tunnel_ipv6 = 0;
11953         }
11954       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
11955         {
11956           is_tunnel = 1;
11957           is_tunnel_ipv6 = 1;
11958         }
11959       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
11960         {
11961           is_tunnel = 1;
11962           is_tunnel_ipv6 = 1;
11963         }
11964       else
11965         if (unformat
11966             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
11967         {
11968           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
11969               crypto_alg >= IPSEC_CRYPTO_N_ALG)
11970             {
11971               clib_warning ("unsupported crypto-alg: '%U'",
11972                             format_ipsec_crypto_alg, crypto_alg);
11973               return -99;
11974             }
11975         }
11976       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
11977         ;
11978       else
11979         if (unformat
11980             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
11981         {
11982           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
11983               integ_alg >= IPSEC_INTEG_N_ALG)
11984             {
11985               clib_warning ("unsupported integ-alg: '%U'",
11986                             format_ipsec_integ_alg, integ_alg);
11987               return -99;
11988             }
11989         }
11990       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
11991         ;
11992       else
11993         {
11994           clib_warning ("parse error '%U'", format_unformat_error, i);
11995           return -99;
11996         }
11997
11998     }
11999
12000   M (IPSEC_SAD_ADD_DEL_ENTRY, mp);
12001
12002   mp->sad_id = ntohl (sad_id);
12003   mp->is_add = is_add;
12004   mp->protocol = protocol;
12005   mp->spi = ntohl (spi);
12006   mp->is_tunnel = is_tunnel;
12007   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
12008   mp->crypto_algorithm = crypto_alg;
12009   mp->integrity_algorithm = integ_alg;
12010   mp->crypto_key_length = vec_len (ck);
12011   mp->integrity_key_length = vec_len (ik);
12012
12013   if (mp->crypto_key_length > sizeof (mp->crypto_key))
12014     mp->crypto_key_length = sizeof (mp->crypto_key);
12015
12016   if (mp->integrity_key_length > sizeof (mp->integrity_key))
12017     mp->integrity_key_length = sizeof (mp->integrity_key);
12018
12019   if (ck)
12020     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
12021   if (ik)
12022     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
12023
12024   if (is_tunnel)
12025     {
12026       if (is_tunnel_ipv6)
12027         {
12028           clib_memcpy (mp->tunnel_src_address, &tun_src6,
12029                        sizeof (ip6_address_t));
12030           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
12031                        sizeof (ip6_address_t));
12032         }
12033       else
12034         {
12035           clib_memcpy (mp->tunnel_src_address, &tun_src4,
12036                        sizeof (ip4_address_t));
12037           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
12038                        sizeof (ip4_address_t));
12039         }
12040     }
12041
12042   S (mp);
12043   W (ret);
12044   return ret;
12045 }
12046
12047 static int
12048 api_ipsec_sa_set_key (vat_main_t * vam)
12049 {
12050   unformat_input_t *i = vam->input;
12051   vl_api_ipsec_sa_set_key_t *mp;
12052   u32 sa_id;
12053   u8 *ck = 0, *ik = 0;
12054   int ret;
12055
12056   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12057     {
12058       if (unformat (i, "sa_id %d", &sa_id))
12059         ;
12060       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
12061         ;
12062       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
12063         ;
12064       else
12065         {
12066           clib_warning ("parse error '%U'", format_unformat_error, i);
12067           return -99;
12068         }
12069     }
12070
12071   M (IPSEC_SA_SET_KEY, mp);
12072
12073   mp->sa_id = ntohl (sa_id);
12074   mp->crypto_key_length = vec_len (ck);
12075   mp->integrity_key_length = vec_len (ik);
12076
12077   if (mp->crypto_key_length > sizeof (mp->crypto_key))
12078     mp->crypto_key_length = sizeof (mp->crypto_key);
12079
12080   if (mp->integrity_key_length > sizeof (mp->integrity_key))
12081     mp->integrity_key_length = sizeof (mp->integrity_key);
12082
12083   if (ck)
12084     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
12085   if (ik)
12086     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
12087
12088   S (mp);
12089   W (ret);
12090   return ret;
12091 }
12092
12093 static int
12094 api_ikev2_profile_add_del (vat_main_t * vam)
12095 {
12096   unformat_input_t *i = vam->input;
12097   vl_api_ikev2_profile_add_del_t *mp;
12098   u8 is_add = 1;
12099   u8 *name = 0;
12100   int ret;
12101
12102   const char *valid_chars = "a-zA-Z0-9_";
12103
12104   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12105     {
12106       if (unformat (i, "del"))
12107         is_add = 0;
12108       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12109         vec_add1 (name, 0);
12110       else
12111         {
12112           errmsg ("parse error '%U'", format_unformat_error, i);
12113           return -99;
12114         }
12115     }
12116
12117   if (!vec_len (name))
12118     {
12119       errmsg ("profile name must be specified");
12120       return -99;
12121     }
12122
12123   if (vec_len (name) > 64)
12124     {
12125       errmsg ("profile name too long");
12126       return -99;
12127     }
12128
12129   M (IKEV2_PROFILE_ADD_DEL, mp);
12130
12131   clib_memcpy (mp->name, name, vec_len (name));
12132   mp->is_add = is_add;
12133   vec_free (name);
12134
12135   S (mp);
12136   W (ret);
12137   return ret;
12138 }
12139
12140 static int
12141 api_ikev2_profile_set_auth (vat_main_t * vam)
12142 {
12143   unformat_input_t *i = vam->input;
12144   vl_api_ikev2_profile_set_auth_t *mp;
12145   u8 *name = 0;
12146   u8 *data = 0;
12147   u32 auth_method = 0;
12148   u8 is_hex = 0;
12149   int ret;
12150
12151   const char *valid_chars = "a-zA-Z0-9_";
12152
12153   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12154     {
12155       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12156         vec_add1 (name, 0);
12157       else if (unformat (i, "auth_method %U",
12158                          unformat_ikev2_auth_method, &auth_method))
12159         ;
12160       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
12161         is_hex = 1;
12162       else if (unformat (i, "auth_data %v", &data))
12163         ;
12164       else
12165         {
12166           errmsg ("parse error '%U'", format_unformat_error, i);
12167           return -99;
12168         }
12169     }
12170
12171   if (!vec_len (name))
12172     {
12173       errmsg ("profile name must be specified");
12174       return -99;
12175     }
12176
12177   if (vec_len (name) > 64)
12178     {
12179       errmsg ("profile name too long");
12180       return -99;
12181     }
12182
12183   if (!vec_len (data))
12184     {
12185       errmsg ("auth_data must be specified");
12186       return -99;
12187     }
12188
12189   if (!auth_method)
12190     {
12191       errmsg ("auth_method must be specified");
12192       return -99;
12193     }
12194
12195   M (IKEV2_PROFILE_SET_AUTH, mp);
12196
12197   mp->is_hex = is_hex;
12198   mp->auth_method = (u8) auth_method;
12199   mp->data_len = vec_len (data);
12200   clib_memcpy (mp->name, name, vec_len (name));
12201   clib_memcpy (mp->data, data, vec_len (data));
12202   vec_free (name);
12203   vec_free (data);
12204
12205   S (mp);
12206   W (ret);
12207   return ret;
12208 }
12209
12210 static int
12211 api_ikev2_profile_set_id (vat_main_t * vam)
12212 {
12213   unformat_input_t *i = vam->input;
12214   vl_api_ikev2_profile_set_id_t *mp;
12215   u8 *name = 0;
12216   u8 *data = 0;
12217   u8 is_local = 0;
12218   u32 id_type = 0;
12219   ip4_address_t ip4;
12220   int ret;
12221
12222   const char *valid_chars = "a-zA-Z0-9_";
12223
12224   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12225     {
12226       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12227         vec_add1 (name, 0);
12228       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
12229         ;
12230       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
12231         {
12232           data = vec_new (u8, 4);
12233           clib_memcpy (data, ip4.as_u8, 4);
12234         }
12235       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
12236         ;
12237       else if (unformat (i, "id_data %v", &data))
12238         ;
12239       else if (unformat (i, "local"))
12240         is_local = 1;
12241       else if (unformat (i, "remote"))
12242         is_local = 0;
12243       else
12244         {
12245           errmsg ("parse error '%U'", format_unformat_error, i);
12246           return -99;
12247         }
12248     }
12249
12250   if (!vec_len (name))
12251     {
12252       errmsg ("profile name must be specified");
12253       return -99;
12254     }
12255
12256   if (vec_len (name) > 64)
12257     {
12258       errmsg ("profile name too long");
12259       return -99;
12260     }
12261
12262   if (!vec_len (data))
12263     {
12264       errmsg ("id_data must be specified");
12265       return -99;
12266     }
12267
12268   if (!id_type)
12269     {
12270       errmsg ("id_type must be specified");
12271       return -99;
12272     }
12273
12274   M (IKEV2_PROFILE_SET_ID, mp);
12275
12276   mp->is_local = is_local;
12277   mp->id_type = (u8) id_type;
12278   mp->data_len = vec_len (data);
12279   clib_memcpy (mp->name, name, vec_len (name));
12280   clib_memcpy (mp->data, data, vec_len (data));
12281   vec_free (name);
12282   vec_free (data);
12283
12284   S (mp);
12285   W (ret);
12286   return ret;
12287 }
12288
12289 static int
12290 api_ikev2_profile_set_ts (vat_main_t * vam)
12291 {
12292   unformat_input_t *i = vam->input;
12293   vl_api_ikev2_profile_set_ts_t *mp;
12294   u8 *name = 0;
12295   u8 is_local = 0;
12296   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
12297   ip4_address_t start_addr, end_addr;
12298
12299   const char *valid_chars = "a-zA-Z0-9_";
12300   int ret;
12301
12302   start_addr.as_u32 = 0;
12303   end_addr.as_u32 = (u32) ~ 0;
12304
12305   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12306     {
12307       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12308         vec_add1 (name, 0);
12309       else if (unformat (i, "protocol %d", &proto))
12310         ;
12311       else if (unformat (i, "start_port %d", &start_port))
12312         ;
12313       else if (unformat (i, "end_port %d", &end_port))
12314         ;
12315       else
12316         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
12317         ;
12318       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
12319         ;
12320       else if (unformat (i, "local"))
12321         is_local = 1;
12322       else if (unformat (i, "remote"))
12323         is_local = 0;
12324       else
12325         {
12326           errmsg ("parse error '%U'", format_unformat_error, i);
12327           return -99;
12328         }
12329     }
12330
12331   if (!vec_len (name))
12332     {
12333       errmsg ("profile name must be specified");
12334       return -99;
12335     }
12336
12337   if (vec_len (name) > 64)
12338     {
12339       errmsg ("profile name too long");
12340       return -99;
12341     }
12342
12343   M (IKEV2_PROFILE_SET_TS, mp);
12344
12345   mp->is_local = is_local;
12346   mp->proto = (u8) proto;
12347   mp->start_port = (u16) start_port;
12348   mp->end_port = (u16) end_port;
12349   mp->start_addr = start_addr.as_u32;
12350   mp->end_addr = end_addr.as_u32;
12351   clib_memcpy (mp->name, name, vec_len (name));
12352   vec_free (name);
12353
12354   S (mp);
12355   W (ret);
12356   return ret;
12357 }
12358
12359 static int
12360 api_ikev2_set_local_key (vat_main_t * vam)
12361 {
12362   unformat_input_t *i = vam->input;
12363   vl_api_ikev2_set_local_key_t *mp;
12364   u8 *file = 0;
12365   int ret;
12366
12367   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12368     {
12369       if (unformat (i, "file %v", &file))
12370         vec_add1 (file, 0);
12371       else
12372         {
12373           errmsg ("parse error '%U'", format_unformat_error, i);
12374           return -99;
12375         }
12376     }
12377
12378   if (!vec_len (file))
12379     {
12380       errmsg ("RSA key file must be specified");
12381       return -99;
12382     }
12383
12384   if (vec_len (file) > 256)
12385     {
12386       errmsg ("file name too long");
12387       return -99;
12388     }
12389
12390   M (IKEV2_SET_LOCAL_KEY, mp);
12391
12392   clib_memcpy (mp->key_file, file, vec_len (file));
12393   vec_free (file);
12394
12395   S (mp);
12396   W (ret);
12397   return ret;
12398 }
12399
12400 static int
12401 api_ikev2_set_responder (vat_main_t * vam)
12402 {
12403   unformat_input_t *i = vam->input;
12404   vl_api_ikev2_set_responder_t *mp;
12405   int ret;
12406   u8 *name = 0;
12407   u32 sw_if_index = ~0;
12408   ip4_address_t address;
12409
12410   const char *valid_chars = "a-zA-Z0-9_";
12411
12412   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12413     {
12414       if (unformat
12415           (i, "%U interface %d address %U", unformat_token, valid_chars,
12416            &name, &sw_if_index, unformat_ip4_address, &address))
12417         vec_add1 (name, 0);
12418       else
12419         {
12420           errmsg ("parse error '%U'", format_unformat_error, i);
12421           return -99;
12422         }
12423     }
12424
12425   if (!vec_len (name))
12426     {
12427       errmsg ("profile name must be specified");
12428       return -99;
12429     }
12430
12431   if (vec_len (name) > 64)
12432     {
12433       errmsg ("profile name too long");
12434       return -99;
12435     }
12436
12437   M (IKEV2_SET_RESPONDER, mp);
12438
12439   clib_memcpy (mp->name, name, vec_len (name));
12440   vec_free (name);
12441
12442   mp->sw_if_index = sw_if_index;
12443   clib_memcpy (mp->address, &address, sizeof (address));
12444
12445   S (mp);
12446   W (ret);
12447   return ret;
12448 }
12449
12450 static int
12451 api_ikev2_set_ike_transforms (vat_main_t * vam)
12452 {
12453   unformat_input_t *i = vam->input;
12454   vl_api_ikev2_set_ike_transforms_t *mp;
12455   int ret;
12456   u8 *name = 0;
12457   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
12458
12459   const char *valid_chars = "a-zA-Z0-9_";
12460
12461   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12462     {
12463       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
12464                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
12465         vec_add1 (name, 0);
12466       else
12467         {
12468           errmsg ("parse error '%U'", format_unformat_error, i);
12469           return -99;
12470         }
12471     }
12472
12473   if (!vec_len (name))
12474     {
12475       errmsg ("profile name must be specified");
12476       return -99;
12477     }
12478
12479   if (vec_len (name) > 64)
12480     {
12481       errmsg ("profile name too long");
12482       return -99;
12483     }
12484
12485   M (IKEV2_SET_IKE_TRANSFORMS, mp);
12486
12487   clib_memcpy (mp->name, name, vec_len (name));
12488   vec_free (name);
12489   mp->crypto_alg = crypto_alg;
12490   mp->crypto_key_size = crypto_key_size;
12491   mp->integ_alg = integ_alg;
12492   mp->dh_group = dh_group;
12493
12494   S (mp);
12495   W (ret);
12496   return ret;
12497 }
12498
12499
12500 static int
12501 api_ikev2_set_esp_transforms (vat_main_t * vam)
12502 {
12503   unformat_input_t *i = vam->input;
12504   vl_api_ikev2_set_esp_transforms_t *mp;
12505   int ret;
12506   u8 *name = 0;
12507   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
12508
12509   const char *valid_chars = "a-zA-Z0-9_";
12510
12511   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12512     {
12513       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
12514                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
12515         vec_add1 (name, 0);
12516       else
12517         {
12518           errmsg ("parse error '%U'", format_unformat_error, i);
12519           return -99;
12520         }
12521     }
12522
12523   if (!vec_len (name))
12524     {
12525       errmsg ("profile name must be specified");
12526       return -99;
12527     }
12528
12529   if (vec_len (name) > 64)
12530     {
12531       errmsg ("profile name too long");
12532       return -99;
12533     }
12534
12535   M (IKEV2_SET_ESP_TRANSFORMS, mp);
12536
12537   clib_memcpy (mp->name, name, vec_len (name));
12538   vec_free (name);
12539   mp->crypto_alg = crypto_alg;
12540   mp->crypto_key_size = crypto_key_size;
12541   mp->integ_alg = integ_alg;
12542   mp->dh_group = dh_group;
12543
12544   S (mp);
12545   W (ret);
12546   return ret;
12547 }
12548
12549 static int
12550 api_ikev2_set_sa_lifetime (vat_main_t * vam)
12551 {
12552   unformat_input_t *i = vam->input;
12553   vl_api_ikev2_set_sa_lifetime_t *mp;
12554   int ret;
12555   u8 *name = 0;
12556   u64 lifetime, lifetime_maxdata;
12557   u32 lifetime_jitter, handover;
12558
12559   const char *valid_chars = "a-zA-Z0-9_";
12560
12561   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12562     {
12563       if (unformat (i, "%U %lu %u %u %lu", unformat_token, valid_chars, &name,
12564                     &lifetime, &lifetime_jitter, &handover,
12565                     &lifetime_maxdata))
12566         vec_add1 (name, 0);
12567       else
12568         {
12569           errmsg ("parse error '%U'", format_unformat_error, i);
12570           return -99;
12571         }
12572     }
12573
12574   if (!vec_len (name))
12575     {
12576       errmsg ("profile name must be specified");
12577       return -99;
12578     }
12579
12580   if (vec_len (name) > 64)
12581     {
12582       errmsg ("profile name too long");
12583       return -99;
12584     }
12585
12586   M (IKEV2_SET_SA_LIFETIME, mp);
12587
12588   clib_memcpy (mp->name, name, vec_len (name));
12589   vec_free (name);
12590   mp->lifetime = lifetime;
12591   mp->lifetime_jitter = lifetime_jitter;
12592   mp->handover = handover;
12593   mp->lifetime_maxdata = lifetime_maxdata;
12594
12595   S (mp);
12596   W (ret);
12597   return ret;
12598 }
12599
12600 static int
12601 api_ikev2_initiate_sa_init (vat_main_t * vam)
12602 {
12603   unformat_input_t *i = vam->input;
12604   vl_api_ikev2_initiate_sa_init_t *mp;
12605   int ret;
12606   u8 *name = 0;
12607
12608   const char *valid_chars = "a-zA-Z0-9_";
12609
12610   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12611     {
12612       if (unformat (i, "%U", unformat_token, valid_chars, &name))
12613         vec_add1 (name, 0);
12614       else
12615         {
12616           errmsg ("parse error '%U'", format_unformat_error, i);
12617           return -99;
12618         }
12619     }
12620
12621   if (!vec_len (name))
12622     {
12623       errmsg ("profile name must be specified");
12624       return -99;
12625     }
12626
12627   if (vec_len (name) > 64)
12628     {
12629       errmsg ("profile name too long");
12630       return -99;
12631     }
12632
12633   M (IKEV2_INITIATE_SA_INIT, mp);
12634
12635   clib_memcpy (mp->name, name, vec_len (name));
12636   vec_free (name);
12637
12638   S (mp);
12639   W (ret);
12640   return ret;
12641 }
12642
12643 static int
12644 api_ikev2_initiate_del_ike_sa (vat_main_t * vam)
12645 {
12646   unformat_input_t *i = vam->input;
12647   vl_api_ikev2_initiate_del_ike_sa_t *mp;
12648   int ret;
12649   u64 ispi;
12650
12651
12652   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12653     {
12654       if (unformat (i, "%lx", &ispi))
12655         ;
12656       else
12657         {
12658           errmsg ("parse error '%U'", format_unformat_error, i);
12659           return -99;
12660         }
12661     }
12662
12663   M (IKEV2_INITIATE_DEL_IKE_SA, mp);
12664
12665   mp->ispi = ispi;
12666
12667   S (mp);
12668   W (ret);
12669   return ret;
12670 }
12671
12672 static int
12673 api_ikev2_initiate_del_child_sa (vat_main_t * vam)
12674 {
12675   unformat_input_t *i = vam->input;
12676   vl_api_ikev2_initiate_del_child_sa_t *mp;
12677   int ret;
12678   u32 ispi;
12679
12680
12681   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12682     {
12683       if (unformat (i, "%x", &ispi))
12684         ;
12685       else
12686         {
12687           errmsg ("parse error '%U'", format_unformat_error, i);
12688           return -99;
12689         }
12690     }
12691
12692   M (IKEV2_INITIATE_DEL_CHILD_SA, mp);
12693
12694   mp->ispi = ispi;
12695
12696   S (mp);
12697   W (ret);
12698   return ret;
12699 }
12700
12701 static int
12702 api_ikev2_initiate_rekey_child_sa (vat_main_t * vam)
12703 {
12704   unformat_input_t *i = vam->input;
12705   vl_api_ikev2_initiate_rekey_child_sa_t *mp;
12706   int ret;
12707   u32 ispi;
12708
12709
12710   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12711     {
12712       if (unformat (i, "%x", &ispi))
12713         ;
12714       else
12715         {
12716           errmsg ("parse error '%U'", format_unformat_error, i);
12717           return -99;
12718         }
12719     }
12720
12721   M (IKEV2_INITIATE_REKEY_CHILD_SA, mp);
12722
12723   mp->ispi = ispi;
12724
12725   S (mp);
12726   W (ret);
12727   return ret;
12728 }
12729
12730 /*
12731  * MAP
12732  */
12733 static int
12734 api_map_add_domain (vat_main_t * vam)
12735 {
12736   unformat_input_t *i = vam->input;
12737   vl_api_map_add_domain_t *mp;
12738
12739   ip4_address_t ip4_prefix;
12740   ip6_address_t ip6_prefix;
12741   ip6_address_t ip6_src;
12742   u32 num_m_args = 0;
12743   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
12744     0, psid_length = 0;
12745   u8 is_translation = 0;
12746   u32 mtu = 0;
12747   u32 ip6_src_len = 128;
12748   int ret;
12749
12750   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12751     {
12752       if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
12753                     &ip4_prefix, &ip4_prefix_len))
12754         num_m_args++;
12755       else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
12756                          &ip6_prefix, &ip6_prefix_len))
12757         num_m_args++;
12758       else
12759         if (unformat
12760             (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
12761              &ip6_src_len))
12762         num_m_args++;
12763       else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
12764         num_m_args++;
12765       else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
12766         num_m_args++;
12767       else if (unformat (i, "psid-offset %d", &psid_offset))
12768         num_m_args++;
12769       else if (unformat (i, "psid-len %d", &psid_length))
12770         num_m_args++;
12771       else if (unformat (i, "mtu %d", &mtu))
12772         num_m_args++;
12773       else if (unformat (i, "map-t"))
12774         is_translation = 1;
12775       else
12776         {
12777           clib_warning ("parse error '%U'", format_unformat_error, i);
12778           return -99;
12779         }
12780     }
12781
12782   if (num_m_args < 3)
12783     {
12784       errmsg ("mandatory argument(s) missing");
12785       return -99;
12786     }
12787
12788   /* Construct the API message */
12789   M (MAP_ADD_DOMAIN, mp);
12790
12791   clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
12792   mp->ip4_prefix_len = ip4_prefix_len;
12793
12794   clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
12795   mp->ip6_prefix_len = ip6_prefix_len;
12796
12797   clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
12798   mp->ip6_src_prefix_len = ip6_src_len;
12799
12800   mp->ea_bits_len = ea_bits_len;
12801   mp->psid_offset = psid_offset;
12802   mp->psid_length = psid_length;
12803   mp->is_translation = is_translation;
12804   mp->mtu = htons (mtu);
12805
12806   /* send it... */
12807   S (mp);
12808
12809   /* Wait for a reply, return good/bad news  */
12810   W (ret);
12811   return ret;
12812 }
12813
12814 static int
12815 api_map_del_domain (vat_main_t * vam)
12816 {
12817   unformat_input_t *i = vam->input;
12818   vl_api_map_del_domain_t *mp;
12819
12820   u32 num_m_args = 0;
12821   u32 index;
12822   int ret;
12823
12824   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12825     {
12826       if (unformat (i, "index %d", &index))
12827         num_m_args++;
12828       else
12829         {
12830           clib_warning ("parse error '%U'", format_unformat_error, i);
12831           return -99;
12832         }
12833     }
12834
12835   if (num_m_args != 1)
12836     {
12837       errmsg ("mandatory argument(s) missing");
12838       return -99;
12839     }
12840
12841   /* Construct the API message */
12842   M (MAP_DEL_DOMAIN, mp);
12843
12844   mp->index = ntohl (index);
12845
12846   /* send it... */
12847   S (mp);
12848
12849   /* Wait for a reply, return good/bad news  */
12850   W (ret);
12851   return ret;
12852 }
12853
12854 static int
12855 api_map_add_del_rule (vat_main_t * vam)
12856 {
12857   unformat_input_t *i = vam->input;
12858   vl_api_map_add_del_rule_t *mp;
12859   u8 is_add = 1;
12860   ip6_address_t ip6_dst;
12861   u32 num_m_args = 0, index, psid = 0;
12862   int ret;
12863
12864   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12865     {
12866       if (unformat (i, "index %d", &index))
12867         num_m_args++;
12868       else if (unformat (i, "psid %d", &psid))
12869         num_m_args++;
12870       else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
12871         num_m_args++;
12872       else if (unformat (i, "del"))
12873         {
12874           is_add = 0;
12875         }
12876       else
12877         {
12878           clib_warning ("parse error '%U'", format_unformat_error, i);
12879           return -99;
12880         }
12881     }
12882
12883   /* Construct the API message */
12884   M (MAP_ADD_DEL_RULE, mp);
12885
12886   mp->index = ntohl (index);
12887   mp->is_add = is_add;
12888   clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
12889   mp->psid = ntohs (psid);
12890
12891   /* send it... */
12892   S (mp);
12893
12894   /* Wait for a reply, return good/bad news  */
12895   W (ret);
12896   return ret;
12897 }
12898
12899 static int
12900 api_map_domain_dump (vat_main_t * vam)
12901 {
12902   vl_api_map_domain_dump_t *mp;
12903   vl_api_control_ping_t *mp_ping;
12904   int ret;
12905
12906   /* Construct the API message */
12907   M (MAP_DOMAIN_DUMP, mp);
12908
12909   /* send it... */
12910   S (mp);
12911
12912   /* Use a control ping for synchronization */
12913   M (CONTROL_PING, mp_ping);
12914   S (mp_ping);
12915
12916   W (ret);
12917   return ret;
12918 }
12919
12920 static int
12921 api_map_rule_dump (vat_main_t * vam)
12922 {
12923   unformat_input_t *i = vam->input;
12924   vl_api_map_rule_dump_t *mp;
12925   vl_api_control_ping_t *mp_ping;
12926   u32 domain_index = ~0;
12927   int ret;
12928
12929   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12930     {
12931       if (unformat (i, "index %u", &domain_index))
12932         ;
12933       else
12934         break;
12935     }
12936
12937   if (domain_index == ~0)
12938     {
12939       clib_warning ("parse error: domain index expected");
12940       return -99;
12941     }
12942
12943   /* Construct the API message */
12944   M (MAP_RULE_DUMP, mp);
12945
12946   mp->domain_index = htonl (domain_index);
12947
12948   /* send it... */
12949   S (mp);
12950
12951   /* Use a control ping for synchronization */
12952   M (CONTROL_PING, mp_ping);
12953   S (mp_ping);
12954
12955   W (ret);
12956   return ret;
12957 }
12958
12959 static void vl_api_map_add_domain_reply_t_handler
12960   (vl_api_map_add_domain_reply_t * mp)
12961 {
12962   vat_main_t *vam = &vat_main;
12963   i32 retval = ntohl (mp->retval);
12964
12965   if (vam->async_mode)
12966     {
12967       vam->async_errors += (retval < 0);
12968     }
12969   else
12970     {
12971       vam->retval = retval;
12972       vam->result_ready = 1;
12973     }
12974 }
12975
12976 static void vl_api_map_add_domain_reply_t_handler_json
12977   (vl_api_map_add_domain_reply_t * mp)
12978 {
12979   vat_main_t *vam = &vat_main;
12980   vat_json_node_t node;
12981
12982   vat_json_init_object (&node);
12983   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
12984   vat_json_object_add_uint (&node, "index", ntohl (mp->index));
12985
12986   vat_json_print (vam->ofp, &node);
12987   vat_json_free (&node);
12988
12989   vam->retval = ntohl (mp->retval);
12990   vam->result_ready = 1;
12991 }
12992
12993 static int
12994 api_get_first_msg_id (vat_main_t * vam)
12995 {
12996   vl_api_get_first_msg_id_t *mp;
12997   unformat_input_t *i = vam->input;
12998   u8 *name;
12999   u8 name_set = 0;
13000   int ret;
13001
13002   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13003     {
13004       if (unformat (i, "client %s", &name))
13005         name_set = 1;
13006       else
13007         break;
13008     }
13009
13010   if (name_set == 0)
13011     {
13012       errmsg ("missing client name");
13013       return -99;
13014     }
13015   vec_add1 (name, 0);
13016
13017   if (vec_len (name) > 63)
13018     {
13019       errmsg ("client name too long");
13020       return -99;
13021     }
13022
13023   M (GET_FIRST_MSG_ID, mp);
13024   clib_memcpy (mp->name, name, vec_len (name));
13025   S (mp);
13026   W (ret);
13027   return ret;
13028 }
13029
13030 static int
13031 api_cop_interface_enable_disable (vat_main_t * vam)
13032 {
13033   unformat_input_t *line_input = vam->input;
13034   vl_api_cop_interface_enable_disable_t *mp;
13035   u32 sw_if_index = ~0;
13036   u8 enable_disable = 1;
13037   int ret;
13038
13039   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13040     {
13041       if (unformat (line_input, "disable"))
13042         enable_disable = 0;
13043       if (unformat (line_input, "enable"))
13044         enable_disable = 1;
13045       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
13046                          vam, &sw_if_index))
13047         ;
13048       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13049         ;
13050       else
13051         break;
13052     }
13053
13054   if (sw_if_index == ~0)
13055     {
13056       errmsg ("missing interface name or sw_if_index");
13057       return -99;
13058     }
13059
13060   /* Construct the API message */
13061   M (COP_INTERFACE_ENABLE_DISABLE, mp);
13062   mp->sw_if_index = ntohl (sw_if_index);
13063   mp->enable_disable = enable_disable;
13064
13065   /* send it... */
13066   S (mp);
13067   /* Wait for the reply */
13068   W (ret);
13069   return ret;
13070 }
13071
13072 static int
13073 api_cop_whitelist_enable_disable (vat_main_t * vam)
13074 {
13075   unformat_input_t *line_input = vam->input;
13076   vl_api_cop_whitelist_enable_disable_t *mp;
13077   u32 sw_if_index = ~0;
13078   u8 ip4 = 0, ip6 = 0, default_cop = 0;
13079   u32 fib_id = 0;
13080   int ret;
13081
13082   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13083     {
13084       if (unformat (line_input, "ip4"))
13085         ip4 = 1;
13086       else if (unformat (line_input, "ip6"))
13087         ip6 = 1;
13088       else if (unformat (line_input, "default"))
13089         default_cop = 1;
13090       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
13091                          vam, &sw_if_index))
13092         ;
13093       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13094         ;
13095       else if (unformat (line_input, "fib-id %d", &fib_id))
13096         ;
13097       else
13098         break;
13099     }
13100
13101   if (sw_if_index == ~0)
13102     {
13103       errmsg ("missing interface name or sw_if_index");
13104       return -99;
13105     }
13106
13107   /* Construct the API message */
13108   M (COP_WHITELIST_ENABLE_DISABLE, mp);
13109   mp->sw_if_index = ntohl (sw_if_index);
13110   mp->fib_id = ntohl (fib_id);
13111   mp->ip4 = ip4;
13112   mp->ip6 = ip6;
13113   mp->default_cop = default_cop;
13114
13115   /* send it... */
13116   S (mp);
13117   /* Wait for the reply */
13118   W (ret);
13119   return ret;
13120 }
13121
13122 static int
13123 api_get_node_graph (vat_main_t * vam)
13124 {
13125   vl_api_get_node_graph_t *mp;
13126   int ret;
13127
13128   M (GET_NODE_GRAPH, mp);
13129
13130   /* send it... */
13131   S (mp);
13132   /* Wait for the reply */
13133   W (ret);
13134   return ret;
13135 }
13136
13137 /* *INDENT-OFF* */
13138 /** Used for parsing LISP eids */
13139 typedef CLIB_PACKED(struct{
13140   u8 addr[16];   /**< eid address */
13141   u32 len;       /**< prefix length if IP */
13142   u8 type;      /**< type of eid */
13143 }) lisp_eid_vat_t;
13144 /* *INDENT-ON* */
13145
13146 static uword
13147 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
13148 {
13149   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
13150
13151   memset (a, 0, sizeof (a[0]));
13152
13153   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
13154     {
13155       a->type = 0;              /* ipv4 type */
13156     }
13157   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
13158     {
13159       a->type = 1;              /* ipv6 type */
13160     }
13161   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
13162     {
13163       a->type = 2;              /* mac type */
13164     }
13165   else
13166     {
13167       return 0;
13168     }
13169
13170   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
13171     {
13172       return 0;
13173     }
13174
13175   return 1;
13176 }
13177
13178 static int
13179 lisp_eid_size_vat (u8 type)
13180 {
13181   switch (type)
13182     {
13183     case 0:
13184       return 4;
13185     case 1:
13186       return 16;
13187     case 2:
13188       return 6;
13189     }
13190   return 0;
13191 }
13192
13193 static void
13194 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
13195 {
13196   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
13197 }
13198
13199 static int
13200 api_one_add_del_locator_set (vat_main_t * vam)
13201 {
13202   unformat_input_t *input = vam->input;
13203   vl_api_one_add_del_locator_set_t *mp;
13204   u8 is_add = 1;
13205   u8 *locator_set_name = NULL;
13206   u8 locator_set_name_set = 0;
13207   vl_api_local_locator_t locator, *locators = 0;
13208   u32 sw_if_index, priority, weight;
13209   u32 data_len = 0;
13210
13211   int ret;
13212   /* Parse args required to build the message */
13213   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13214     {
13215       if (unformat (input, "del"))
13216         {
13217           is_add = 0;
13218         }
13219       else if (unformat (input, "locator-set %s", &locator_set_name))
13220         {
13221           locator_set_name_set = 1;
13222         }
13223       else if (unformat (input, "sw_if_index %u p %u w %u",
13224                          &sw_if_index, &priority, &weight))
13225         {
13226           locator.sw_if_index = htonl (sw_if_index);
13227           locator.priority = priority;
13228           locator.weight = weight;
13229           vec_add1 (locators, locator);
13230         }
13231       else
13232         if (unformat
13233             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
13234              &sw_if_index, &priority, &weight))
13235         {
13236           locator.sw_if_index = htonl (sw_if_index);
13237           locator.priority = priority;
13238           locator.weight = weight;
13239           vec_add1 (locators, locator);
13240         }
13241       else
13242         break;
13243     }
13244
13245   if (locator_set_name_set == 0)
13246     {
13247       errmsg ("missing locator-set name");
13248       vec_free (locators);
13249       return -99;
13250     }
13251
13252   if (vec_len (locator_set_name) > 64)
13253     {
13254       errmsg ("locator-set name too long");
13255       vec_free (locator_set_name);
13256       vec_free (locators);
13257       return -99;
13258     }
13259   vec_add1 (locator_set_name, 0);
13260
13261   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
13262
13263   /* Construct the API message */
13264   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
13265
13266   mp->is_add = is_add;
13267   clib_memcpy (mp->locator_set_name, locator_set_name,
13268                vec_len (locator_set_name));
13269   vec_free (locator_set_name);
13270
13271   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
13272   if (locators)
13273     clib_memcpy (mp->locators, locators, data_len);
13274   vec_free (locators);
13275
13276   /* send it... */
13277   S (mp);
13278
13279   /* Wait for a reply... */
13280   W (ret);
13281   return ret;
13282 }
13283
13284 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
13285
13286 static int
13287 api_one_add_del_locator (vat_main_t * vam)
13288 {
13289   unformat_input_t *input = vam->input;
13290   vl_api_one_add_del_locator_t *mp;
13291   u32 tmp_if_index = ~0;
13292   u32 sw_if_index = ~0;
13293   u8 sw_if_index_set = 0;
13294   u8 sw_if_index_if_name_set = 0;
13295   u32 priority = ~0;
13296   u8 priority_set = 0;
13297   u32 weight = ~0;
13298   u8 weight_set = 0;
13299   u8 is_add = 1;
13300   u8 *locator_set_name = NULL;
13301   u8 locator_set_name_set = 0;
13302   int ret;
13303
13304   /* Parse args required to build the message */
13305   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13306     {
13307       if (unformat (input, "del"))
13308         {
13309           is_add = 0;
13310         }
13311       else if (unformat (input, "locator-set %s", &locator_set_name))
13312         {
13313           locator_set_name_set = 1;
13314         }
13315       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
13316                          &tmp_if_index))
13317         {
13318           sw_if_index_if_name_set = 1;
13319           sw_if_index = tmp_if_index;
13320         }
13321       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
13322         {
13323           sw_if_index_set = 1;
13324           sw_if_index = tmp_if_index;
13325         }
13326       else if (unformat (input, "p %d", &priority))
13327         {
13328           priority_set = 1;
13329         }
13330       else if (unformat (input, "w %d", &weight))
13331         {
13332           weight_set = 1;
13333         }
13334       else
13335         break;
13336     }
13337
13338   if (locator_set_name_set == 0)
13339     {
13340       errmsg ("missing locator-set name");
13341       return -99;
13342     }
13343
13344   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
13345     {
13346       errmsg ("missing sw_if_index");
13347       vec_free (locator_set_name);
13348       return -99;
13349     }
13350
13351   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
13352     {
13353       errmsg ("cannot use both params interface name and sw_if_index");
13354       vec_free (locator_set_name);
13355       return -99;
13356     }
13357
13358   if (priority_set == 0)
13359     {
13360       errmsg ("missing locator-set priority");
13361       vec_free (locator_set_name);
13362       return -99;
13363     }
13364
13365   if (weight_set == 0)
13366     {
13367       errmsg ("missing locator-set weight");
13368       vec_free (locator_set_name);
13369       return -99;
13370     }
13371
13372   if (vec_len (locator_set_name) > 64)
13373     {
13374       errmsg ("locator-set name too long");
13375       vec_free (locator_set_name);
13376       return -99;
13377     }
13378   vec_add1 (locator_set_name, 0);
13379
13380   /* Construct the API message */
13381   M (ONE_ADD_DEL_LOCATOR, mp);
13382
13383   mp->is_add = is_add;
13384   mp->sw_if_index = ntohl (sw_if_index);
13385   mp->priority = priority;
13386   mp->weight = weight;
13387   clib_memcpy (mp->locator_set_name, locator_set_name,
13388                vec_len (locator_set_name));
13389   vec_free (locator_set_name);
13390
13391   /* send it... */
13392   S (mp);
13393
13394   /* Wait for a reply... */
13395   W (ret);
13396   return ret;
13397 }
13398
13399 #define api_lisp_add_del_locator api_one_add_del_locator
13400
13401 uword
13402 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
13403 {
13404   u32 *key_id = va_arg (*args, u32 *);
13405   u8 *s = 0;
13406
13407   if (unformat (input, "%s", &s))
13408     {
13409       if (!strcmp ((char *) s, "sha1"))
13410         key_id[0] = HMAC_SHA_1_96;
13411       else if (!strcmp ((char *) s, "sha256"))
13412         key_id[0] = HMAC_SHA_256_128;
13413       else
13414         {
13415           clib_warning ("invalid key_id: '%s'", s);
13416           key_id[0] = HMAC_NO_KEY;
13417         }
13418     }
13419   else
13420     return 0;
13421
13422   vec_free (s);
13423   return 1;
13424 }
13425
13426 static int
13427 api_one_add_del_local_eid (vat_main_t * vam)
13428 {
13429   unformat_input_t *input = vam->input;
13430   vl_api_one_add_del_local_eid_t *mp;
13431   u8 is_add = 1;
13432   u8 eid_set = 0;
13433   lisp_eid_vat_t _eid, *eid = &_eid;
13434   u8 *locator_set_name = 0;
13435   u8 locator_set_name_set = 0;
13436   u32 vni = 0;
13437   u16 key_id = 0;
13438   u8 *key = 0;
13439   int ret;
13440
13441   /* Parse args required to build the message */
13442   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13443     {
13444       if (unformat (input, "del"))
13445         {
13446           is_add = 0;
13447         }
13448       else if (unformat (input, "vni %d", &vni))
13449         {
13450           ;
13451         }
13452       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
13453         {
13454           eid_set = 1;
13455         }
13456       else if (unformat (input, "locator-set %s", &locator_set_name))
13457         {
13458           locator_set_name_set = 1;
13459         }
13460       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
13461         ;
13462       else if (unformat (input, "secret-key %_%v%_", &key))
13463         ;
13464       else
13465         break;
13466     }
13467
13468   if (locator_set_name_set == 0)
13469     {
13470       errmsg ("missing locator-set name");
13471       return -99;
13472     }
13473
13474   if (0 == eid_set)
13475     {
13476       errmsg ("EID address not set!");
13477       vec_free (locator_set_name);
13478       return -99;
13479     }
13480
13481   if (key && (0 == key_id))
13482     {
13483       errmsg ("invalid key_id!");
13484       return -99;
13485     }
13486
13487   if (vec_len (key) > 64)
13488     {
13489       errmsg ("key too long");
13490       vec_free (key);
13491       return -99;
13492     }
13493
13494   if (vec_len (locator_set_name) > 64)
13495     {
13496       errmsg ("locator-set name too long");
13497       vec_free (locator_set_name);
13498       return -99;
13499     }
13500   vec_add1 (locator_set_name, 0);
13501
13502   /* Construct the API message */
13503   M (ONE_ADD_DEL_LOCAL_EID, mp);
13504
13505   mp->is_add = is_add;
13506   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
13507   mp->eid_type = eid->type;
13508   mp->prefix_len = eid->len;
13509   mp->vni = clib_host_to_net_u32 (vni);
13510   mp->key_id = clib_host_to_net_u16 (key_id);
13511   clib_memcpy (mp->locator_set_name, locator_set_name,
13512                vec_len (locator_set_name));
13513   clib_memcpy (mp->key, key, vec_len (key));
13514
13515   vec_free (locator_set_name);
13516   vec_free (key);
13517
13518   /* send it... */
13519   S (mp);
13520
13521   /* Wait for a reply... */
13522   W (ret);
13523   return ret;
13524 }
13525
13526 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
13527
13528 static int
13529 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
13530 {
13531   u32 dp_table = 0, vni = 0;;
13532   unformat_input_t *input = vam->input;
13533   vl_api_gpe_add_del_fwd_entry_t *mp;
13534   u8 is_add = 1;
13535   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
13536   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
13537   u8 rmt_eid_set = 0, lcl_eid_set = 0;
13538   u32 action = ~0, w;
13539   ip4_address_t rmt_rloc4, lcl_rloc4;
13540   ip6_address_t rmt_rloc6, lcl_rloc6;
13541   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
13542   int ret;
13543
13544   memset (&rloc, 0, sizeof (rloc));
13545
13546   /* Parse args required to build the message */
13547   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13548     {
13549       if (unformat (input, "del"))
13550         is_add = 0;
13551       else if (unformat (input, "add"))
13552         is_add = 1;
13553       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
13554         {
13555           rmt_eid_set = 1;
13556         }
13557       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
13558         {
13559           lcl_eid_set = 1;
13560         }
13561       else if (unformat (input, "vrf %d", &dp_table))
13562         ;
13563       else if (unformat (input, "bd %d", &dp_table))
13564         ;
13565       else if (unformat (input, "vni %d", &vni))
13566         ;
13567       else if (unformat (input, "w %d", &w))
13568         {
13569           if (!curr_rloc)
13570             {
13571               errmsg ("No RLOC configured for setting priority/weight!");
13572               return -99;
13573             }
13574           curr_rloc->weight = w;
13575         }
13576       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
13577                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
13578         {
13579           rloc.is_ip4 = 1;
13580
13581           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
13582           rloc.weight = 0;
13583           vec_add1 (lcl_locs, rloc);
13584
13585           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
13586           vec_add1 (rmt_locs, rloc);
13587           /* weight saved in rmt loc */
13588           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
13589         }
13590       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
13591                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
13592         {
13593           rloc.is_ip4 = 0;
13594           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
13595           rloc.weight = 0;
13596           vec_add1 (lcl_locs, rloc);
13597
13598           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
13599           vec_add1 (rmt_locs, rloc);
13600           /* weight saved in rmt loc */
13601           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
13602         }
13603       else if (unformat (input, "action %d", &action))
13604         {
13605           ;
13606         }
13607       else
13608         {
13609           clib_warning ("parse error '%U'", format_unformat_error, input);
13610           return -99;
13611         }
13612     }
13613
13614   if (!rmt_eid_set)
13615     {
13616       errmsg ("remote eid addresses not set");
13617       return -99;
13618     }
13619
13620   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
13621     {
13622       errmsg ("eid types don't match");
13623       return -99;
13624     }
13625
13626   if (0 == rmt_locs && (u32) ~ 0 == action)
13627     {
13628       errmsg ("action not set for negative mapping");
13629       return -99;
13630     }
13631
13632   /* Construct the API message */
13633   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
13634       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
13635
13636   mp->is_add = is_add;
13637   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
13638   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
13639   mp->eid_type = rmt_eid->type;
13640   mp->dp_table = clib_host_to_net_u32 (dp_table);
13641   mp->vni = clib_host_to_net_u32 (vni);
13642   mp->rmt_len = rmt_eid->len;
13643   mp->lcl_len = lcl_eid->len;
13644   mp->action = action;
13645
13646   if (0 != rmt_locs && 0 != lcl_locs)
13647     {
13648       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
13649       clib_memcpy (mp->locs, lcl_locs,
13650                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
13651
13652       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
13653       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
13654                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
13655     }
13656   vec_free (lcl_locs);
13657   vec_free (rmt_locs);
13658
13659   /* send it... */
13660   S (mp);
13661
13662   /* Wait for a reply... */
13663   W (ret);
13664   return ret;
13665 }
13666
13667 static int
13668 api_one_add_del_map_server (vat_main_t * vam)
13669 {
13670   unformat_input_t *input = vam->input;
13671   vl_api_one_add_del_map_server_t *mp;
13672   u8 is_add = 1;
13673   u8 ipv4_set = 0;
13674   u8 ipv6_set = 0;
13675   ip4_address_t ipv4;
13676   ip6_address_t ipv6;
13677   int ret;
13678
13679   /* Parse args required to build the message */
13680   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13681     {
13682       if (unformat (input, "del"))
13683         {
13684           is_add = 0;
13685         }
13686       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
13687         {
13688           ipv4_set = 1;
13689         }
13690       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
13691         {
13692           ipv6_set = 1;
13693         }
13694       else
13695         break;
13696     }
13697
13698   if (ipv4_set && ipv6_set)
13699     {
13700       errmsg ("both eid v4 and v6 addresses set");
13701       return -99;
13702     }
13703
13704   if (!ipv4_set && !ipv6_set)
13705     {
13706       errmsg ("eid addresses not set");
13707       return -99;
13708     }
13709
13710   /* Construct the API message */
13711   M (ONE_ADD_DEL_MAP_SERVER, mp);
13712
13713   mp->is_add = is_add;
13714   if (ipv6_set)
13715     {
13716       mp->is_ipv6 = 1;
13717       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
13718     }
13719   else
13720     {
13721       mp->is_ipv6 = 0;
13722       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
13723     }
13724
13725   /* send it... */
13726   S (mp);
13727
13728   /* Wait for a reply... */
13729   W (ret);
13730   return ret;
13731 }
13732
13733 #define api_lisp_add_del_map_server api_one_add_del_map_server
13734
13735 static int
13736 api_one_add_del_map_resolver (vat_main_t * vam)
13737 {
13738   unformat_input_t *input = vam->input;
13739   vl_api_one_add_del_map_resolver_t *mp;
13740   u8 is_add = 1;
13741   u8 ipv4_set = 0;
13742   u8 ipv6_set = 0;
13743   ip4_address_t ipv4;
13744   ip6_address_t ipv6;
13745   int ret;
13746
13747   /* Parse args required to build the message */
13748   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13749     {
13750       if (unformat (input, "del"))
13751         {
13752           is_add = 0;
13753         }
13754       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
13755         {
13756           ipv4_set = 1;
13757         }
13758       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
13759         {
13760           ipv6_set = 1;
13761         }
13762       else
13763         break;
13764     }
13765
13766   if (ipv4_set && ipv6_set)
13767     {
13768       errmsg ("both eid v4 and v6 addresses set");
13769       return -99;
13770     }
13771
13772   if (!ipv4_set && !ipv6_set)
13773     {
13774       errmsg ("eid addresses not set");
13775       return -99;
13776     }
13777
13778   /* Construct the API message */
13779   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
13780
13781   mp->is_add = is_add;
13782   if (ipv6_set)
13783     {
13784       mp->is_ipv6 = 1;
13785       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
13786     }
13787   else
13788     {
13789       mp->is_ipv6 = 0;
13790       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
13791     }
13792
13793   /* send it... */
13794   S (mp);
13795
13796   /* Wait for a reply... */
13797   W (ret);
13798   return ret;
13799 }
13800
13801 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
13802
13803 static int
13804 api_lisp_gpe_enable_disable (vat_main_t * vam)
13805 {
13806   unformat_input_t *input = vam->input;
13807   vl_api_gpe_enable_disable_t *mp;
13808   u8 is_set = 0;
13809   u8 is_en = 1;
13810   int ret;
13811
13812   /* Parse args required to build the message */
13813   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13814     {
13815       if (unformat (input, "enable"))
13816         {
13817           is_set = 1;
13818           is_en = 1;
13819         }
13820       else if (unformat (input, "disable"))
13821         {
13822           is_set = 1;
13823           is_en = 0;
13824         }
13825       else
13826         break;
13827     }
13828
13829   if (is_set == 0)
13830     {
13831       errmsg ("Value not set");
13832       return -99;
13833     }
13834
13835   /* Construct the API message */
13836   M (GPE_ENABLE_DISABLE, mp);
13837
13838   mp->is_en = is_en;
13839
13840   /* send it... */
13841   S (mp);
13842
13843   /* Wait for a reply... */
13844   W (ret);
13845   return ret;
13846 }
13847
13848 static int
13849 api_one_rloc_probe_enable_disable (vat_main_t * vam)
13850 {
13851   unformat_input_t *input = vam->input;
13852   vl_api_one_rloc_probe_enable_disable_t *mp;
13853   u8 is_set = 0;
13854   u8 is_en = 0;
13855   int ret;
13856
13857   /* Parse args required to build the message */
13858   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13859     {
13860       if (unformat (input, "enable"))
13861         {
13862           is_set = 1;
13863           is_en = 1;
13864         }
13865       else if (unformat (input, "disable"))
13866         is_set = 1;
13867       else
13868         break;
13869     }
13870
13871   if (!is_set)
13872     {
13873       errmsg ("Value not set");
13874       return -99;
13875     }
13876
13877   /* Construct the API message */
13878   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
13879
13880   mp->is_enabled = is_en;
13881
13882   /* send it... */
13883   S (mp);
13884
13885   /* Wait for a reply... */
13886   W (ret);
13887   return ret;
13888 }
13889
13890 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
13891
13892 static int
13893 api_one_map_register_enable_disable (vat_main_t * vam)
13894 {
13895   unformat_input_t *input = vam->input;
13896   vl_api_one_map_register_enable_disable_t *mp;
13897   u8 is_set = 0;
13898   u8 is_en = 0;
13899   int ret;
13900
13901   /* Parse args required to build the message */
13902   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13903     {
13904       if (unformat (input, "enable"))
13905         {
13906           is_set = 1;
13907           is_en = 1;
13908         }
13909       else if (unformat (input, "disable"))
13910         is_set = 1;
13911       else
13912         break;
13913     }
13914
13915   if (!is_set)
13916     {
13917       errmsg ("Value not set");
13918       return -99;
13919     }
13920
13921   /* Construct the API message */
13922   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
13923
13924   mp->is_enabled = is_en;
13925
13926   /* send it... */
13927   S (mp);
13928
13929   /* Wait for a reply... */
13930   W (ret);
13931   return ret;
13932 }
13933
13934 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
13935
13936 static int
13937 api_one_enable_disable (vat_main_t * vam)
13938 {
13939   unformat_input_t *input = vam->input;
13940   vl_api_one_enable_disable_t *mp;
13941   u8 is_set = 0;
13942   u8 is_en = 0;
13943   int ret;
13944
13945   /* Parse args required to build the message */
13946   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13947     {
13948       if (unformat (input, "enable"))
13949         {
13950           is_set = 1;
13951           is_en = 1;
13952         }
13953       else if (unformat (input, "disable"))
13954         {
13955           is_set = 1;
13956         }
13957       else
13958         break;
13959     }
13960
13961   if (!is_set)
13962     {
13963       errmsg ("Value not set");
13964       return -99;
13965     }
13966
13967   /* Construct the API message */
13968   M (ONE_ENABLE_DISABLE, mp);
13969
13970   mp->is_en = is_en;
13971
13972   /* send it... */
13973   S (mp);
13974
13975   /* Wait for a reply... */
13976   W (ret);
13977   return ret;
13978 }
13979
13980 #define api_lisp_enable_disable api_one_enable_disable
13981
13982 static int
13983 api_show_one_map_register_state (vat_main_t * vam)
13984 {
13985   vl_api_show_one_map_register_state_t *mp;
13986   int ret;
13987
13988   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
13989
13990   /* send */
13991   S (mp);
13992
13993   /* wait for reply */
13994   W (ret);
13995   return ret;
13996 }
13997
13998 #define api_show_lisp_map_register_state api_show_one_map_register_state
13999
14000 static int
14001 api_show_one_rloc_probe_state (vat_main_t * vam)
14002 {
14003   vl_api_show_one_rloc_probe_state_t *mp;
14004   int ret;
14005
14006   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
14007
14008   /* send */
14009   S (mp);
14010
14011   /* wait for reply */
14012   W (ret);
14013   return ret;
14014 }
14015
14016 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
14017
14018 static int
14019 api_show_one_map_request_mode (vat_main_t * vam)
14020 {
14021   vl_api_show_one_map_request_mode_t *mp;
14022   int ret;
14023
14024   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
14025
14026   /* send */
14027   S (mp);
14028
14029   /* wait for reply */
14030   W (ret);
14031   return ret;
14032 }
14033
14034 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
14035
14036 static int
14037 api_one_map_request_mode (vat_main_t * vam)
14038 {
14039   unformat_input_t *input = vam->input;
14040   vl_api_one_map_request_mode_t *mp;
14041   u8 mode = 0;
14042   int ret;
14043
14044   /* Parse args required to build the message */
14045   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14046     {
14047       if (unformat (input, "dst-only"))
14048         mode = 0;
14049       else if (unformat (input, "src-dst"))
14050         mode = 1;
14051       else
14052         {
14053           errmsg ("parse error '%U'", format_unformat_error, input);
14054           return -99;
14055         }
14056     }
14057
14058   M (ONE_MAP_REQUEST_MODE, mp);
14059
14060   mp->mode = mode;
14061
14062   /* send */
14063   S (mp);
14064
14065   /* wait for reply */
14066   W (ret);
14067   return ret;
14068 }
14069
14070 #define api_lisp_map_request_mode api_one_map_request_mode
14071
14072 /**
14073  * Enable/disable ONE proxy ITR.
14074  *
14075  * @param vam vpp API test context
14076  * @return return code
14077  */
14078 static int
14079 api_one_pitr_set_locator_set (vat_main_t * vam)
14080 {
14081   u8 ls_name_set = 0;
14082   unformat_input_t *input = vam->input;
14083   vl_api_one_pitr_set_locator_set_t *mp;
14084   u8 is_add = 1;
14085   u8 *ls_name = 0;
14086   int ret;
14087
14088   /* Parse args required to build the message */
14089   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14090     {
14091       if (unformat (input, "del"))
14092         is_add = 0;
14093       else if (unformat (input, "locator-set %s", &ls_name))
14094         ls_name_set = 1;
14095       else
14096         {
14097           errmsg ("parse error '%U'", format_unformat_error, input);
14098           return -99;
14099         }
14100     }
14101
14102   if (!ls_name_set)
14103     {
14104       errmsg ("locator-set name not set!");
14105       return -99;
14106     }
14107
14108   M (ONE_PITR_SET_LOCATOR_SET, mp);
14109
14110   mp->is_add = is_add;
14111   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
14112   vec_free (ls_name);
14113
14114   /* send */
14115   S (mp);
14116
14117   /* wait for reply */
14118   W (ret);
14119   return ret;
14120 }
14121
14122 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
14123
14124 static int
14125 api_show_one_pitr (vat_main_t * vam)
14126 {
14127   vl_api_show_one_pitr_t *mp;
14128   int ret;
14129
14130   if (!vam->json_output)
14131     {
14132       print (vam->ofp, "%=20s", "lisp status:");
14133     }
14134
14135   M (SHOW_ONE_PITR, mp);
14136   /* send it... */
14137   S (mp);
14138
14139   /* Wait for a reply... */
14140   W (ret);
14141   return ret;
14142 }
14143
14144 #define api_show_lisp_pitr api_show_one_pitr
14145
14146 /**
14147  * Add/delete mapping between vni and vrf
14148  */
14149 static int
14150 api_one_eid_table_add_del_map (vat_main_t * vam)
14151 {
14152   unformat_input_t *input = vam->input;
14153   vl_api_one_eid_table_add_del_map_t *mp;
14154   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
14155   u32 vni, vrf, bd_index;
14156   int ret;
14157
14158   /* Parse args required to build the message */
14159   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14160     {
14161       if (unformat (input, "del"))
14162         is_add = 0;
14163       else if (unformat (input, "vrf %d", &vrf))
14164         vrf_set = 1;
14165       else if (unformat (input, "bd_index %d", &bd_index))
14166         bd_index_set = 1;
14167       else if (unformat (input, "vni %d", &vni))
14168         vni_set = 1;
14169       else
14170         break;
14171     }
14172
14173   if (!vni_set || (!vrf_set && !bd_index_set))
14174     {
14175       errmsg ("missing arguments!");
14176       return -99;
14177     }
14178
14179   if (vrf_set && bd_index_set)
14180     {
14181       errmsg ("error: both vrf and bd entered!");
14182       return -99;
14183     }
14184
14185   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
14186
14187   mp->is_add = is_add;
14188   mp->vni = htonl (vni);
14189   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
14190   mp->is_l2 = bd_index_set;
14191
14192   /* send */
14193   S (mp);
14194
14195   /* wait for reply */
14196   W (ret);
14197   return ret;
14198 }
14199
14200 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
14201
14202 uword
14203 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
14204 {
14205   u32 *action = va_arg (*args, u32 *);
14206   u8 *s = 0;
14207
14208   if (unformat (input, "%s", &s))
14209     {
14210       if (!strcmp ((char *) s, "no-action"))
14211         action[0] = 0;
14212       else if (!strcmp ((char *) s, "natively-forward"))
14213         action[0] = 1;
14214       else if (!strcmp ((char *) s, "send-map-request"))
14215         action[0] = 2;
14216       else if (!strcmp ((char *) s, "drop"))
14217         action[0] = 3;
14218       else
14219         {
14220           clib_warning ("invalid action: '%s'", s);
14221           action[0] = 3;
14222         }
14223     }
14224   else
14225     return 0;
14226
14227   vec_free (s);
14228   return 1;
14229 }
14230
14231 /**
14232  * Add/del remote mapping to/from ONE control plane
14233  *
14234  * @param vam vpp API test context
14235  * @return return code
14236  */
14237 static int
14238 api_one_add_del_remote_mapping (vat_main_t * vam)
14239 {
14240   unformat_input_t *input = vam->input;
14241   vl_api_one_add_del_remote_mapping_t *mp;
14242   u32 vni = 0;
14243   lisp_eid_vat_t _eid, *eid = &_eid;
14244   lisp_eid_vat_t _seid, *seid = &_seid;
14245   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
14246   u32 action = ~0, p, w, data_len;
14247   ip4_address_t rloc4;
14248   ip6_address_t rloc6;
14249   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
14250   int ret;
14251
14252   memset (&rloc, 0, sizeof (rloc));
14253
14254   /* Parse args required to build the message */
14255   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14256     {
14257       if (unformat (input, "del-all"))
14258         {
14259           del_all = 1;
14260         }
14261       else if (unformat (input, "del"))
14262         {
14263           is_add = 0;
14264         }
14265       else if (unformat (input, "add"))
14266         {
14267           is_add = 1;
14268         }
14269       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
14270         {
14271           eid_set = 1;
14272         }
14273       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
14274         {
14275           seid_set = 1;
14276         }
14277       else if (unformat (input, "vni %d", &vni))
14278         {
14279           ;
14280         }
14281       else if (unformat (input, "p %d w %d", &p, &w))
14282         {
14283           if (!curr_rloc)
14284             {
14285               errmsg ("No RLOC configured for setting priority/weight!");
14286               return -99;
14287             }
14288           curr_rloc->priority = p;
14289           curr_rloc->weight = w;
14290         }
14291       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
14292         {
14293           rloc.is_ip4 = 1;
14294           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
14295           vec_add1 (rlocs, rloc);
14296           curr_rloc = &rlocs[vec_len (rlocs) - 1];
14297         }
14298       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
14299         {
14300           rloc.is_ip4 = 0;
14301           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
14302           vec_add1 (rlocs, rloc);
14303           curr_rloc = &rlocs[vec_len (rlocs) - 1];
14304         }
14305       else if (unformat (input, "action %U",
14306                          unformat_negative_mapping_action, &action))
14307         {
14308           ;
14309         }
14310       else
14311         {
14312           clib_warning ("parse error '%U'", format_unformat_error, input);
14313           return -99;
14314         }
14315     }
14316
14317   if (0 == eid_set)
14318     {
14319       errmsg ("missing params!");
14320       return -99;
14321     }
14322
14323   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
14324     {
14325       errmsg ("no action set for negative map-reply!");
14326       return -99;
14327     }
14328
14329   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
14330
14331   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
14332   mp->is_add = is_add;
14333   mp->vni = htonl (vni);
14334   mp->action = (u8) action;
14335   mp->is_src_dst = seid_set;
14336   mp->eid_len = eid->len;
14337   mp->seid_len = seid->len;
14338   mp->del_all = del_all;
14339   mp->eid_type = eid->type;
14340   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
14341   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
14342
14343   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
14344   clib_memcpy (mp->rlocs, rlocs, data_len);
14345   vec_free (rlocs);
14346
14347   /* send it... */
14348   S (mp);
14349
14350   /* Wait for a reply... */
14351   W (ret);
14352   return ret;
14353 }
14354
14355 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
14356
14357 /**
14358  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
14359  * forwarding entries in data-plane accordingly.
14360  *
14361  * @param vam vpp API test context
14362  * @return return code
14363  */
14364 static int
14365 api_one_add_del_adjacency (vat_main_t * vam)
14366 {
14367   unformat_input_t *input = vam->input;
14368   vl_api_one_add_del_adjacency_t *mp;
14369   u32 vni = 0;
14370   ip4_address_t leid4, reid4;
14371   ip6_address_t leid6, reid6;
14372   u8 reid_mac[6] = { 0 };
14373   u8 leid_mac[6] = { 0 };
14374   u8 reid_type, leid_type;
14375   u32 leid_len = 0, reid_len = 0, len;
14376   u8 is_add = 1;
14377   int ret;
14378
14379   leid_type = reid_type = (u8) ~ 0;
14380
14381   /* Parse args required to build the message */
14382   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14383     {
14384       if (unformat (input, "del"))
14385         {
14386           is_add = 0;
14387         }
14388       else if (unformat (input, "add"))
14389         {
14390           is_add = 1;
14391         }
14392       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
14393                          &reid4, &len))
14394         {
14395           reid_type = 0;        /* ipv4 */
14396           reid_len = len;
14397         }
14398       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
14399                          &reid6, &len))
14400         {
14401           reid_type = 1;        /* ipv6 */
14402           reid_len = len;
14403         }
14404       else if (unformat (input, "reid %U", unformat_ethernet_address,
14405                          reid_mac))
14406         {
14407           reid_type = 2;        /* mac */
14408         }
14409       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
14410                          &leid4, &len))
14411         {
14412           leid_type = 0;        /* ipv4 */
14413           leid_len = len;
14414         }
14415       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
14416                          &leid6, &len))
14417         {
14418           leid_type = 1;        /* ipv6 */
14419           leid_len = len;
14420         }
14421       else if (unformat (input, "leid %U", unformat_ethernet_address,
14422                          leid_mac))
14423         {
14424           leid_type = 2;        /* mac */
14425         }
14426       else if (unformat (input, "vni %d", &vni))
14427         {
14428           ;
14429         }
14430       else
14431         {
14432           errmsg ("parse error '%U'", format_unformat_error, input);
14433           return -99;
14434         }
14435     }
14436
14437   if ((u8) ~ 0 == reid_type)
14438     {
14439       errmsg ("missing params!");
14440       return -99;
14441     }
14442
14443   if (leid_type != reid_type)
14444     {
14445       errmsg ("remote and local EIDs are of different types!");
14446       return -99;
14447     }
14448
14449   M (ONE_ADD_DEL_ADJACENCY, mp);
14450   mp->is_add = is_add;
14451   mp->vni = htonl (vni);
14452   mp->leid_len = leid_len;
14453   mp->reid_len = reid_len;
14454   mp->eid_type = reid_type;
14455
14456   switch (mp->eid_type)
14457     {
14458     case 0:
14459       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
14460       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
14461       break;
14462     case 1:
14463       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
14464       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
14465       break;
14466     case 2:
14467       clib_memcpy (mp->leid, leid_mac, 6);
14468       clib_memcpy (mp->reid, reid_mac, 6);
14469       break;
14470     default:
14471       errmsg ("unknown EID type %d!", mp->eid_type);
14472       return 0;
14473     }
14474
14475   /* send it... */
14476   S (mp);
14477
14478   /* Wait for a reply... */
14479   W (ret);
14480   return ret;
14481 }
14482
14483 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
14484
14485 uword
14486 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
14487 {
14488   u32 *mode = va_arg (*args, u32 *);
14489
14490   if (unformat (input, "lisp"))
14491     *mode = 0;
14492   else if (unformat (input, "vxlan"))
14493     *mode = 1;
14494   else
14495     return 0;
14496
14497   return 1;
14498 }
14499
14500 static int
14501 api_gpe_get_encap_mode (vat_main_t * vam)
14502 {
14503   vl_api_gpe_get_encap_mode_t *mp;
14504   int ret;
14505
14506   /* Construct the API message */
14507   M (GPE_GET_ENCAP_MODE, mp);
14508
14509   /* send it... */
14510   S (mp);
14511
14512   /* Wait for a reply... */
14513   W (ret);
14514   return ret;
14515 }
14516
14517 static int
14518 api_gpe_set_encap_mode (vat_main_t * vam)
14519 {
14520   unformat_input_t *input = vam->input;
14521   vl_api_gpe_set_encap_mode_t *mp;
14522   int ret;
14523   u32 mode = 0;
14524
14525   /* Parse args required to build the message */
14526   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14527     {
14528       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
14529         ;
14530       else
14531         break;
14532     }
14533
14534   /* Construct the API message */
14535   M (GPE_SET_ENCAP_MODE, mp);
14536
14537   mp->mode = mode;
14538
14539   /* send it... */
14540   S (mp);
14541
14542   /* Wait for a reply... */
14543   W (ret);
14544   return ret;
14545 }
14546
14547 static int
14548 api_lisp_gpe_add_del_iface (vat_main_t * vam)
14549 {
14550   unformat_input_t *input = vam->input;
14551   vl_api_gpe_add_del_iface_t *mp;
14552   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
14553   u32 dp_table = 0, vni = 0;
14554   int ret;
14555
14556   /* Parse args required to build the message */
14557   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14558     {
14559       if (unformat (input, "up"))
14560         {
14561           action_set = 1;
14562           is_add = 1;
14563         }
14564       else if (unformat (input, "down"))
14565         {
14566           action_set = 1;
14567           is_add = 0;
14568         }
14569       else if (unformat (input, "table_id %d", &dp_table))
14570         {
14571           dp_table_set = 1;
14572         }
14573       else if (unformat (input, "bd_id %d", &dp_table))
14574         {
14575           dp_table_set = 1;
14576           is_l2 = 1;
14577         }
14578       else if (unformat (input, "vni %d", &vni))
14579         {
14580           vni_set = 1;
14581         }
14582       else
14583         break;
14584     }
14585
14586   if (action_set == 0)
14587     {
14588       errmsg ("Action not set");
14589       return -99;
14590     }
14591   if (dp_table_set == 0 || vni_set == 0)
14592     {
14593       errmsg ("vni and dp_table must be set");
14594       return -99;
14595     }
14596
14597   /* Construct the API message */
14598   M (GPE_ADD_DEL_IFACE, mp);
14599
14600   mp->is_add = is_add;
14601   mp->dp_table = dp_table;
14602   mp->is_l2 = is_l2;
14603   mp->vni = vni;
14604
14605   /* send it... */
14606   S (mp);
14607
14608   /* Wait for a reply... */
14609   W (ret);
14610   return ret;
14611 }
14612
14613 /**
14614  * Add/del map request itr rlocs from ONE control plane and updates
14615  *
14616  * @param vam vpp API test context
14617  * @return return code
14618  */
14619 static int
14620 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
14621 {
14622   unformat_input_t *input = vam->input;
14623   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
14624   u8 *locator_set_name = 0;
14625   u8 locator_set_name_set = 0;
14626   u8 is_add = 1;
14627   int ret;
14628
14629   /* Parse args required to build the message */
14630   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14631     {
14632       if (unformat (input, "del"))
14633         {
14634           is_add = 0;
14635         }
14636       else if (unformat (input, "%_%v%_", &locator_set_name))
14637         {
14638           locator_set_name_set = 1;
14639         }
14640       else
14641         {
14642           clib_warning ("parse error '%U'", format_unformat_error, input);
14643           return -99;
14644         }
14645     }
14646
14647   if (is_add && !locator_set_name_set)
14648     {
14649       errmsg ("itr-rloc is not set!");
14650       return -99;
14651     }
14652
14653   if (is_add && vec_len (locator_set_name) > 64)
14654     {
14655       errmsg ("itr-rloc locator-set name too long");
14656       vec_free (locator_set_name);
14657       return -99;
14658     }
14659
14660   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
14661   mp->is_add = is_add;
14662   if (is_add)
14663     {
14664       clib_memcpy (mp->locator_set_name, locator_set_name,
14665                    vec_len (locator_set_name));
14666     }
14667   else
14668     {
14669       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
14670     }
14671   vec_free (locator_set_name);
14672
14673   /* send it... */
14674   S (mp);
14675
14676   /* Wait for a reply... */
14677   W (ret);
14678   return ret;
14679 }
14680
14681 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
14682
14683 static int
14684 api_one_locator_dump (vat_main_t * vam)
14685 {
14686   unformat_input_t *input = vam->input;
14687   vl_api_one_locator_dump_t *mp;
14688   vl_api_control_ping_t *mp_ping;
14689   u8 is_index_set = 0, is_name_set = 0;
14690   u8 *ls_name = 0;
14691   u32 ls_index = ~0;
14692   int ret;
14693
14694   /* Parse args required to build the message */
14695   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14696     {
14697       if (unformat (input, "ls_name %_%v%_", &ls_name))
14698         {
14699           is_name_set = 1;
14700         }
14701       else if (unformat (input, "ls_index %d", &ls_index))
14702         {
14703           is_index_set = 1;
14704         }
14705       else
14706         {
14707           errmsg ("parse error '%U'", format_unformat_error, input);
14708           return -99;
14709         }
14710     }
14711
14712   if (!is_index_set && !is_name_set)
14713     {
14714       errmsg ("error: expected one of index or name!");
14715       return -99;
14716     }
14717
14718   if (is_index_set && is_name_set)
14719     {
14720       errmsg ("error: only one param expected!");
14721       return -99;
14722     }
14723
14724   if (vec_len (ls_name) > 62)
14725     {
14726       errmsg ("error: locator set name too long!");
14727       return -99;
14728     }
14729
14730   if (!vam->json_output)
14731     {
14732       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
14733     }
14734
14735   M (ONE_LOCATOR_DUMP, mp);
14736   mp->is_index_set = is_index_set;
14737
14738   if (is_index_set)
14739     mp->ls_index = clib_host_to_net_u32 (ls_index);
14740   else
14741     {
14742       vec_add1 (ls_name, 0);
14743       strncpy ((char *) mp->ls_name, (char *) ls_name,
14744                sizeof (mp->ls_name) - 1);
14745     }
14746
14747   /* send it... */
14748   S (mp);
14749
14750   /* Use a control ping for synchronization */
14751   M (CONTROL_PING, mp_ping);
14752   S (mp_ping);
14753
14754   /* Wait for a reply... */
14755   W (ret);
14756   return ret;
14757 }
14758
14759 #define api_lisp_locator_dump api_one_locator_dump
14760
14761 static int
14762 api_one_locator_set_dump (vat_main_t * vam)
14763 {
14764   vl_api_one_locator_set_dump_t *mp;
14765   vl_api_control_ping_t *mp_ping;
14766   unformat_input_t *input = vam->input;
14767   u8 filter = 0;
14768   int ret;
14769
14770   /* Parse args required to build the message */
14771   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14772     {
14773       if (unformat (input, "local"))
14774         {
14775           filter = 1;
14776         }
14777       else if (unformat (input, "remote"))
14778         {
14779           filter = 2;
14780         }
14781       else
14782         {
14783           errmsg ("parse error '%U'", format_unformat_error, input);
14784           return -99;
14785         }
14786     }
14787
14788   if (!vam->json_output)
14789     {
14790       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
14791     }
14792
14793   M (ONE_LOCATOR_SET_DUMP, mp);
14794
14795   mp->filter = filter;
14796
14797   /* send it... */
14798   S (mp);
14799
14800   /* Use a control ping for synchronization */
14801   M (CONTROL_PING, mp_ping);
14802   S (mp_ping);
14803
14804   /* Wait for a reply... */
14805   W (ret);
14806   return ret;
14807 }
14808
14809 #define api_lisp_locator_set_dump api_one_locator_set_dump
14810
14811 static int
14812 api_one_eid_table_map_dump (vat_main_t * vam)
14813 {
14814   u8 is_l2 = 0;
14815   u8 mode_set = 0;
14816   unformat_input_t *input = vam->input;
14817   vl_api_one_eid_table_map_dump_t *mp;
14818   vl_api_control_ping_t *mp_ping;
14819   int ret;
14820
14821   /* Parse args required to build the message */
14822   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14823     {
14824       if (unformat (input, "l2"))
14825         {
14826           is_l2 = 1;
14827           mode_set = 1;
14828         }
14829       else if (unformat (input, "l3"))
14830         {
14831           is_l2 = 0;
14832           mode_set = 1;
14833         }
14834       else
14835         {
14836           errmsg ("parse error '%U'", format_unformat_error, input);
14837           return -99;
14838         }
14839     }
14840
14841   if (!mode_set)
14842     {
14843       errmsg ("expected one of 'l2' or 'l3' parameter!");
14844       return -99;
14845     }
14846
14847   if (!vam->json_output)
14848     {
14849       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
14850     }
14851
14852   M (ONE_EID_TABLE_MAP_DUMP, mp);
14853   mp->is_l2 = is_l2;
14854
14855   /* send it... */
14856   S (mp);
14857
14858   /* Use a control ping for synchronization */
14859   M (CONTROL_PING, mp_ping);
14860   S (mp_ping);
14861
14862   /* Wait for a reply... */
14863   W (ret);
14864   return ret;
14865 }
14866
14867 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
14868
14869 static int
14870 api_one_eid_table_vni_dump (vat_main_t * vam)
14871 {
14872   vl_api_one_eid_table_vni_dump_t *mp;
14873   vl_api_control_ping_t *mp_ping;
14874   int ret;
14875
14876   if (!vam->json_output)
14877     {
14878       print (vam->ofp, "VNI");
14879     }
14880
14881   M (ONE_EID_TABLE_VNI_DUMP, mp);
14882
14883   /* send it... */
14884   S (mp);
14885
14886   /* Use a control ping for synchronization */
14887   M (CONTROL_PING, mp_ping);
14888   S (mp_ping);
14889
14890   /* Wait for a reply... */
14891   W (ret);
14892   return ret;
14893 }
14894
14895 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
14896
14897 static int
14898 api_one_eid_table_dump (vat_main_t * vam)
14899 {
14900   unformat_input_t *i = vam->input;
14901   vl_api_one_eid_table_dump_t *mp;
14902   vl_api_control_ping_t *mp_ping;
14903   struct in_addr ip4;
14904   struct in6_addr ip6;
14905   u8 mac[6];
14906   u8 eid_type = ~0, eid_set = 0;
14907   u32 prefix_length = ~0, t, vni = 0;
14908   u8 filter = 0;
14909   int ret;
14910
14911   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14912     {
14913       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
14914         {
14915           eid_set = 1;
14916           eid_type = 0;
14917           prefix_length = t;
14918         }
14919       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
14920         {
14921           eid_set = 1;
14922           eid_type = 1;
14923           prefix_length = t;
14924         }
14925       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
14926         {
14927           eid_set = 1;
14928           eid_type = 2;
14929         }
14930       else if (unformat (i, "vni %d", &t))
14931         {
14932           vni = t;
14933         }
14934       else if (unformat (i, "local"))
14935         {
14936           filter = 1;
14937         }
14938       else if (unformat (i, "remote"))
14939         {
14940           filter = 2;
14941         }
14942       else
14943         {
14944           errmsg ("parse error '%U'", format_unformat_error, i);
14945           return -99;
14946         }
14947     }
14948
14949   if (!vam->json_output)
14950     {
14951       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
14952              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
14953     }
14954
14955   M (ONE_EID_TABLE_DUMP, mp);
14956
14957   mp->filter = filter;
14958   if (eid_set)
14959     {
14960       mp->eid_set = 1;
14961       mp->vni = htonl (vni);
14962       mp->eid_type = eid_type;
14963       switch (eid_type)
14964         {
14965         case 0:
14966           mp->prefix_length = prefix_length;
14967           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
14968           break;
14969         case 1:
14970           mp->prefix_length = prefix_length;
14971           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
14972           break;
14973         case 2:
14974           clib_memcpy (mp->eid, mac, sizeof (mac));
14975           break;
14976         default:
14977           errmsg ("unknown EID type %d!", eid_type);
14978           return -99;
14979         }
14980     }
14981
14982   /* send it... */
14983   S (mp);
14984
14985   /* Use a control ping for synchronization */
14986   M (CONTROL_PING, mp_ping);
14987   S (mp_ping);
14988
14989   /* Wait for a reply... */
14990   W (ret);
14991   return ret;
14992 }
14993
14994 #define api_lisp_eid_table_dump api_one_eid_table_dump
14995
14996 static int
14997 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
14998 {
14999   unformat_input_t *i = vam->input;
15000   vl_api_gpe_fwd_entries_get_t *mp;
15001   u8 vni_set = 0;
15002   u32 vni = ~0;
15003   int ret;
15004
15005   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15006     {
15007       if (unformat (i, "vni %d", &vni))
15008         {
15009           vni_set = 1;
15010         }
15011       else
15012         {
15013           errmsg ("parse error '%U'", format_unformat_error, i);
15014           return -99;
15015         }
15016     }
15017
15018   if (!vni_set)
15019     {
15020       errmsg ("vni not set!");
15021       return -99;
15022     }
15023
15024   if (!vam->json_output)
15025     {
15026       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
15027              "leid", "reid");
15028     }
15029
15030   M (GPE_FWD_ENTRIES_GET, mp);
15031   mp->vni = clib_host_to_net_u32 (vni);
15032
15033   /* send it... */
15034   S (mp);
15035
15036   /* Wait for a reply... */
15037   W (ret);
15038   return ret;
15039 }
15040
15041 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
15042 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
15043 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
15044 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
15045
15046 static int
15047 api_one_adjacencies_get (vat_main_t * vam)
15048 {
15049   unformat_input_t *i = vam->input;
15050   vl_api_one_adjacencies_get_t *mp;
15051   u8 vni_set = 0;
15052   u32 vni = ~0;
15053   int ret;
15054
15055   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15056     {
15057       if (unformat (i, "vni %d", &vni))
15058         {
15059           vni_set = 1;
15060         }
15061       else
15062         {
15063           errmsg ("parse error '%U'", format_unformat_error, i);
15064           return -99;
15065         }
15066     }
15067
15068   if (!vni_set)
15069     {
15070       errmsg ("vni not set!");
15071       return -99;
15072     }
15073
15074   if (!vam->json_output)
15075     {
15076       print (vam->ofp, "%s %40s", "leid", "reid");
15077     }
15078
15079   M (ONE_ADJACENCIES_GET, mp);
15080   mp->vni = clib_host_to_net_u32 (vni);
15081
15082   /* send it... */
15083   S (mp);
15084
15085   /* Wait for a reply... */
15086   W (ret);
15087   return ret;
15088 }
15089
15090 #define api_lisp_adjacencies_get api_one_adjacencies_get
15091
15092 static int
15093 api_one_map_server_dump (vat_main_t * vam)
15094 {
15095   vl_api_one_map_server_dump_t *mp;
15096   vl_api_control_ping_t *mp_ping;
15097   int ret;
15098
15099   if (!vam->json_output)
15100     {
15101       print (vam->ofp, "%=20s", "Map server");
15102     }
15103
15104   M (ONE_MAP_SERVER_DUMP, mp);
15105   /* send it... */
15106   S (mp);
15107
15108   /* Use a control ping for synchronization */
15109   M (CONTROL_PING, mp_ping);
15110   S (mp_ping);
15111
15112   /* Wait for a reply... */
15113   W (ret);
15114   return ret;
15115 }
15116
15117 #define api_lisp_map_server_dump api_one_map_server_dump
15118
15119 static int
15120 api_one_map_resolver_dump (vat_main_t * vam)
15121 {
15122   vl_api_one_map_resolver_dump_t *mp;
15123   vl_api_control_ping_t *mp_ping;
15124   int ret;
15125
15126   if (!vam->json_output)
15127     {
15128       print (vam->ofp, "%=20s", "Map resolver");
15129     }
15130
15131   M (ONE_MAP_RESOLVER_DUMP, mp);
15132   /* send it... */
15133   S (mp);
15134
15135   /* Use a control ping for synchronization */
15136   M (CONTROL_PING, mp_ping);
15137   S (mp_ping);
15138
15139   /* Wait for a reply... */
15140   W (ret);
15141   return ret;
15142 }
15143
15144 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
15145
15146 static int
15147 api_show_one_status (vat_main_t * vam)
15148 {
15149   vl_api_show_one_status_t *mp;
15150   int ret;
15151
15152   if (!vam->json_output)
15153     {
15154       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
15155     }
15156
15157   M (SHOW_ONE_STATUS, mp);
15158   /* send it... */
15159   S (mp);
15160   /* Wait for a reply... */
15161   W (ret);
15162   return ret;
15163 }
15164
15165 #define api_show_lisp_status api_show_one_status
15166
15167 static int
15168 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
15169 {
15170   vl_api_gpe_fwd_entry_path_dump_t *mp;
15171   vl_api_control_ping_t *mp_ping;
15172   unformat_input_t *i = vam->input;
15173   u32 fwd_entry_index = ~0;
15174   int ret;
15175
15176   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15177     {
15178       if (unformat (i, "index %d", &fwd_entry_index))
15179         ;
15180       else
15181         break;
15182     }
15183
15184   if (~0 == fwd_entry_index)
15185     {
15186       errmsg ("no index specified!");
15187       return -99;
15188     }
15189
15190   if (!vam->json_output)
15191     {
15192       print (vam->ofp, "first line");
15193     }
15194
15195   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
15196
15197   /* send it... */
15198   S (mp);
15199   /* Use a control ping for synchronization */
15200   M (CONTROL_PING, mp_ping);
15201   S (mp_ping);
15202
15203   /* Wait for a reply... */
15204   W (ret);
15205   return ret;
15206 }
15207
15208 static int
15209 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
15210 {
15211   vl_api_one_get_map_request_itr_rlocs_t *mp;
15212   int ret;
15213
15214   if (!vam->json_output)
15215     {
15216       print (vam->ofp, "%=20s", "itr-rlocs:");
15217     }
15218
15219   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
15220   /* send it... */
15221   S (mp);
15222   /* Wait for a reply... */
15223   W (ret);
15224   return ret;
15225 }
15226
15227 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
15228
15229 static int
15230 api_af_packet_create (vat_main_t * vam)
15231 {
15232   unformat_input_t *i = vam->input;
15233   vl_api_af_packet_create_t *mp;
15234   u8 *host_if_name = 0;
15235   u8 hw_addr[6];
15236   u8 random_hw_addr = 1;
15237   int ret;
15238
15239   memset (hw_addr, 0, sizeof (hw_addr));
15240
15241   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15242     {
15243       if (unformat (i, "name %s", &host_if_name))
15244         vec_add1 (host_if_name, 0);
15245       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
15246         random_hw_addr = 0;
15247       else
15248         break;
15249     }
15250
15251   if (!vec_len (host_if_name))
15252     {
15253       errmsg ("host-interface name must be specified");
15254       return -99;
15255     }
15256
15257   if (vec_len (host_if_name) > 64)
15258     {
15259       errmsg ("host-interface name too long");
15260       return -99;
15261     }
15262
15263   M (AF_PACKET_CREATE, mp);
15264
15265   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
15266   clib_memcpy (mp->hw_addr, hw_addr, 6);
15267   mp->use_random_hw_addr = random_hw_addr;
15268   vec_free (host_if_name);
15269
15270   S (mp);
15271
15272   /* *INDENT-OFF* */
15273   W2 (ret,
15274       ({
15275         if (ret == 0)
15276           fprintf (vam->ofp ? vam->ofp : stderr,
15277                    " new sw_if_index = %d\n", vam->sw_if_index);
15278       }));
15279   /* *INDENT-ON* */
15280   return ret;
15281 }
15282
15283 static int
15284 api_af_packet_delete (vat_main_t * vam)
15285 {
15286   unformat_input_t *i = vam->input;
15287   vl_api_af_packet_delete_t *mp;
15288   u8 *host_if_name = 0;
15289   int ret;
15290
15291   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15292     {
15293       if (unformat (i, "name %s", &host_if_name))
15294         vec_add1 (host_if_name, 0);
15295       else
15296         break;
15297     }
15298
15299   if (!vec_len (host_if_name))
15300     {
15301       errmsg ("host-interface name must be specified");
15302       return -99;
15303     }
15304
15305   if (vec_len (host_if_name) > 64)
15306     {
15307       errmsg ("host-interface name too long");
15308       return -99;
15309     }
15310
15311   M (AF_PACKET_DELETE, mp);
15312
15313   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
15314   vec_free (host_if_name);
15315
15316   S (mp);
15317   W (ret);
15318   return ret;
15319 }
15320
15321 static int
15322 api_policer_add_del (vat_main_t * vam)
15323 {
15324   unformat_input_t *i = vam->input;
15325   vl_api_policer_add_del_t *mp;
15326   u8 is_add = 1;
15327   u8 *name = 0;
15328   u32 cir = 0;
15329   u32 eir = 0;
15330   u64 cb = 0;
15331   u64 eb = 0;
15332   u8 rate_type = 0;
15333   u8 round_type = 0;
15334   u8 type = 0;
15335   u8 color_aware = 0;
15336   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
15337   int ret;
15338
15339   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
15340   conform_action.dscp = 0;
15341   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
15342   exceed_action.dscp = 0;
15343   violate_action.action_type = SSE2_QOS_ACTION_DROP;
15344   violate_action.dscp = 0;
15345
15346   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15347     {
15348       if (unformat (i, "del"))
15349         is_add = 0;
15350       else if (unformat (i, "name %s", &name))
15351         vec_add1 (name, 0);
15352       else if (unformat (i, "cir %u", &cir))
15353         ;
15354       else if (unformat (i, "eir %u", &eir))
15355         ;
15356       else if (unformat (i, "cb %u", &cb))
15357         ;
15358       else if (unformat (i, "eb %u", &eb))
15359         ;
15360       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
15361                          &rate_type))
15362         ;
15363       else if (unformat (i, "round_type %U", unformat_policer_round_type,
15364                          &round_type))
15365         ;
15366       else if (unformat (i, "type %U", unformat_policer_type, &type))
15367         ;
15368       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
15369                          &conform_action))
15370         ;
15371       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
15372                          &exceed_action))
15373         ;
15374       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
15375                          &violate_action))
15376         ;
15377       else if (unformat (i, "color-aware"))
15378         color_aware = 1;
15379       else
15380         break;
15381     }
15382
15383   if (!vec_len (name))
15384     {
15385       errmsg ("policer name must be specified");
15386       return -99;
15387     }
15388
15389   if (vec_len (name) > 64)
15390     {
15391       errmsg ("policer name too long");
15392       return -99;
15393     }
15394
15395   M (POLICER_ADD_DEL, mp);
15396
15397   clib_memcpy (mp->name, name, vec_len (name));
15398   vec_free (name);
15399   mp->is_add = is_add;
15400   mp->cir = cir;
15401   mp->eir = eir;
15402   mp->cb = cb;
15403   mp->eb = eb;
15404   mp->rate_type = rate_type;
15405   mp->round_type = round_type;
15406   mp->type = type;
15407   mp->conform_action_type = conform_action.action_type;
15408   mp->conform_dscp = conform_action.dscp;
15409   mp->exceed_action_type = exceed_action.action_type;
15410   mp->exceed_dscp = exceed_action.dscp;
15411   mp->violate_action_type = violate_action.action_type;
15412   mp->violate_dscp = violate_action.dscp;
15413   mp->color_aware = color_aware;
15414
15415   S (mp);
15416   W (ret);
15417   return ret;
15418 }
15419
15420 static int
15421 api_policer_dump (vat_main_t * vam)
15422 {
15423   unformat_input_t *i = vam->input;
15424   vl_api_policer_dump_t *mp;
15425   vl_api_control_ping_t *mp_ping;
15426   u8 *match_name = 0;
15427   u8 match_name_valid = 0;
15428   int ret;
15429
15430   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15431     {
15432       if (unformat (i, "name %s", &match_name))
15433         {
15434           vec_add1 (match_name, 0);
15435           match_name_valid = 1;
15436         }
15437       else
15438         break;
15439     }
15440
15441   M (POLICER_DUMP, mp);
15442   mp->match_name_valid = match_name_valid;
15443   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
15444   vec_free (match_name);
15445   /* send it... */
15446   S (mp);
15447
15448   /* Use a control ping for synchronization */
15449   M (CONTROL_PING, mp_ping);
15450   S (mp_ping);
15451
15452   /* Wait for a reply... */
15453   W (ret);
15454   return ret;
15455 }
15456
15457 static int
15458 api_policer_classify_set_interface (vat_main_t * vam)
15459 {
15460   unformat_input_t *i = vam->input;
15461   vl_api_policer_classify_set_interface_t *mp;
15462   u32 sw_if_index;
15463   int sw_if_index_set;
15464   u32 ip4_table_index = ~0;
15465   u32 ip6_table_index = ~0;
15466   u32 l2_table_index = ~0;
15467   u8 is_add = 1;
15468   int ret;
15469
15470   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15471     {
15472       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15473         sw_if_index_set = 1;
15474       else if (unformat (i, "sw_if_index %d", &sw_if_index))
15475         sw_if_index_set = 1;
15476       else if (unformat (i, "del"))
15477         is_add = 0;
15478       else if (unformat (i, "ip4-table %d", &ip4_table_index))
15479         ;
15480       else if (unformat (i, "ip6-table %d", &ip6_table_index))
15481         ;
15482       else if (unformat (i, "l2-table %d", &l2_table_index))
15483         ;
15484       else
15485         {
15486           clib_warning ("parse error '%U'", format_unformat_error, i);
15487           return -99;
15488         }
15489     }
15490
15491   if (sw_if_index_set == 0)
15492     {
15493       errmsg ("missing interface name or sw_if_index");
15494       return -99;
15495     }
15496
15497   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
15498
15499   mp->sw_if_index = ntohl (sw_if_index);
15500   mp->ip4_table_index = ntohl (ip4_table_index);
15501   mp->ip6_table_index = ntohl (ip6_table_index);
15502   mp->l2_table_index = ntohl (l2_table_index);
15503   mp->is_add = is_add;
15504
15505   S (mp);
15506   W (ret);
15507   return ret;
15508 }
15509
15510 static int
15511 api_policer_classify_dump (vat_main_t * vam)
15512 {
15513   unformat_input_t *i = vam->input;
15514   vl_api_policer_classify_dump_t *mp;
15515   vl_api_control_ping_t *mp_ping;
15516   u8 type = POLICER_CLASSIFY_N_TABLES;
15517   int ret;
15518
15519   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
15520     ;
15521   else
15522     {
15523       errmsg ("classify table type must be specified");
15524       return -99;
15525     }
15526
15527   if (!vam->json_output)
15528     {
15529       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
15530     }
15531
15532   M (POLICER_CLASSIFY_DUMP, mp);
15533   mp->type = type;
15534   /* send it... */
15535   S (mp);
15536
15537   /* Use a control ping for synchronization */
15538   M (CONTROL_PING, mp_ping);
15539   S (mp_ping);
15540
15541   /* Wait for a reply... */
15542   W (ret);
15543   return ret;
15544 }
15545
15546 static int
15547 api_netmap_create (vat_main_t * vam)
15548 {
15549   unformat_input_t *i = vam->input;
15550   vl_api_netmap_create_t *mp;
15551   u8 *if_name = 0;
15552   u8 hw_addr[6];
15553   u8 random_hw_addr = 1;
15554   u8 is_pipe = 0;
15555   u8 is_master = 0;
15556   int ret;
15557
15558   memset (hw_addr, 0, sizeof (hw_addr));
15559
15560   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15561     {
15562       if (unformat (i, "name %s", &if_name))
15563         vec_add1 (if_name, 0);
15564       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
15565         random_hw_addr = 0;
15566       else if (unformat (i, "pipe"))
15567         is_pipe = 1;
15568       else if (unformat (i, "master"))
15569         is_master = 1;
15570       else if (unformat (i, "slave"))
15571         is_master = 0;
15572       else
15573         break;
15574     }
15575
15576   if (!vec_len (if_name))
15577     {
15578       errmsg ("interface name must be specified");
15579       return -99;
15580     }
15581
15582   if (vec_len (if_name) > 64)
15583     {
15584       errmsg ("interface name too long");
15585       return -99;
15586     }
15587
15588   M (NETMAP_CREATE, mp);
15589
15590   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
15591   clib_memcpy (mp->hw_addr, hw_addr, 6);
15592   mp->use_random_hw_addr = random_hw_addr;
15593   mp->is_pipe = is_pipe;
15594   mp->is_master = is_master;
15595   vec_free (if_name);
15596
15597   S (mp);
15598   W (ret);
15599   return ret;
15600 }
15601
15602 static int
15603 api_netmap_delete (vat_main_t * vam)
15604 {
15605   unformat_input_t *i = vam->input;
15606   vl_api_netmap_delete_t *mp;
15607   u8 *if_name = 0;
15608   int ret;
15609
15610   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15611     {
15612       if (unformat (i, "name %s", &if_name))
15613         vec_add1 (if_name, 0);
15614       else
15615         break;
15616     }
15617
15618   if (!vec_len (if_name))
15619     {
15620       errmsg ("interface name must be specified");
15621       return -99;
15622     }
15623
15624   if (vec_len (if_name) > 64)
15625     {
15626       errmsg ("interface name too long");
15627       return -99;
15628     }
15629
15630   M (NETMAP_DELETE, mp);
15631
15632   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
15633   vec_free (if_name);
15634
15635   S (mp);
15636   W (ret);
15637   return ret;
15638 }
15639
15640 static void vl_api_mpls_tunnel_details_t_handler
15641   (vl_api_mpls_tunnel_details_t * mp)
15642 {
15643   vat_main_t *vam = &vat_main;
15644   i32 len = mp->mt_next_hop_n_labels;
15645   i32 i;
15646
15647   print (vam->ofp, "[%d]: via %U %d labels ",
15648          mp->tunnel_index,
15649          format_ip4_address, mp->mt_next_hop,
15650          ntohl (mp->mt_next_hop_sw_if_index));
15651   for (i = 0; i < len; i++)
15652     {
15653       print (vam->ofp, "%u ", ntohl (mp->mt_next_hop_out_labels[i]));
15654     }
15655   print (vam->ofp, "");
15656 }
15657
15658 static void vl_api_mpls_tunnel_details_t_handler_json
15659   (vl_api_mpls_tunnel_details_t * mp)
15660 {
15661   vat_main_t *vam = &vat_main;
15662   vat_json_node_t *node = NULL;
15663   struct in_addr ip4;
15664   i32 i;
15665   i32 len = mp->mt_next_hop_n_labels;
15666
15667   if (VAT_JSON_ARRAY != vam->json_tree.type)
15668     {
15669       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15670       vat_json_init_array (&vam->json_tree);
15671     }
15672   node = vat_json_array_add (&vam->json_tree);
15673
15674   vat_json_init_object (node);
15675   vat_json_object_add_uint (node, "tunnel_index", ntohl (mp->tunnel_index));
15676   clib_memcpy (&ip4, &(mp->mt_next_hop), sizeof (ip4));
15677   vat_json_object_add_ip4 (node, "next_hop", ip4);
15678   vat_json_object_add_uint (node, "next_hop_sw_if_index",
15679                             ntohl (mp->mt_next_hop_sw_if_index));
15680   vat_json_object_add_uint (node, "l2_only", ntohl (mp->mt_l2_only));
15681   vat_json_object_add_uint (node, "label_count", len);
15682   for (i = 0; i < len; i++)
15683     {
15684       vat_json_object_add_uint (node, "label",
15685                                 ntohl (mp->mt_next_hop_out_labels[i]));
15686     }
15687 }
15688
15689 static int
15690 api_mpls_tunnel_dump (vat_main_t * vam)
15691 {
15692   vl_api_mpls_tunnel_dump_t *mp;
15693   vl_api_control_ping_t *mp_ping;
15694   i32 index = -1;
15695   int ret;
15696
15697   /* Parse args required to build the message */
15698   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
15699     {
15700       if (!unformat (vam->input, "tunnel_index %d", &index))
15701         {
15702           index = -1;
15703           break;
15704         }
15705     }
15706
15707   print (vam->ofp, "  tunnel_index %d", index);
15708
15709   M (MPLS_TUNNEL_DUMP, mp);
15710   mp->tunnel_index = htonl (index);
15711   S (mp);
15712
15713   /* Use a control ping for synchronization */
15714   M (CONTROL_PING, mp_ping);
15715   S (mp_ping);
15716
15717   W (ret);
15718   return ret;
15719 }
15720
15721 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
15722 #define vl_api_mpls_fib_details_t_print vl_noop_handler
15723
15724 static void
15725 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
15726 {
15727   vat_main_t *vam = &vat_main;
15728   int count = ntohl (mp->count);
15729   vl_api_fib_path2_t *fp;
15730   int i;
15731
15732   print (vam->ofp,
15733          "table-id %d, label %u, ess_bit %u",
15734          ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
15735   fp = mp->path;
15736   for (i = 0; i < count; i++)
15737     {
15738       if (fp->afi == IP46_TYPE_IP6)
15739         print (vam->ofp,
15740                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15741                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
15742                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15743                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15744                format_ip6_address, fp->next_hop);
15745       else if (fp->afi == IP46_TYPE_IP4)
15746         print (vam->ofp,
15747                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15748                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
15749                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15750                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15751                format_ip4_address, fp->next_hop);
15752       fp++;
15753     }
15754 }
15755
15756 static void vl_api_mpls_fib_details_t_handler_json
15757   (vl_api_mpls_fib_details_t * mp)
15758 {
15759   vat_main_t *vam = &vat_main;
15760   int count = ntohl (mp->count);
15761   vat_json_node_t *node = NULL;
15762   struct in_addr ip4;
15763   struct in6_addr ip6;
15764   vl_api_fib_path2_t *fp;
15765   int i;
15766
15767   if (VAT_JSON_ARRAY != vam->json_tree.type)
15768     {
15769       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15770       vat_json_init_array (&vam->json_tree);
15771     }
15772   node = vat_json_array_add (&vam->json_tree);
15773
15774   vat_json_init_object (node);
15775   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
15776   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
15777   vat_json_object_add_uint (node, "label", ntohl (mp->label));
15778   vat_json_object_add_uint (node, "path_count", count);
15779   fp = mp->path;
15780   for (i = 0; i < count; i++)
15781     {
15782       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
15783       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
15784       vat_json_object_add_uint (node, "is_local", fp->is_local);
15785       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
15786       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
15787       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
15788       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
15789       if (fp->afi == IP46_TYPE_IP4)
15790         {
15791           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
15792           vat_json_object_add_ip4 (node, "next_hop", ip4);
15793         }
15794       else if (fp->afi == IP46_TYPE_IP6)
15795         {
15796           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
15797           vat_json_object_add_ip6 (node, "next_hop", ip6);
15798         }
15799     }
15800 }
15801
15802 static int
15803 api_mpls_fib_dump (vat_main_t * vam)
15804 {
15805   vl_api_mpls_fib_dump_t *mp;
15806   vl_api_control_ping_t *mp_ping;
15807   int ret;
15808
15809   M (MPLS_FIB_DUMP, mp);
15810   S (mp);
15811
15812   /* Use a control ping for synchronization */
15813   M (CONTROL_PING, mp_ping);
15814   S (mp_ping);
15815
15816   W (ret);
15817   return ret;
15818 }
15819
15820 #define vl_api_ip_fib_details_t_endian vl_noop_handler
15821 #define vl_api_ip_fib_details_t_print vl_noop_handler
15822
15823 static void
15824 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
15825 {
15826   vat_main_t *vam = &vat_main;
15827   int count = ntohl (mp->count);
15828   vl_api_fib_path_t *fp;
15829   int i;
15830
15831   print (vam->ofp,
15832          "table-id %d, prefix %U/%d",
15833          ntohl (mp->table_id), format_ip4_address, mp->address,
15834          mp->address_length);
15835   fp = mp->path;
15836   for (i = 0; i < count; i++)
15837     {
15838       if (fp->afi == IP46_TYPE_IP6)
15839         print (vam->ofp,
15840                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15841                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
15842                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15843                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15844                format_ip6_address, fp->next_hop);
15845       else if (fp->afi == IP46_TYPE_IP4)
15846         print (vam->ofp,
15847                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15848                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
15849                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15850                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15851                format_ip4_address, fp->next_hop);
15852       fp++;
15853     }
15854 }
15855
15856 static void vl_api_ip_fib_details_t_handler_json
15857   (vl_api_ip_fib_details_t * mp)
15858 {
15859   vat_main_t *vam = &vat_main;
15860   int count = ntohl (mp->count);
15861   vat_json_node_t *node = NULL;
15862   struct in_addr ip4;
15863   struct in6_addr ip6;
15864   vl_api_fib_path_t *fp;
15865   int i;
15866
15867   if (VAT_JSON_ARRAY != vam->json_tree.type)
15868     {
15869       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15870       vat_json_init_array (&vam->json_tree);
15871     }
15872   node = vat_json_array_add (&vam->json_tree);
15873
15874   vat_json_init_object (node);
15875   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
15876   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
15877   vat_json_object_add_ip4 (node, "prefix", ip4);
15878   vat_json_object_add_uint (node, "mask_length", mp->address_length);
15879   vat_json_object_add_uint (node, "path_count", count);
15880   fp = mp->path;
15881   for (i = 0; i < count; i++)
15882     {
15883       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
15884       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
15885       vat_json_object_add_uint (node, "is_local", fp->is_local);
15886       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
15887       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
15888       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
15889       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
15890       if (fp->afi == IP46_TYPE_IP4)
15891         {
15892           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
15893           vat_json_object_add_ip4 (node, "next_hop", ip4);
15894         }
15895       else if (fp->afi == IP46_TYPE_IP6)
15896         {
15897           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
15898           vat_json_object_add_ip6 (node, "next_hop", ip6);
15899         }
15900     }
15901 }
15902
15903 static int
15904 api_ip_fib_dump (vat_main_t * vam)
15905 {
15906   vl_api_ip_fib_dump_t *mp;
15907   vl_api_control_ping_t *mp_ping;
15908   int ret;
15909
15910   M (IP_FIB_DUMP, mp);
15911   S (mp);
15912
15913   /* Use a control ping for synchronization */
15914   M (CONTROL_PING, mp_ping);
15915   S (mp_ping);
15916
15917   W (ret);
15918   return ret;
15919 }
15920
15921 static int
15922 api_ip_mfib_dump (vat_main_t * vam)
15923 {
15924   vl_api_ip_mfib_dump_t *mp;
15925   vl_api_control_ping_t *mp_ping;
15926   int ret;
15927
15928   M (IP_MFIB_DUMP, mp);
15929   S (mp);
15930
15931   /* Use a control ping for synchronization */
15932   M (CONTROL_PING, mp_ping);
15933   S (mp_ping);
15934
15935   W (ret);
15936   return ret;
15937 }
15938
15939 static void vl_api_ip_neighbor_details_t_handler
15940   (vl_api_ip_neighbor_details_t * mp)
15941 {
15942   vat_main_t *vam = &vat_main;
15943
15944   print (vam->ofp, "%c %U %U",
15945          (mp->is_static) ? 'S' : 'D',
15946          format_ethernet_address, &mp->mac_address,
15947          (mp->is_ipv6) ? format_ip6_address : format_ip4_address,
15948          &mp->ip_address);
15949 }
15950
15951 static void vl_api_ip_neighbor_details_t_handler_json
15952   (vl_api_ip_neighbor_details_t * mp)
15953 {
15954
15955   vat_main_t *vam = &vat_main;
15956   vat_json_node_t *node;
15957   struct in_addr ip4;
15958   struct in6_addr ip6;
15959
15960   if (VAT_JSON_ARRAY != vam->json_tree.type)
15961     {
15962       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15963       vat_json_init_array (&vam->json_tree);
15964     }
15965   node = vat_json_array_add (&vam->json_tree);
15966
15967   vat_json_init_object (node);
15968   vat_json_object_add_string_copy (node, "flag",
15969                                    (mp->is_static) ? (u8 *) "static" : (u8 *)
15970                                    "dynamic");
15971
15972   vat_json_object_add_string_copy (node, "link_layer",
15973                                    format (0, "%U", format_ethernet_address,
15974                                            &mp->mac_address));
15975
15976   if (mp->is_ipv6)
15977     {
15978       clib_memcpy (&ip6, &mp->ip_address, sizeof (ip6));
15979       vat_json_object_add_ip6 (node, "ip_address", ip6);
15980     }
15981   else
15982     {
15983       clib_memcpy (&ip4, &mp->ip_address, sizeof (ip4));
15984       vat_json_object_add_ip4 (node, "ip_address", ip4);
15985     }
15986 }
15987
15988 static int
15989 api_ip_neighbor_dump (vat_main_t * vam)
15990 {
15991   unformat_input_t *i = vam->input;
15992   vl_api_ip_neighbor_dump_t *mp;
15993   vl_api_control_ping_t *mp_ping;
15994   u8 is_ipv6 = 0;
15995   u32 sw_if_index = ~0;
15996   int ret;
15997
15998   /* Parse args required to build the message */
15999   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16000     {
16001       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16002         ;
16003       else if (unformat (i, "sw_if_index %d", &sw_if_index))
16004         ;
16005       else if (unformat (i, "ip6"))
16006         is_ipv6 = 1;
16007       else
16008         break;
16009     }
16010
16011   if (sw_if_index == ~0)
16012     {
16013       errmsg ("missing interface name or sw_if_index");
16014       return -99;
16015     }
16016
16017   M (IP_NEIGHBOR_DUMP, mp);
16018   mp->is_ipv6 = (u8) is_ipv6;
16019   mp->sw_if_index = ntohl (sw_if_index);
16020   S (mp);
16021
16022   /* Use a control ping for synchronization */
16023   M (CONTROL_PING, mp_ping);
16024   S (mp_ping);
16025
16026   W (ret);
16027   return ret;
16028 }
16029
16030 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
16031 #define vl_api_ip6_fib_details_t_print vl_noop_handler
16032
16033 static void
16034 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
16035 {
16036   vat_main_t *vam = &vat_main;
16037   int count = ntohl (mp->count);
16038   vl_api_fib_path_t *fp;
16039   int i;
16040
16041   print (vam->ofp,
16042          "table-id %d, prefix %U/%d",
16043          ntohl (mp->table_id), format_ip6_address, mp->address,
16044          mp->address_length);
16045   fp = mp->path;
16046   for (i = 0; i < count; i++)
16047     {
16048       if (fp->afi == IP46_TYPE_IP6)
16049         print (vam->ofp,
16050                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16051                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16052                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16053                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16054                format_ip6_address, fp->next_hop);
16055       else if (fp->afi == IP46_TYPE_IP4)
16056         print (vam->ofp,
16057                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16058                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16059                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16060                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16061                format_ip4_address, fp->next_hop);
16062       fp++;
16063     }
16064 }
16065
16066 static void vl_api_ip6_fib_details_t_handler_json
16067   (vl_api_ip6_fib_details_t * mp)
16068 {
16069   vat_main_t *vam = &vat_main;
16070   int count = ntohl (mp->count);
16071   vat_json_node_t *node = NULL;
16072   struct in_addr ip4;
16073   struct in6_addr ip6;
16074   vl_api_fib_path_t *fp;
16075   int i;
16076
16077   if (VAT_JSON_ARRAY != vam->json_tree.type)
16078     {
16079       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16080       vat_json_init_array (&vam->json_tree);
16081     }
16082   node = vat_json_array_add (&vam->json_tree);
16083
16084   vat_json_init_object (node);
16085   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
16086   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
16087   vat_json_object_add_ip6 (node, "prefix", ip6);
16088   vat_json_object_add_uint (node, "mask_length", mp->address_length);
16089   vat_json_object_add_uint (node, "path_count", count);
16090   fp = mp->path;
16091   for (i = 0; i < count; i++)
16092     {
16093       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
16094       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
16095       vat_json_object_add_uint (node, "is_local", fp->is_local);
16096       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
16097       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
16098       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
16099       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
16100       if (fp->afi == IP46_TYPE_IP4)
16101         {
16102           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
16103           vat_json_object_add_ip4 (node, "next_hop", ip4);
16104         }
16105       else if (fp->afi == IP46_TYPE_IP6)
16106         {
16107           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
16108           vat_json_object_add_ip6 (node, "next_hop", ip6);
16109         }
16110     }
16111 }
16112
16113 static int
16114 api_ip6_fib_dump (vat_main_t * vam)
16115 {
16116   vl_api_ip6_fib_dump_t *mp;
16117   vl_api_control_ping_t *mp_ping;
16118   int ret;
16119
16120   M (IP6_FIB_DUMP, mp);
16121   S (mp);
16122
16123   /* Use a control ping for synchronization */
16124   M (CONTROL_PING, mp_ping);
16125   S (mp_ping);
16126
16127   W (ret);
16128   return ret;
16129 }
16130
16131 static int
16132 api_ip6_mfib_dump (vat_main_t * vam)
16133 {
16134   vl_api_ip6_mfib_dump_t *mp;
16135   vl_api_control_ping_t *mp_ping;
16136   int ret;
16137
16138   M (IP6_MFIB_DUMP, mp);
16139   S (mp);
16140
16141   /* Use a control ping for synchronization */
16142   M (CONTROL_PING, mp_ping);
16143   S (mp_ping);
16144
16145   W (ret);
16146   return ret;
16147 }
16148
16149 int
16150 api_classify_table_ids (vat_main_t * vam)
16151 {
16152   vl_api_classify_table_ids_t *mp;
16153   int ret;
16154
16155   /* Construct the API message */
16156   M (CLASSIFY_TABLE_IDS, mp);
16157   mp->context = 0;
16158
16159   S (mp);
16160   W (ret);
16161   return ret;
16162 }
16163
16164 int
16165 api_classify_table_by_interface (vat_main_t * vam)
16166 {
16167   unformat_input_t *input = vam->input;
16168   vl_api_classify_table_by_interface_t *mp;
16169
16170   u32 sw_if_index = ~0;
16171   int ret;
16172   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16173     {
16174       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16175         ;
16176       else if (unformat (input, "sw_if_index %d", &sw_if_index))
16177         ;
16178       else
16179         break;
16180     }
16181   if (sw_if_index == ~0)
16182     {
16183       errmsg ("missing interface name or sw_if_index");
16184       return -99;
16185     }
16186
16187   /* Construct the API message */
16188   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
16189   mp->context = 0;
16190   mp->sw_if_index = ntohl (sw_if_index);
16191
16192   S (mp);
16193   W (ret);
16194   return ret;
16195 }
16196
16197 int
16198 api_classify_table_info (vat_main_t * vam)
16199 {
16200   unformat_input_t *input = vam->input;
16201   vl_api_classify_table_info_t *mp;
16202
16203   u32 table_id = ~0;
16204   int ret;
16205   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16206     {
16207       if (unformat (input, "table_id %d", &table_id))
16208         ;
16209       else
16210         break;
16211     }
16212   if (table_id == ~0)
16213     {
16214       errmsg ("missing table id");
16215       return -99;
16216     }
16217
16218   /* Construct the API message */
16219   M (CLASSIFY_TABLE_INFO, mp);
16220   mp->context = 0;
16221   mp->table_id = ntohl (table_id);
16222
16223   S (mp);
16224   W (ret);
16225   return ret;
16226 }
16227
16228 int
16229 api_classify_session_dump (vat_main_t * vam)
16230 {
16231   unformat_input_t *input = vam->input;
16232   vl_api_classify_session_dump_t *mp;
16233   vl_api_control_ping_t *mp_ping;
16234
16235   u32 table_id = ~0;
16236   int ret;
16237   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16238     {
16239       if (unformat (input, "table_id %d", &table_id))
16240         ;
16241       else
16242         break;
16243     }
16244   if (table_id == ~0)
16245     {
16246       errmsg ("missing table id");
16247       return -99;
16248     }
16249
16250   /* Construct the API message */
16251   M (CLASSIFY_SESSION_DUMP, mp);
16252   mp->context = 0;
16253   mp->table_id = ntohl (table_id);
16254   S (mp);
16255
16256   /* Use a control ping for synchronization */
16257   M (CONTROL_PING, mp_ping);
16258   S (mp_ping);
16259
16260   W (ret);
16261   return ret;
16262 }
16263
16264 static void
16265 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
16266 {
16267   vat_main_t *vam = &vat_main;
16268
16269   print (vam->ofp, "collector_address %U, collector_port %d, "
16270          "src_address %U, vrf_id %d, path_mtu %u, "
16271          "template_interval %u, udp_checksum %d",
16272          format_ip4_address, mp->collector_address,
16273          ntohs (mp->collector_port),
16274          format_ip4_address, mp->src_address,
16275          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
16276          ntohl (mp->template_interval), mp->udp_checksum);
16277
16278   vam->retval = 0;
16279   vam->result_ready = 1;
16280 }
16281
16282 static void
16283   vl_api_ipfix_exporter_details_t_handler_json
16284   (vl_api_ipfix_exporter_details_t * mp)
16285 {
16286   vat_main_t *vam = &vat_main;
16287   vat_json_node_t node;
16288   struct in_addr collector_address;
16289   struct in_addr src_address;
16290
16291   vat_json_init_object (&node);
16292   clib_memcpy (&collector_address, &mp->collector_address,
16293                sizeof (collector_address));
16294   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
16295   vat_json_object_add_uint (&node, "collector_port",
16296                             ntohs (mp->collector_port));
16297   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
16298   vat_json_object_add_ip4 (&node, "src_address", src_address);
16299   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
16300   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
16301   vat_json_object_add_uint (&node, "template_interval",
16302                             ntohl (mp->template_interval));
16303   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
16304
16305   vat_json_print (vam->ofp, &node);
16306   vat_json_free (&node);
16307   vam->retval = 0;
16308   vam->result_ready = 1;
16309 }
16310
16311 int
16312 api_ipfix_exporter_dump (vat_main_t * vam)
16313 {
16314   vl_api_ipfix_exporter_dump_t *mp;
16315   int ret;
16316
16317   /* Construct the API message */
16318   M (IPFIX_EXPORTER_DUMP, mp);
16319   mp->context = 0;
16320
16321   S (mp);
16322   W (ret);
16323   return ret;
16324 }
16325
16326 static int
16327 api_ipfix_classify_stream_dump (vat_main_t * vam)
16328 {
16329   vl_api_ipfix_classify_stream_dump_t *mp;
16330   int ret;
16331
16332   /* Construct the API message */
16333   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
16334   mp->context = 0;
16335
16336   S (mp);
16337   W (ret);
16338   return ret;
16339   /* NOTREACHED */
16340   return 0;
16341 }
16342
16343 static void
16344   vl_api_ipfix_classify_stream_details_t_handler
16345   (vl_api_ipfix_classify_stream_details_t * mp)
16346 {
16347   vat_main_t *vam = &vat_main;
16348   print (vam->ofp, "domain_id %d, src_port %d",
16349          ntohl (mp->domain_id), ntohs (mp->src_port));
16350   vam->retval = 0;
16351   vam->result_ready = 1;
16352 }
16353
16354 static void
16355   vl_api_ipfix_classify_stream_details_t_handler_json
16356   (vl_api_ipfix_classify_stream_details_t * mp)
16357 {
16358   vat_main_t *vam = &vat_main;
16359   vat_json_node_t node;
16360
16361   vat_json_init_object (&node);
16362   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
16363   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
16364
16365   vat_json_print (vam->ofp, &node);
16366   vat_json_free (&node);
16367   vam->retval = 0;
16368   vam->result_ready = 1;
16369 }
16370
16371 static int
16372 api_ipfix_classify_table_dump (vat_main_t * vam)
16373 {
16374   vl_api_ipfix_classify_table_dump_t *mp;
16375   vl_api_control_ping_t *mp_ping;
16376   int ret;
16377
16378   if (!vam->json_output)
16379     {
16380       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
16381              "transport_protocol");
16382     }
16383
16384   /* Construct the API message */
16385   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
16386
16387   /* send it... */
16388   S (mp);
16389
16390   /* Use a control ping for synchronization */
16391   M (CONTROL_PING, mp_ping);
16392   S (mp_ping);
16393
16394   W (ret);
16395   return ret;
16396 }
16397
16398 static void
16399   vl_api_ipfix_classify_table_details_t_handler
16400   (vl_api_ipfix_classify_table_details_t * mp)
16401 {
16402   vat_main_t *vam = &vat_main;
16403   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
16404          mp->transport_protocol);
16405 }
16406
16407 static void
16408   vl_api_ipfix_classify_table_details_t_handler_json
16409   (vl_api_ipfix_classify_table_details_t * mp)
16410 {
16411   vat_json_node_t *node = NULL;
16412   vat_main_t *vam = &vat_main;
16413
16414   if (VAT_JSON_ARRAY != vam->json_tree.type)
16415     {
16416       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16417       vat_json_init_array (&vam->json_tree);
16418     }
16419
16420   node = vat_json_array_add (&vam->json_tree);
16421   vat_json_init_object (node);
16422
16423   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
16424   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
16425   vat_json_object_add_uint (node, "transport_protocol",
16426                             mp->transport_protocol);
16427 }
16428
16429 static int
16430 api_sw_interface_span_enable_disable (vat_main_t * vam)
16431 {
16432   unformat_input_t *i = vam->input;
16433   vl_api_sw_interface_span_enable_disable_t *mp;
16434   u32 src_sw_if_index = ~0;
16435   u32 dst_sw_if_index = ~0;
16436   u8 state = 3;
16437   int ret;
16438
16439   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16440     {
16441       if (unformat
16442           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
16443         ;
16444       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
16445         ;
16446       else
16447         if (unformat
16448             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
16449         ;
16450       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
16451         ;
16452       else if (unformat (i, "disable"))
16453         state = 0;
16454       else if (unformat (i, "rx"))
16455         state = 1;
16456       else if (unformat (i, "tx"))
16457         state = 2;
16458       else if (unformat (i, "both"))
16459         state = 3;
16460       else
16461         break;
16462     }
16463
16464   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
16465
16466   mp->sw_if_index_from = htonl (src_sw_if_index);
16467   mp->sw_if_index_to = htonl (dst_sw_if_index);
16468   mp->state = state;
16469
16470   S (mp);
16471   W (ret);
16472   return ret;
16473 }
16474
16475 static void
16476 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
16477                                             * mp)
16478 {
16479   vat_main_t *vam = &vat_main;
16480   u8 *sw_if_from_name = 0;
16481   u8 *sw_if_to_name = 0;
16482   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
16483   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
16484   char *states[] = { "none", "rx", "tx", "both" };
16485   hash_pair_t *p;
16486
16487   /* *INDENT-OFF* */
16488   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
16489   ({
16490     if ((u32) p->value[0] == sw_if_index_from)
16491       {
16492         sw_if_from_name = (u8 *)(p->key);
16493         if (sw_if_to_name)
16494           break;
16495       }
16496     if ((u32) p->value[0] == sw_if_index_to)
16497       {
16498         sw_if_to_name = (u8 *)(p->key);
16499         if (sw_if_from_name)
16500           break;
16501       }
16502   }));
16503   /* *INDENT-ON* */
16504   print (vam->ofp, "%20s => %20s (%s)",
16505          sw_if_from_name, sw_if_to_name, states[mp->state]);
16506 }
16507
16508 static void
16509   vl_api_sw_interface_span_details_t_handler_json
16510   (vl_api_sw_interface_span_details_t * mp)
16511 {
16512   vat_main_t *vam = &vat_main;
16513   vat_json_node_t *node = NULL;
16514   u8 *sw_if_from_name = 0;
16515   u8 *sw_if_to_name = 0;
16516   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
16517   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
16518   hash_pair_t *p;
16519
16520   /* *INDENT-OFF* */
16521   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
16522   ({
16523     if ((u32) p->value[0] == sw_if_index_from)
16524       {
16525         sw_if_from_name = (u8 *)(p->key);
16526         if (sw_if_to_name)
16527           break;
16528       }
16529     if ((u32) p->value[0] == sw_if_index_to)
16530       {
16531         sw_if_to_name = (u8 *)(p->key);
16532         if (sw_if_from_name)
16533           break;
16534       }
16535   }));
16536   /* *INDENT-ON* */
16537
16538   if (VAT_JSON_ARRAY != vam->json_tree.type)
16539     {
16540       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16541       vat_json_init_array (&vam->json_tree);
16542     }
16543   node = vat_json_array_add (&vam->json_tree);
16544
16545   vat_json_init_object (node);
16546   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
16547   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
16548   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
16549   if (0 != sw_if_to_name)
16550     {
16551       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
16552     }
16553   vat_json_object_add_uint (node, "state", mp->state);
16554 }
16555
16556 static int
16557 api_sw_interface_span_dump (vat_main_t * vam)
16558 {
16559   vl_api_sw_interface_span_dump_t *mp;
16560   vl_api_control_ping_t *mp_ping;
16561   int ret;
16562
16563   M (SW_INTERFACE_SPAN_DUMP, mp);
16564   S (mp);
16565
16566   /* Use a control ping for synchronization */
16567   M (CONTROL_PING, mp_ping);
16568   S (mp_ping);
16569
16570   W (ret);
16571   return ret;
16572 }
16573
16574 int
16575 api_pg_create_interface (vat_main_t * vam)
16576 {
16577   unformat_input_t *input = vam->input;
16578   vl_api_pg_create_interface_t *mp;
16579
16580   u32 if_id = ~0;
16581   int ret;
16582   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16583     {
16584       if (unformat (input, "if_id %d", &if_id))
16585         ;
16586       else
16587         break;
16588     }
16589   if (if_id == ~0)
16590     {
16591       errmsg ("missing pg interface index");
16592       return -99;
16593     }
16594
16595   /* Construct the API message */
16596   M (PG_CREATE_INTERFACE, mp);
16597   mp->context = 0;
16598   mp->interface_id = ntohl (if_id);
16599
16600   S (mp);
16601   W (ret);
16602   return ret;
16603 }
16604
16605 int
16606 api_pg_capture (vat_main_t * vam)
16607 {
16608   unformat_input_t *input = vam->input;
16609   vl_api_pg_capture_t *mp;
16610
16611   u32 if_id = ~0;
16612   u8 enable = 1;
16613   u32 count = 1;
16614   u8 pcap_file_set = 0;
16615   u8 *pcap_file = 0;
16616   int ret;
16617   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16618     {
16619       if (unformat (input, "if_id %d", &if_id))
16620         ;
16621       else if (unformat (input, "pcap %s", &pcap_file))
16622         pcap_file_set = 1;
16623       else if (unformat (input, "count %d", &count))
16624         ;
16625       else if (unformat (input, "disable"))
16626         enable = 0;
16627       else
16628         break;
16629     }
16630   if (if_id == ~0)
16631     {
16632       errmsg ("missing pg interface index");
16633       return -99;
16634     }
16635   if (pcap_file_set > 0)
16636     {
16637       if (vec_len (pcap_file) > 255)
16638         {
16639           errmsg ("pcap file name is too long");
16640           return -99;
16641         }
16642     }
16643
16644   u32 name_len = vec_len (pcap_file);
16645   /* Construct the API message */
16646   M (PG_CAPTURE, mp);
16647   mp->context = 0;
16648   mp->interface_id = ntohl (if_id);
16649   mp->is_enabled = enable;
16650   mp->count = ntohl (count);
16651   mp->pcap_name_length = ntohl (name_len);
16652   if (pcap_file_set != 0)
16653     {
16654       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
16655     }
16656   vec_free (pcap_file);
16657
16658   S (mp);
16659   W (ret);
16660   return ret;
16661 }
16662
16663 int
16664 api_pg_enable_disable (vat_main_t * vam)
16665 {
16666   unformat_input_t *input = vam->input;
16667   vl_api_pg_enable_disable_t *mp;
16668
16669   u8 enable = 1;
16670   u8 stream_name_set = 0;
16671   u8 *stream_name = 0;
16672   int ret;
16673   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16674     {
16675       if (unformat (input, "stream %s", &stream_name))
16676         stream_name_set = 1;
16677       else if (unformat (input, "disable"))
16678         enable = 0;
16679       else
16680         break;
16681     }
16682
16683   if (stream_name_set > 0)
16684     {
16685       if (vec_len (stream_name) > 255)
16686         {
16687           errmsg ("stream name too long");
16688           return -99;
16689         }
16690     }
16691
16692   u32 name_len = vec_len (stream_name);
16693   /* Construct the API message */
16694   M (PG_ENABLE_DISABLE, mp);
16695   mp->context = 0;
16696   mp->is_enabled = enable;
16697   if (stream_name_set != 0)
16698     {
16699       mp->stream_name_length = ntohl (name_len);
16700       clib_memcpy (mp->stream_name, stream_name, name_len);
16701     }
16702   vec_free (stream_name);
16703
16704   S (mp);
16705   W (ret);
16706   return ret;
16707 }
16708
16709 int
16710 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
16711 {
16712   unformat_input_t *input = vam->input;
16713   vl_api_ip_source_and_port_range_check_add_del_t *mp;
16714
16715   u16 *low_ports = 0;
16716   u16 *high_ports = 0;
16717   u16 this_low;
16718   u16 this_hi;
16719   ip4_address_t ip4_addr;
16720   ip6_address_t ip6_addr;
16721   u32 length;
16722   u32 tmp, tmp2;
16723   u8 prefix_set = 0;
16724   u32 vrf_id = ~0;
16725   u8 is_add = 1;
16726   u8 is_ipv6 = 0;
16727   int ret;
16728
16729   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16730     {
16731       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
16732         {
16733           prefix_set = 1;
16734         }
16735       else
16736         if (unformat
16737             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
16738         {
16739           prefix_set = 1;
16740           is_ipv6 = 1;
16741         }
16742       else if (unformat (input, "vrf %d", &vrf_id))
16743         ;
16744       else if (unformat (input, "del"))
16745         is_add = 0;
16746       else if (unformat (input, "port %d", &tmp))
16747         {
16748           if (tmp == 0 || tmp > 65535)
16749             {
16750               errmsg ("port %d out of range", tmp);
16751               return -99;
16752             }
16753           this_low = tmp;
16754           this_hi = this_low + 1;
16755           vec_add1 (low_ports, this_low);
16756           vec_add1 (high_ports, this_hi);
16757         }
16758       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
16759         {
16760           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
16761             {
16762               errmsg ("incorrect range parameters");
16763               return -99;
16764             }
16765           this_low = tmp;
16766           /* Note: in debug CLI +1 is added to high before
16767              passing to real fn that does "the work"
16768              (ip_source_and_port_range_check_add_del).
16769              This fn is a wrapper around the binary API fn a
16770              control plane will call, which expects this increment
16771              to have occurred. Hence letting the binary API control
16772              plane fn do the increment for consistency between VAT
16773              and other control planes.
16774            */
16775           this_hi = tmp2;
16776           vec_add1 (low_ports, this_low);
16777           vec_add1 (high_ports, this_hi);
16778         }
16779       else
16780         break;
16781     }
16782
16783   if (prefix_set == 0)
16784     {
16785       errmsg ("<address>/<mask> not specified");
16786       return -99;
16787     }
16788
16789   if (vrf_id == ~0)
16790     {
16791       errmsg ("VRF ID required, not specified");
16792       return -99;
16793     }
16794
16795   if (vrf_id == 0)
16796     {
16797       errmsg
16798         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
16799       return -99;
16800     }
16801
16802   if (vec_len (low_ports) == 0)
16803     {
16804       errmsg ("At least one port or port range required");
16805       return -99;
16806     }
16807
16808   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
16809
16810   mp->is_add = is_add;
16811
16812   if (is_ipv6)
16813     {
16814       mp->is_ipv6 = 1;
16815       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
16816     }
16817   else
16818     {
16819       mp->is_ipv6 = 0;
16820       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
16821     }
16822
16823   mp->mask_length = length;
16824   mp->number_of_ranges = vec_len (low_ports);
16825
16826   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
16827   vec_free (low_ports);
16828
16829   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
16830   vec_free (high_ports);
16831
16832   mp->vrf_id = ntohl (vrf_id);
16833
16834   S (mp);
16835   W (ret);
16836   return ret;
16837 }
16838
16839 int
16840 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
16841 {
16842   unformat_input_t *input = vam->input;
16843   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
16844   u32 sw_if_index = ~0;
16845   int vrf_set = 0;
16846   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
16847   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
16848   u8 is_add = 1;
16849   int ret;
16850
16851   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16852     {
16853       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16854         ;
16855       else if (unformat (input, "sw_if_index %d", &sw_if_index))
16856         ;
16857       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
16858         vrf_set = 1;
16859       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
16860         vrf_set = 1;
16861       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
16862         vrf_set = 1;
16863       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
16864         vrf_set = 1;
16865       else if (unformat (input, "del"))
16866         is_add = 0;
16867       else
16868         break;
16869     }
16870
16871   if (sw_if_index == ~0)
16872     {
16873       errmsg ("Interface required but not specified");
16874       return -99;
16875     }
16876
16877   if (vrf_set == 0)
16878     {
16879       errmsg ("VRF ID required but not specified");
16880       return -99;
16881     }
16882
16883   if (tcp_out_vrf_id == 0
16884       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
16885     {
16886       errmsg
16887         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
16888       return -99;
16889     }
16890
16891   /* Construct the API message */
16892   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
16893
16894   mp->sw_if_index = ntohl (sw_if_index);
16895   mp->is_add = is_add;
16896   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
16897   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
16898   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
16899   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
16900
16901   /* send it... */
16902   S (mp);
16903
16904   /* Wait for a reply... */
16905   W (ret);
16906   return ret;
16907 }
16908
16909 static int
16910 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
16911 {
16912   unformat_input_t *i = vam->input;
16913   vl_api_ipsec_gre_add_del_tunnel_t *mp;
16914   u32 local_sa_id = 0;
16915   u32 remote_sa_id = 0;
16916   ip4_address_t src_address;
16917   ip4_address_t dst_address;
16918   u8 is_add = 1;
16919   int ret;
16920
16921   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16922     {
16923       if (unformat (i, "local_sa %d", &local_sa_id))
16924         ;
16925       else if (unformat (i, "remote_sa %d", &remote_sa_id))
16926         ;
16927       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
16928         ;
16929       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
16930         ;
16931       else if (unformat (i, "del"))
16932         is_add = 0;
16933       else
16934         {
16935           clib_warning ("parse error '%U'", format_unformat_error, i);
16936           return -99;
16937         }
16938     }
16939
16940   M (IPSEC_GRE_ADD_DEL_TUNNEL, mp);
16941
16942   mp->local_sa_id = ntohl (local_sa_id);
16943   mp->remote_sa_id = ntohl (remote_sa_id);
16944   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
16945   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
16946   mp->is_add = is_add;
16947
16948   S (mp);
16949   W (ret);
16950   return ret;
16951 }
16952
16953 static int
16954 api_punt (vat_main_t * vam)
16955 {
16956   unformat_input_t *i = vam->input;
16957   vl_api_punt_t *mp;
16958   u32 ipv = ~0;
16959   u32 protocol = ~0;
16960   u32 port = ~0;
16961   int is_add = 1;
16962   int ret;
16963
16964   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16965     {
16966       if (unformat (i, "ip %d", &ipv))
16967         ;
16968       else if (unformat (i, "protocol %d", &protocol))
16969         ;
16970       else if (unformat (i, "port %d", &port))
16971         ;
16972       else if (unformat (i, "del"))
16973         is_add = 0;
16974       else
16975         {
16976           clib_warning ("parse error '%U'", format_unformat_error, i);
16977           return -99;
16978         }
16979     }
16980
16981   M (PUNT, mp);
16982
16983   mp->is_add = (u8) is_add;
16984   mp->ipv = (u8) ipv;
16985   mp->l4_protocol = (u8) protocol;
16986   mp->l4_port = htons ((u16) port);
16987
16988   S (mp);
16989   W (ret);
16990   return ret;
16991 }
16992
16993 static void vl_api_ipsec_gre_tunnel_details_t_handler
16994   (vl_api_ipsec_gre_tunnel_details_t * mp)
16995 {
16996   vat_main_t *vam = &vat_main;
16997
16998   print (vam->ofp, "%11d%15U%15U%14d%14d",
16999          ntohl (mp->sw_if_index),
17000          format_ip4_address, &mp->src_address,
17001          format_ip4_address, &mp->dst_address,
17002          ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
17003 }
17004
17005 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
17006   (vl_api_ipsec_gre_tunnel_details_t * mp)
17007 {
17008   vat_main_t *vam = &vat_main;
17009   vat_json_node_t *node = NULL;
17010   struct in_addr ip4;
17011
17012   if (VAT_JSON_ARRAY != vam->json_tree.type)
17013     {
17014       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17015       vat_json_init_array (&vam->json_tree);
17016     }
17017   node = vat_json_array_add (&vam->json_tree);
17018
17019   vat_json_init_object (node);
17020   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
17021   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
17022   vat_json_object_add_ip4 (node, "src_address", ip4);
17023   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
17024   vat_json_object_add_ip4 (node, "dst_address", ip4);
17025   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
17026   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
17027 }
17028
17029 static int
17030 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
17031 {
17032   unformat_input_t *i = vam->input;
17033   vl_api_ipsec_gre_tunnel_dump_t *mp;
17034   vl_api_control_ping_t *mp_ping;
17035   u32 sw_if_index;
17036   u8 sw_if_index_set = 0;
17037   int ret;
17038
17039   /* Parse args required to build the message */
17040   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17041     {
17042       if (unformat (i, "sw_if_index %d", &sw_if_index))
17043         sw_if_index_set = 1;
17044       else
17045         break;
17046     }
17047
17048   if (sw_if_index_set == 0)
17049     {
17050       sw_if_index = ~0;
17051     }
17052
17053   if (!vam->json_output)
17054     {
17055       print (vam->ofp, "%11s%15s%15s%14s%14s",
17056              "sw_if_index", "src_address", "dst_address",
17057              "local_sa_id", "remote_sa_id");
17058     }
17059
17060   /* Get list of gre-tunnel interfaces */
17061   M (IPSEC_GRE_TUNNEL_DUMP, mp);
17062
17063   mp->sw_if_index = htonl (sw_if_index);
17064
17065   S (mp);
17066
17067   /* Use a control ping for synchronization */
17068   M (CONTROL_PING, mp_ping);
17069   S (mp_ping);
17070
17071   W (ret);
17072   return ret;
17073 }
17074
17075 static int
17076 api_delete_subif (vat_main_t * vam)
17077 {
17078   unformat_input_t *i = vam->input;
17079   vl_api_delete_subif_t *mp;
17080   u32 sw_if_index = ~0;
17081   int ret;
17082
17083   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17084     {
17085       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17086         ;
17087       if (unformat (i, "sw_if_index %d", &sw_if_index))
17088         ;
17089       else
17090         break;
17091     }
17092
17093   if (sw_if_index == ~0)
17094     {
17095       errmsg ("missing sw_if_index");
17096       return -99;
17097     }
17098
17099   /* Construct the API message */
17100   M (DELETE_SUBIF, mp);
17101   mp->sw_if_index = ntohl (sw_if_index);
17102
17103   S (mp);
17104   W (ret);
17105   return ret;
17106 }
17107
17108 #define foreach_pbb_vtr_op      \
17109 _("disable",  L2_VTR_DISABLED)  \
17110 _("pop",  L2_VTR_POP_2)         \
17111 _("push",  L2_VTR_PUSH_2)
17112
17113 static int
17114 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
17115 {
17116   unformat_input_t *i = vam->input;
17117   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
17118   u32 sw_if_index = ~0, vtr_op = ~0;
17119   u16 outer_tag = ~0;
17120   u8 dmac[6], smac[6];
17121   u8 dmac_set = 0, smac_set = 0;
17122   u16 vlanid = 0;
17123   u32 sid = ~0;
17124   u32 tmp;
17125   int ret;
17126
17127   /* Shut up coverity */
17128   memset (dmac, 0, sizeof (dmac));
17129   memset (smac, 0, sizeof (smac));
17130
17131   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17132     {
17133       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17134         ;
17135       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17136         ;
17137       else if (unformat (i, "vtr_op %d", &vtr_op))
17138         ;
17139 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
17140       foreach_pbb_vtr_op
17141 #undef _
17142         else if (unformat (i, "translate_pbb_stag"))
17143         {
17144           if (unformat (i, "%d", &tmp))
17145             {
17146               vtr_op = L2_VTR_TRANSLATE_2_1;
17147               outer_tag = tmp;
17148             }
17149           else
17150             {
17151               errmsg
17152                 ("translate_pbb_stag operation requires outer tag definition");
17153               return -99;
17154             }
17155         }
17156       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
17157         dmac_set++;
17158       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
17159         smac_set++;
17160       else if (unformat (i, "sid %d", &sid))
17161         ;
17162       else if (unformat (i, "vlanid %d", &tmp))
17163         vlanid = tmp;
17164       else
17165         {
17166           clib_warning ("parse error '%U'", format_unformat_error, i);
17167           return -99;
17168         }
17169     }
17170
17171   if ((sw_if_index == ~0) || (vtr_op == ~0))
17172     {
17173       errmsg ("missing sw_if_index or vtr operation");
17174       return -99;
17175     }
17176   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
17177       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
17178     {
17179       errmsg
17180         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
17181       return -99;
17182     }
17183
17184   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
17185   mp->sw_if_index = ntohl (sw_if_index);
17186   mp->vtr_op = ntohl (vtr_op);
17187   mp->outer_tag = ntohs (outer_tag);
17188   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
17189   clib_memcpy (mp->b_smac, smac, sizeof (smac));
17190   mp->b_vlanid = ntohs (vlanid);
17191   mp->i_sid = ntohl (sid);
17192
17193   S (mp);
17194   W (ret);
17195   return ret;
17196 }
17197
17198 static int
17199 api_flow_classify_set_interface (vat_main_t * vam)
17200 {
17201   unformat_input_t *i = vam->input;
17202   vl_api_flow_classify_set_interface_t *mp;
17203   u32 sw_if_index;
17204   int sw_if_index_set;
17205   u32 ip4_table_index = ~0;
17206   u32 ip6_table_index = ~0;
17207   u8 is_add = 1;
17208   int ret;
17209
17210   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17211     {
17212       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17213         sw_if_index_set = 1;
17214       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17215         sw_if_index_set = 1;
17216       else if (unformat (i, "del"))
17217         is_add = 0;
17218       else if (unformat (i, "ip4-table %d", &ip4_table_index))
17219         ;
17220       else if (unformat (i, "ip6-table %d", &ip6_table_index))
17221         ;
17222       else
17223         {
17224           clib_warning ("parse error '%U'", format_unformat_error, i);
17225           return -99;
17226         }
17227     }
17228
17229   if (sw_if_index_set == 0)
17230     {
17231       errmsg ("missing interface name or sw_if_index");
17232       return -99;
17233     }
17234
17235   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
17236
17237   mp->sw_if_index = ntohl (sw_if_index);
17238   mp->ip4_table_index = ntohl (ip4_table_index);
17239   mp->ip6_table_index = ntohl (ip6_table_index);
17240   mp->is_add = is_add;
17241
17242   S (mp);
17243   W (ret);
17244   return ret;
17245 }
17246
17247 static int
17248 api_flow_classify_dump (vat_main_t * vam)
17249 {
17250   unformat_input_t *i = vam->input;
17251   vl_api_flow_classify_dump_t *mp;
17252   vl_api_control_ping_t *mp_ping;
17253   u8 type = FLOW_CLASSIFY_N_TABLES;
17254   int ret;
17255
17256   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
17257     ;
17258   else
17259     {
17260       errmsg ("classify table type must be specified");
17261       return -99;
17262     }
17263
17264   if (!vam->json_output)
17265     {
17266       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
17267     }
17268
17269   M (FLOW_CLASSIFY_DUMP, mp);
17270   mp->type = type;
17271   /* send it... */
17272   S (mp);
17273
17274   /* Use a control ping for synchronization */
17275   M (CONTROL_PING, mp_ping);
17276   S (mp_ping);
17277
17278   /* Wait for a reply... */
17279   W (ret);
17280   return ret;
17281 }
17282
17283 static int
17284 api_feature_enable_disable (vat_main_t * vam)
17285 {
17286   unformat_input_t *i = vam->input;
17287   vl_api_feature_enable_disable_t *mp;
17288   u8 *arc_name = 0;
17289   u8 *feature_name = 0;
17290   u32 sw_if_index = ~0;
17291   u8 enable = 1;
17292   int ret;
17293
17294   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17295     {
17296       if (unformat (i, "arc_name %s", &arc_name))
17297         ;
17298       else if (unformat (i, "feature_name %s", &feature_name))
17299         ;
17300       else
17301         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17302         ;
17303       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17304         ;
17305       else if (unformat (i, "disable"))
17306         enable = 0;
17307       else
17308         break;
17309     }
17310
17311   if (arc_name == 0)
17312     {
17313       errmsg ("missing arc name");
17314       return -99;
17315     }
17316   if (vec_len (arc_name) > 63)
17317     {
17318       errmsg ("arc name too long");
17319     }
17320
17321   if (feature_name == 0)
17322     {
17323       errmsg ("missing feature name");
17324       return -99;
17325     }
17326   if (vec_len (feature_name) > 63)
17327     {
17328       errmsg ("feature name too long");
17329     }
17330
17331   if (sw_if_index == ~0)
17332     {
17333       errmsg ("missing interface name or sw_if_index");
17334       return -99;
17335     }
17336
17337   /* Construct the API message */
17338   M (FEATURE_ENABLE_DISABLE, mp);
17339   mp->sw_if_index = ntohl (sw_if_index);
17340   mp->enable = enable;
17341   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
17342   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
17343   vec_free (arc_name);
17344   vec_free (feature_name);
17345
17346   S (mp);
17347   W (ret);
17348   return ret;
17349 }
17350
17351 static int
17352 api_sw_interface_tag_add_del (vat_main_t * vam)
17353 {
17354   unformat_input_t *i = vam->input;
17355   vl_api_sw_interface_tag_add_del_t *mp;
17356   u32 sw_if_index = ~0;
17357   u8 *tag = 0;
17358   u8 enable = 1;
17359   int ret;
17360
17361   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17362     {
17363       if (unformat (i, "tag %s", &tag))
17364         ;
17365       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17366         ;
17367       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17368         ;
17369       else if (unformat (i, "del"))
17370         enable = 0;
17371       else
17372         break;
17373     }
17374
17375   if (sw_if_index == ~0)
17376     {
17377       errmsg ("missing interface name or sw_if_index");
17378       return -99;
17379     }
17380
17381   if (enable && (tag == 0))
17382     {
17383       errmsg ("no tag specified");
17384       return -99;
17385     }
17386
17387   /* Construct the API message */
17388   M (SW_INTERFACE_TAG_ADD_DEL, mp);
17389   mp->sw_if_index = ntohl (sw_if_index);
17390   mp->is_add = enable;
17391   if (enable)
17392     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
17393   vec_free (tag);
17394
17395   S (mp);
17396   W (ret);
17397   return ret;
17398 }
17399
17400 static void vl_api_l2_xconnect_details_t_handler
17401   (vl_api_l2_xconnect_details_t * mp)
17402 {
17403   vat_main_t *vam = &vat_main;
17404
17405   print (vam->ofp, "%15d%15d",
17406          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
17407 }
17408
17409 static void vl_api_l2_xconnect_details_t_handler_json
17410   (vl_api_l2_xconnect_details_t * mp)
17411 {
17412   vat_main_t *vam = &vat_main;
17413   vat_json_node_t *node = NULL;
17414
17415   if (VAT_JSON_ARRAY != vam->json_tree.type)
17416     {
17417       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17418       vat_json_init_array (&vam->json_tree);
17419     }
17420   node = vat_json_array_add (&vam->json_tree);
17421
17422   vat_json_init_object (node);
17423   vat_json_object_add_uint (node, "rx_sw_if_index",
17424                             ntohl (mp->rx_sw_if_index));
17425   vat_json_object_add_uint (node, "tx_sw_if_index",
17426                             ntohl (mp->tx_sw_if_index));
17427 }
17428
17429 static int
17430 api_l2_xconnect_dump (vat_main_t * vam)
17431 {
17432   vl_api_l2_xconnect_dump_t *mp;
17433   vl_api_control_ping_t *mp_ping;
17434   int ret;
17435
17436   if (!vam->json_output)
17437     {
17438       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
17439     }
17440
17441   M (L2_XCONNECT_DUMP, mp);
17442
17443   S (mp);
17444
17445   /* Use a control ping for synchronization */
17446   M (CONTROL_PING, mp_ping);
17447   S (mp_ping);
17448
17449   W (ret);
17450   return ret;
17451 }
17452
17453 static int
17454 api_sw_interface_set_mtu (vat_main_t * vam)
17455 {
17456   unformat_input_t *i = vam->input;
17457   vl_api_sw_interface_set_mtu_t *mp;
17458   u32 sw_if_index = ~0;
17459   u32 mtu = 0;
17460   int ret;
17461
17462   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17463     {
17464       if (unformat (i, "mtu %d", &mtu))
17465         ;
17466       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17467         ;
17468       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17469         ;
17470       else
17471         break;
17472     }
17473
17474   if (sw_if_index == ~0)
17475     {
17476       errmsg ("missing interface name or sw_if_index");
17477       return -99;
17478     }
17479
17480   if (mtu == 0)
17481     {
17482       errmsg ("no mtu specified");
17483       return -99;
17484     }
17485
17486   /* Construct the API message */
17487   M (SW_INTERFACE_SET_MTU, mp);
17488   mp->sw_if_index = ntohl (sw_if_index);
17489   mp->mtu = ntohs ((u16) mtu);
17490
17491   S (mp);
17492   W (ret);
17493   return ret;
17494 }
17495
17496
17497 static int
17498 q_or_quit (vat_main_t * vam)
17499 {
17500 #if VPP_API_TEST_BUILTIN == 0
17501   longjmp (vam->jump_buf, 1);
17502 #endif
17503   return 0;                     /* not so much */
17504 }
17505
17506 static int
17507 q (vat_main_t * vam)
17508 {
17509   return q_or_quit (vam);
17510 }
17511
17512 static int
17513 quit (vat_main_t * vam)
17514 {
17515   return q_or_quit (vam);
17516 }
17517
17518 static int
17519 comment (vat_main_t * vam)
17520 {
17521   return 0;
17522 }
17523
17524 static int
17525 cmd_cmp (void *a1, void *a2)
17526 {
17527   u8 **c1 = a1;
17528   u8 **c2 = a2;
17529
17530   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
17531 }
17532
17533 static int
17534 help (vat_main_t * vam)
17535 {
17536   u8 **cmds = 0;
17537   u8 *name = 0;
17538   hash_pair_t *p;
17539   unformat_input_t *i = vam->input;
17540   int j;
17541
17542   if (unformat (i, "%s", &name))
17543     {
17544       uword *hs;
17545
17546       vec_add1 (name, 0);
17547
17548       hs = hash_get_mem (vam->help_by_name, name);
17549       if (hs)
17550         print (vam->ofp, "usage: %s %s", name, hs[0]);
17551       else
17552         print (vam->ofp, "No such msg / command '%s'", name);
17553       vec_free (name);
17554       return 0;
17555     }
17556
17557   print (vam->ofp, "Help is available for the following:");
17558
17559     /* *INDENT-OFF* */
17560     hash_foreach_pair (p, vam->function_by_name,
17561     ({
17562       vec_add1 (cmds, (u8 *)(p->key));
17563     }));
17564     /* *INDENT-ON* */
17565
17566   vec_sort_with_function (cmds, cmd_cmp);
17567
17568   for (j = 0; j < vec_len (cmds); j++)
17569     print (vam->ofp, "%s", cmds[j]);
17570
17571   vec_free (cmds);
17572   return 0;
17573 }
17574
17575 static int
17576 set (vat_main_t * vam)
17577 {
17578   u8 *name = 0, *value = 0;
17579   unformat_input_t *i = vam->input;
17580
17581   if (unformat (i, "%s", &name))
17582     {
17583       /* The input buffer is a vector, not a string. */
17584       value = vec_dup (i->buffer);
17585       vec_delete (value, i->index, 0);
17586       /* Almost certainly has a trailing newline */
17587       if (value[vec_len (value) - 1] == '\n')
17588         value[vec_len (value) - 1] = 0;
17589       /* Make sure it's a proper string, one way or the other */
17590       vec_add1 (value, 0);
17591       (void) clib_macro_set_value (&vam->macro_main,
17592                                    (char *) name, (char *) value);
17593     }
17594   else
17595     errmsg ("usage: set <name> <value>");
17596
17597   vec_free (name);
17598   vec_free (value);
17599   return 0;
17600 }
17601
17602 static int
17603 unset (vat_main_t * vam)
17604 {
17605   u8 *name = 0;
17606
17607   if (unformat (vam->input, "%s", &name))
17608     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
17609       errmsg ("unset: %s wasn't set", name);
17610   vec_free (name);
17611   return 0;
17612 }
17613
17614 typedef struct
17615 {
17616   u8 *name;
17617   u8 *value;
17618 } macro_sort_t;
17619
17620
17621 static int
17622 macro_sort_cmp (void *a1, void *a2)
17623 {
17624   macro_sort_t *s1 = a1;
17625   macro_sort_t *s2 = a2;
17626
17627   return strcmp ((char *) (s1->name), (char *) (s2->name));
17628 }
17629
17630 static int
17631 dump_macro_table (vat_main_t * vam)
17632 {
17633   macro_sort_t *sort_me = 0, *sm;
17634   int i;
17635   hash_pair_t *p;
17636
17637     /* *INDENT-OFF* */
17638     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
17639     ({
17640       vec_add2 (sort_me, sm, 1);
17641       sm->name = (u8 *)(p->key);
17642       sm->value = (u8 *) (p->value[0]);
17643     }));
17644     /* *INDENT-ON* */
17645
17646   vec_sort_with_function (sort_me, macro_sort_cmp);
17647
17648   if (vec_len (sort_me))
17649     print (vam->ofp, "%-15s%s", "Name", "Value");
17650   else
17651     print (vam->ofp, "The macro table is empty...");
17652
17653   for (i = 0; i < vec_len (sort_me); i++)
17654     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
17655   return 0;
17656 }
17657
17658 static int
17659 dump_node_table (vat_main_t * vam)
17660 {
17661   int i, j;
17662   vlib_node_t *node, *next_node;
17663
17664   if (vec_len (vam->graph_nodes) == 0)
17665     {
17666       print (vam->ofp, "Node table empty, issue get_node_graph...");
17667       return 0;
17668     }
17669
17670   for (i = 0; i < vec_len (vam->graph_nodes); i++)
17671     {
17672       node = vam->graph_nodes[i];
17673       print (vam->ofp, "[%d] %s", i, node->name);
17674       for (j = 0; j < vec_len (node->next_nodes); j++)
17675         {
17676           if (node->next_nodes[j] != ~0)
17677             {
17678               next_node = vam->graph_nodes[node->next_nodes[j]];
17679               print (vam->ofp, "  [%d] %s", j, next_node->name);
17680             }
17681         }
17682     }
17683   return 0;
17684 }
17685
17686 static int
17687 value_sort_cmp (void *a1, void *a2)
17688 {
17689   name_sort_t *n1 = a1;
17690   name_sort_t *n2 = a2;
17691
17692   if (n1->value < n2->value)
17693     return -1;
17694   if (n1->value > n2->value)
17695     return 1;
17696   return 0;
17697 }
17698
17699
17700 static int
17701 dump_msg_api_table (vat_main_t * vam)
17702 {
17703   api_main_t *am = &api_main;
17704   name_sort_t *nses = 0, *ns;
17705   hash_pair_t *hp;
17706   int i;
17707
17708   /* *INDENT-OFF* */
17709   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
17710   ({
17711     vec_add2 (nses, ns, 1);
17712     ns->name = (u8 *)(hp->key);
17713     ns->value = (u32) hp->value[0];
17714   }));
17715   /* *INDENT-ON* */
17716
17717   vec_sort_with_function (nses, value_sort_cmp);
17718
17719   for (i = 0; i < vec_len (nses); i++)
17720     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
17721   vec_free (nses);
17722   return 0;
17723 }
17724
17725 static int
17726 get_msg_id (vat_main_t * vam)
17727 {
17728   u8 *name_and_crc;
17729   u32 message_index;
17730
17731   if (unformat (vam->input, "%s", &name_and_crc))
17732     {
17733       message_index = vl_api_get_msg_index (name_and_crc);
17734       if (message_index == ~0)
17735         {
17736           print (vam->ofp, " '%s' not found", name_and_crc);
17737           return 0;
17738         }
17739       print (vam->ofp, " '%s' has message index %d",
17740              name_and_crc, message_index);
17741       return 0;
17742     }
17743   errmsg ("name_and_crc required...");
17744   return 0;
17745 }
17746
17747 static int
17748 search_node_table (vat_main_t * vam)
17749 {
17750   unformat_input_t *line_input = vam->input;
17751   u8 *node_to_find;
17752   int j;
17753   vlib_node_t *node, *next_node;
17754   uword *p;
17755
17756   if (vam->graph_node_index_by_name == 0)
17757     {
17758       print (vam->ofp, "Node table empty, issue get_node_graph...");
17759       return 0;
17760     }
17761
17762   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
17763     {
17764       if (unformat (line_input, "%s", &node_to_find))
17765         {
17766           vec_add1 (node_to_find, 0);
17767           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
17768           if (p == 0)
17769             {
17770               print (vam->ofp, "%s not found...", node_to_find);
17771               goto out;
17772             }
17773           node = vam->graph_nodes[p[0]];
17774           print (vam->ofp, "[%d] %s", p[0], node->name);
17775           for (j = 0; j < vec_len (node->next_nodes); j++)
17776             {
17777               if (node->next_nodes[j] != ~0)
17778                 {
17779                   next_node = vam->graph_nodes[node->next_nodes[j]];
17780                   print (vam->ofp, "  [%d] %s", j, next_node->name);
17781                 }
17782             }
17783         }
17784
17785       else
17786         {
17787           clib_warning ("parse error '%U'", format_unformat_error,
17788                         line_input);
17789           return -99;
17790         }
17791
17792     out:
17793       vec_free (node_to_find);
17794
17795     }
17796
17797   return 0;
17798 }
17799
17800
17801 static int
17802 script (vat_main_t * vam)
17803 {
17804 #if (VPP_API_TEST_BUILTIN==0)
17805   u8 *s = 0;
17806   char *save_current_file;
17807   unformat_input_t save_input;
17808   jmp_buf save_jump_buf;
17809   u32 save_line_number;
17810
17811   FILE *new_fp, *save_ifp;
17812
17813   if (unformat (vam->input, "%s", &s))
17814     {
17815       new_fp = fopen ((char *) s, "r");
17816       if (new_fp == 0)
17817         {
17818           errmsg ("Couldn't open script file %s", s);
17819           vec_free (s);
17820           return -99;
17821         }
17822     }
17823   else
17824     {
17825       errmsg ("Missing script name");
17826       return -99;
17827     }
17828
17829   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
17830   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
17831   save_ifp = vam->ifp;
17832   save_line_number = vam->input_line_number;
17833   save_current_file = (char *) vam->current_file;
17834
17835   vam->input_line_number = 0;
17836   vam->ifp = new_fp;
17837   vam->current_file = s;
17838   do_one_file (vam);
17839
17840   clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
17841   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
17842   vam->ifp = save_ifp;
17843   vam->input_line_number = save_line_number;
17844   vam->current_file = (u8 *) save_current_file;
17845   vec_free (s);
17846
17847   return 0;
17848 #else
17849   clib_warning ("use the exec command...");
17850   return -99;
17851 #endif
17852 }
17853
17854 static int
17855 echo (vat_main_t * vam)
17856 {
17857   print (vam->ofp, "%v", vam->input->buffer);
17858   return 0;
17859 }
17860
17861 /* List of API message constructors, CLI names map to api_xxx */
17862 #define foreach_vpe_api_msg                                             \
17863 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
17864 _(sw_interface_dump,"")                                                 \
17865 _(sw_interface_set_flags,                                               \
17866   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
17867 _(sw_interface_add_del_address,                                         \
17868   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
17869 _(sw_interface_set_table,                                               \
17870   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
17871 _(sw_interface_set_mpls_enable,                                         \
17872   "<intfc> | sw_if_index [disable | dis]")                              \
17873 _(sw_interface_set_vpath,                                               \
17874   "<intfc> | sw_if_index <id> enable | disable")                        \
17875 _(sw_interface_set_vxlan_bypass,                                        \
17876   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
17877 _(sw_interface_set_l2_xconnect,                                         \
17878   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
17879   "enable | disable")                                                   \
17880 _(sw_interface_set_l2_bridge,                                           \
17881   "<intfc> | sw_if_index <id> bd_id <bridge-domain-id>\n"               \
17882   "[shg <split-horizon-group>] [bvi]\n"                                 \
17883   "enable | disable")                                                   \
17884 _(bridge_domain_add_del,                                                \
17885   "bd_id <bridge-domain-id> [flood 1|0] [uu-flood 1|0] [forward 1|0] [learn 1|0] [arp-term 1|0] [del]\n") \
17886 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
17887 _(l2fib_add_del,                                                        \
17888   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
17889 _(l2_flags,                                                             \
17890   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood]\n") \
17891 _(bridge_flags,                                                         \
17892   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
17893 _(tap_connect,                                                          \
17894   "tapname <name> mac <mac-addr> | random-mac [tag <string>]")          \
17895 _(tap_modify,                                                           \
17896   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
17897 _(tap_delete,                                                           \
17898   "<vpp-if-name> | sw_if_index <id>")                                   \
17899 _(sw_interface_tap_dump, "")                                            \
17900 _(ip_add_del_route,                                                     \
17901   "<addr>/<mask> via <addr> [table-id <n>]\n"                           \
17902   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
17903   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
17904   "[multipath] [count <n>]")                                            \
17905 _(ip_mroute_add_del,                                                    \
17906   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
17907   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
17908 _(mpls_route_add_del,                                                   \
17909   "<label> <eos> via <addr> [table-id <n>]\n"                           \
17910   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
17911   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
17912   "[multipath] [count <n>]")                                            \
17913 _(mpls_ip_bind_unbind,                                                  \
17914   "<label> <addr/len>")                                                 \
17915 _(mpls_tunnel_add_del,                                                  \
17916   " via <addr> [table-id <n>]\n"                                        \
17917   "sw_if_index <id>] [l2]  [del]")                                      \
17918 _(proxy_arp_add_del,                                                    \
17919   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
17920 _(proxy_arp_intfc_enable_disable,                                       \
17921   "<intfc> | sw_if_index <id> enable | disable")                        \
17922 _(sw_interface_set_unnumbered,                                          \
17923   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
17924 _(ip_neighbor_add_del,                                                  \
17925   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
17926   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
17927 _(reset_vrf, "vrf <id> [ipv6]")                                         \
17928 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
17929 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
17930   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
17931   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
17932   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
17933 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
17934 _(reset_fib, "vrf <n> [ipv6]")                                          \
17935 _(dhcp_proxy_config,                                                    \
17936   "svr <v46-address> src <v46-address>\n"                               \
17937    "rx_vrf_id <nn> server_vrf_id <nn>  [del]")                          \
17938 _(dhcp_proxy_set_vss,                                                   \
17939   "tbl_id <n> fib_id <n> oui <n> [ipv6] [del]")                         \
17940 _(dhcp_proxy_dump, "ip6")                                               \
17941 _(dhcp_client_config,                                                   \
17942   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
17943 _(set_ip_flow_hash,                                                     \
17944   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
17945 _(sw_interface_ip6_enable_disable,                                      \
17946   "<intfc> | sw_if_index <id> enable | disable")                        \
17947 _(sw_interface_ip6_set_link_local_address,                              \
17948   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
17949 _(sw_interface_ip6nd_ra_prefix,                                         \
17950   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
17951   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
17952   "[nolink] [isno]")                                                    \
17953 _(sw_interface_ip6nd_ra_config,                                         \
17954   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
17955   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
17956   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
17957 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
17958 _(l2_patch_add_del,                                                     \
17959   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
17960   "enable | disable")                                                   \
17961 _(sr_localsid_add_del,                                                  \
17962   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
17963   "fib-table <num> (end.psp) sw_if_index <num>")                        \
17964 _(classify_add_del_table,                                               \
17965   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
17966   " [del] [del-chain] mask <mask-value>\n"                              \
17967   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
17968   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
17969 _(classify_add_del_session,                                             \
17970   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
17971   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
17972   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
17973   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
17974 _(classify_set_interface_ip_table,                                      \
17975   "<intfc> | sw_if_index <nn> table <nn>")                              \
17976 _(classify_set_interface_l2_tables,                                     \
17977   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
17978   "  [other-table <nn>]")                                               \
17979 _(get_node_index, "node <node-name")                                    \
17980 _(add_node_next, "node <node-name> next <next-node-name>")              \
17981 _(l2tpv3_create_tunnel,                                                 \
17982   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
17983   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
17984   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
17985 _(l2tpv3_set_tunnel_cookies,                                            \
17986   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
17987   "[new_remote_cookie <nn>]\n")                                         \
17988 _(l2tpv3_interface_enable_disable,                                      \
17989   "<intfc> | sw_if_index <nn> enable | disable")                        \
17990 _(l2tpv3_set_lookup_key,                                                \
17991   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
17992 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
17993 _(vxlan_add_del_tunnel,                                                 \
17994   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
17995   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
17996   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
17997 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
17998 _(gre_add_del_tunnel,                                                   \
17999   "src <ip4-addr> dst <ip4-addr> [outer-fib-id <nn>] [teb] [del]\n")    \
18000 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
18001 _(l2_fib_clear_table, "")                                               \
18002 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
18003 _(l2_interface_vlan_tag_rewrite,                                        \
18004   "<intfc> | sw_if_index <nn> \n"                                       \
18005   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
18006   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
18007 _(create_vhost_user_if,                                                 \
18008         "socket <filename> [server] [renumber <dev_instance>] "         \
18009         "[mac <mac_address>]")                                          \
18010 _(modify_vhost_user_if,                                                 \
18011         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
18012         "[server] [renumber <dev_instance>]")                           \
18013 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
18014 _(sw_interface_vhost_user_dump, "")                                     \
18015 _(show_version, "")                                                     \
18016 _(vxlan_gpe_add_del_tunnel,                                             \
18017   "local <addr> remote <addr> vni <nn>\n"                               \
18018     "[encap-vrf-id <nn>] [decap-vrf-id <nn>] [next-ip4][next-ip6]"      \
18019   "[next-ethernet] [next-nsh]\n")                                       \
18020 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
18021 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
18022 _(interface_name_renumber,                                              \
18023   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
18024 _(input_acl_set_interface,                                              \
18025   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
18026   "  [l2-table <nn>] [del]")                                            \
18027 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
18028 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
18029 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
18030 _(ip_dump, "ipv4 | ipv6")                                               \
18031 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
18032 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
18033   "  spid_id <n> ")                                                     \
18034 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
18035   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
18036   "  integ_alg <alg> integ_key <hex>")                                  \
18037 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
18038   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
18039   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
18040   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
18041 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
18042 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
18043 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
18044   "(auth_data 0x<data> | auth_data <data>)")                            \
18045 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
18046   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
18047 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
18048   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
18049   "(local|remote)")                                                     \
18050 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
18051 _(ikev2_set_responder, "<profile_name> interface <interface> address <addr>") \
18052 _(ikev2_set_ike_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
18053 _(ikev2_set_esp_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
18054 _(ikev2_set_sa_lifetime, "<profile_name> <seconds> <jitter> <handover> <max bytes>") \
18055 _(ikev2_initiate_sa_init, "<profile_name>")                             \
18056 _(ikev2_initiate_del_ike_sa, "<ispi>")                                  \
18057 _(ikev2_initiate_del_child_sa, "<ispi>")                                \
18058 _(ikev2_initiate_rekey_child_sa, "<ispi>")                              \
18059 _(delete_loopback,"sw_if_index <nn>")                                   \
18060 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
18061 _(map_add_domain,                                                       \
18062   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
18063   "ip6-src <ip6addr> "                                                  \
18064   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
18065 _(map_del_domain, "index <n>")                                          \
18066 _(map_add_del_rule,                                                     \
18067   "index <n> psid <n> dst <ip6addr> [del]")                             \
18068 _(map_domain_dump, "")                                                  \
18069 _(map_rule_dump, "index <map-domain>")                                  \
18070 _(want_interface_events,  "enable|disable")                             \
18071 _(want_stats,"enable|disable")                                          \
18072 _(get_first_msg_id, "client <name>")                                    \
18073 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
18074 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
18075   "fib-id <nn> [ip4][ip6][default]")                                    \
18076 _(get_node_graph, " ")                                                  \
18077 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
18078 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
18079 _(ioam_disable, "")                                                     \
18080 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
18081                             " sw_if_index <sw_if_index> p <priority> "  \
18082                             "w <weight>] [del]")                        \
18083 _(one_add_del_locator, "locator-set <locator_name> "                    \
18084                         "iface <intf> | sw_if_index <sw_if_index> "     \
18085                         "p <priority> w <weight> [del]")                \
18086 _(one_add_del_local_eid,"vni <vni> eid "                                \
18087                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
18088                          "locator-set <locator_name> [del]"             \
18089                          "[key-id sha1|sha256 secret-key <secret-key>]")\
18090 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
18091 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
18092 _(one_enable_disable, "enable|disable")                                 \
18093 _(one_map_register_enable_disable, "enable|disable")                    \
18094 _(one_rloc_probe_enable_disable, "enable|disable")                      \
18095 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
18096                                "[seid <seid>] "                         \
18097                                "rloc <locator> p <prio> "               \
18098                                "w <weight> [rloc <loc> ... ] "          \
18099                                "action <action> [del-all]")             \
18100 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
18101                           "<local-eid>")                                \
18102 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
18103 _(one_map_request_mode, "src-dst|dst-only")                             \
18104 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
18105 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
18106 _(one_locator_set_dump, "[local | remote]")                             \
18107 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
18108 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
18109                        "[local] | [remote]")                            \
18110 _(one_eid_table_vni_dump, "")                                           \
18111 _(one_eid_table_map_dump, "l2|l3")                                      \
18112 _(one_map_resolver_dump, "")                                            \
18113 _(one_map_server_dump, "")                                              \
18114 _(one_adjacencies_get, "vni <vni>")                                     \
18115 _(show_one_rloc_probe_state, "")                                        \
18116 _(show_one_map_register_state, "")                                      \
18117 _(show_one_status, "")                                                  \
18118 _(one_get_map_request_itr_rlocs, "")                                    \
18119 _(show_one_pitr, "")                                                    \
18120 _(show_one_map_request_mode, "")                                        \
18121 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
18122                             " sw_if_index <sw_if_index> p <priority> "  \
18123                             "w <weight>] [del]")                        \
18124 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
18125                         "iface <intf> | sw_if_index <sw_if_index> "     \
18126                         "p <priority> w <weight> [del]")                \
18127 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
18128                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
18129                          "locator-set <locator_name> [del]"             \
18130                          "[key-id sha1|sha256 secret-key <secret-key>]") \
18131 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
18132 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
18133 _(lisp_enable_disable, "enable|disable")                                \
18134 _(lisp_map_register_enable_disable, "enable|disable")                   \
18135 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
18136 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
18137                                "[seid <seid>] "                         \
18138                                "rloc <locator> p <prio> "               \
18139                                "w <weight> [rloc <loc> ... ] "          \
18140                                "action <action> [del-all]")             \
18141 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
18142                           "<local-eid>")                                \
18143 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
18144 _(lisp_map_request_mode, "src-dst|dst-only")                            \
18145 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
18146 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
18147 _(lisp_locator_set_dump, "[local | remote]")                            \
18148 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
18149 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
18150                        "[local] | [remote]")                            \
18151 _(lisp_eid_table_vni_dump, "")                                          \
18152 _(lisp_eid_table_map_dump, "l2|l3")                                     \
18153 _(lisp_map_resolver_dump, "")                                           \
18154 _(lisp_map_server_dump, "")                                             \
18155 _(lisp_adjacencies_get, "vni <vni>")                                    \
18156 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
18157 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
18158 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
18159 _(gpe_get_encap_mode, "")                                               \
18160 _(lisp_gpe_add_del_iface, "up|down")                                    \
18161 _(lisp_gpe_enable_disable, "enable|disable")                            \
18162 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
18163   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
18164 _(show_lisp_rloc_probe_state, "")                                       \
18165 _(show_lisp_map_register_state, "")                                     \
18166 _(show_lisp_status, "")                                                 \
18167 _(lisp_get_map_request_itr_rlocs, "")                                   \
18168 _(show_lisp_pitr, "")                                                   \
18169 _(show_lisp_map_request_mode, "")                                       \
18170 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
18171 _(af_packet_delete, "name <host interface name>")                       \
18172 _(policer_add_del, "name <policer name> <params> [del]")                \
18173 _(policer_dump, "[name <policer name>]")                                \
18174 _(policer_classify_set_interface,                                       \
18175   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
18176   "  [l2-table <nn>] [del]")                                            \
18177 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
18178 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
18179     "[master|slave]")                                                   \
18180 _(netmap_delete, "name <interface name>")                               \
18181 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
18182 _(mpls_fib_dump, "")                                                    \
18183 _(classify_table_ids, "")                                               \
18184 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
18185 _(classify_table_info, "table_id <nn>")                                 \
18186 _(classify_session_dump, "table_id <nn>")                               \
18187 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
18188     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
18189     "[template_interval <nn>] [udp_checksum]")                          \
18190 _(ipfix_exporter_dump, "")                                              \
18191 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
18192 _(ipfix_classify_stream_dump, "")                                       \
18193 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
18194 _(ipfix_classify_table_dump, "")                                        \
18195 _(sw_interface_span_enable_disable, "[src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
18196 _(sw_interface_span_dump, "")                                           \
18197 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
18198 _(pg_create_interface, "if_id <nn>")                                    \
18199 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
18200 _(pg_enable_disable, "[stream <id>] disable")                           \
18201 _(ip_source_and_port_range_check_add_del,                               \
18202   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
18203 _(ip_source_and_port_range_check_interface_add_del,                     \
18204   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
18205   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
18206 _(ipsec_gre_add_del_tunnel,                                             \
18207   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
18208 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
18209 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
18210 _(l2_interface_pbb_tag_rewrite,                                         \
18211   "<intfc> | sw_if_index <nn> \n"                                       \
18212   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
18213   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
18214 _(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
18215 _(flow_classify_set_interface,                                          \
18216   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
18217 _(flow_classify_dump, "type [ip4|ip6]")                                 \
18218 _(ip_fib_dump, "")                                                      \
18219 _(ip_mfib_dump, "")                                                     \
18220 _(ip6_fib_dump, "")                                                     \
18221 _(ip6_mfib_dump, "")                                                    \
18222 _(feature_enable_disable, "arc_name <arc_name> "                        \
18223   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
18224 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
18225 "[disable]")                                                            \
18226 _(l2_xconnect_dump, "")                                                 \
18227 _(sw_interface_set_mtu, "<intfc> | sw_if_index <nn> mtu <nn>")        \
18228 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
18229 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")
18230
18231 /* List of command functions, CLI names map directly to functions */
18232 #define foreach_cli_function                                    \
18233 _(comment, "usage: comment <ignore-rest-of-line>")              \
18234 _(dump_interface_table, "usage: dump_interface_table")          \
18235 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
18236 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
18237 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
18238 _(dump_stats_table, "usage: dump_stats_table")                  \
18239 _(dump_macro_table, "usage: dump_macro_table ")                 \
18240 _(dump_node_table, "usage: dump_node_table")                    \
18241 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
18242 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
18243 _(echo, "usage: echo <message>")                                \
18244 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
18245 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
18246 _(help, "usage: help")                                          \
18247 _(q, "usage: quit")                                             \
18248 _(quit, "usage: quit")                                          \
18249 _(search_node_table, "usage: search_node_table <name>...")      \
18250 _(set, "usage: set <variable-name> <value>")                    \
18251 _(script, "usage: script <file-name>")                          \
18252 _(unset, "usage: unset <variable-name>")
18253
18254 #define _(N,n)                                  \
18255     static void vl_api_##n##_t_handler_uni      \
18256     (vl_api_##n##_t * mp)                       \
18257     {                                           \
18258         vat_main_t * vam = &vat_main;           \
18259         if (vam->json_output) {                 \
18260             vl_api_##n##_t_handler_json(mp);    \
18261         } else {                                \
18262             vl_api_##n##_t_handler(mp);         \
18263         }                                       \
18264     }
18265 foreach_vpe_api_reply_msg;
18266 #if VPP_API_TEST_BUILTIN == 0
18267 foreach_standalone_reply_msg;
18268 #endif
18269 #undef _
18270
18271 void
18272 vat_api_hookup (vat_main_t * vam)
18273 {
18274 #define _(N,n)                                                  \
18275     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
18276                            vl_api_##n##_t_handler_uni,          \
18277                            vl_noop_handler,                     \
18278                            vl_api_##n##_t_endian,               \
18279                            vl_api_##n##_t_print,                \
18280                            sizeof(vl_api_##n##_t), 1);
18281   foreach_vpe_api_reply_msg;
18282 #if VPP_API_TEST_BUILTIN == 0
18283   foreach_standalone_reply_msg;
18284 #endif
18285 #undef _
18286
18287 #if (VPP_API_TEST_BUILTIN==0)
18288   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
18289 #endif
18290
18291   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
18292
18293   vam->function_by_name = hash_create_string (0, sizeof (uword));
18294
18295   vam->help_by_name = hash_create_string (0, sizeof (uword));
18296
18297   /* API messages we can send */
18298 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
18299   foreach_vpe_api_msg;
18300 #undef _
18301
18302   /* Help strings */
18303 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
18304   foreach_vpe_api_msg;
18305 #undef _
18306
18307   /* CLI functions */
18308 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
18309   foreach_cli_function;
18310 #undef _
18311
18312   /* Help strings */
18313 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
18314   foreach_cli_function;
18315 #undef _
18316 }
18317
18318 #if VPP_API_TEST_BUILTIN
18319 static clib_error_t *
18320 vat_api_hookup_shim (vlib_main_t * vm)
18321 {
18322   vat_api_hookup (&vat_main);
18323   return 0;
18324 }
18325
18326 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
18327 #endif
18328
18329 /*
18330  * fd.io coding-style-patch-verification: ON
18331  *
18332  * Local Variables:
18333  * eval: (c-set-style "gnu")
18334  * End:
18335  */